Repository: glampert/debug-draw Branch: master Commit: 623e351c4842 Files: 124 Total size: 3.7 MB Directory structure: gitextract_gyt1ey61/ ├── .travis.yml ├── README.md ├── debug_draw.hpp └── samples/ ├── Makefile ├── README.md ├── gl3w/ │ ├── README.rst │ ├── UNLICENSE │ ├── gl3w_gen.py │ ├── include/ │ │ └── GL/ │ │ ├── gl3w.h │ │ └── glcorearb.h │ └── src/ │ └── gl3w.cpp ├── sample_d3d11.cpp ├── sample_gl_core.cpp ├── sample_gl_core_multithreaded_explicit.cpp ├── sample_gl_core_multithreaded_tls.cpp ├── sample_gl_legacy.cpp ├── sample_null_renderer.cpp ├── samples_common.hpp ├── vectormath/ │ ├── LICENSE │ ├── SSE/ │ │ └── cpp/ │ │ ├── boolInVec.h │ │ ├── defines.h │ │ ├── floatInVec.h │ │ ├── mat_aos.h │ │ ├── quat_aos.h │ │ ├── vec_aos.h │ │ ├── vecidx_aos.h │ │ └── vectormath_aos.h │ ├── c/ │ │ ├── vectormath_aos.h │ │ ├── vectormath_aos_v.h │ │ ├── vectormath_soa.h │ │ └── vectormath_soa_v.h │ ├── cpp/ │ │ ├── vectormath_aos.h │ │ └── vectormath_soa.h │ ├── ppu/ │ │ ├── c/ │ │ │ ├── mat_aos.h │ │ │ ├── mat_aos_v.h │ │ │ ├── mat_soa.h │ │ │ ├── mat_soa_v.h │ │ │ ├── quat_aos.h │ │ │ ├── quat_aos_v.h │ │ │ ├── quat_soa.h │ │ │ ├── quat_soa_v.h │ │ │ ├── vec_aos.h │ │ │ ├── vec_aos_v.h │ │ │ ├── vec_soa.h │ │ │ ├── vec_soa_v.h │ │ │ ├── vec_types.h │ │ │ ├── vectormath_aos.h │ │ │ ├── vectormath_aos_v.h │ │ │ ├── vectormath_soa.h │ │ │ └── vectormath_soa_v.h │ │ └── cpp/ │ │ ├── boolInVec.h │ │ ├── floatInVec.h │ │ ├── mat_aos.h │ │ ├── mat_soa.h │ │ ├── quat_aos.h │ │ ├── quat_soa.h │ │ ├── vec_aos.h │ │ ├── vec_soa.h │ │ ├── vecidx_aos.h │ │ ├── vectormath_aos.h │ │ └── vectormath_soa.h │ ├── scalar/ │ │ ├── c/ │ │ │ ├── mat_aos.h │ │ │ ├── mat_aos_v.h │ │ │ ├── quat_aos.h │ │ │ ├── quat_aos_v.h │ │ │ ├── vec_aos.h │ │ │ ├── vec_aos_v.h │ │ │ ├── vectormath_aos.h │ │ │ └── vectormath_aos_v.h │ │ └── cpp/ │ │ ├── mat_aos.h │ │ ├── quat_aos.h │ │ ├── vec_aos.h │ │ └── vectormath_aos.h │ ├── spu/ │ │ ├── c/ │ │ │ ├── mat_aos.h │ │ │ ├── mat_aos_v.h │ │ │ ├── mat_soa.h │ │ │ ├── mat_soa_v.h │ │ │ ├── quat_aos.h │ │ │ ├── quat_aos_v.h │ │ │ ├── quat_soa.h │ │ │ ├── quat_soa_v.h │ │ │ ├── vec_aos.h │ │ │ ├── vec_aos_v.h │ │ │ ├── vec_soa.h │ │ │ ├── vec_soa_v.h │ │ │ ├── vectormath_aos.h │ │ │ ├── vectormath_aos_v.h │ │ │ ├── vectormath_soa.h │ │ │ └── vectormath_soa_v.h │ │ └── cpp/ │ │ ├── boolInVec.h │ │ ├── floatInVec.h │ │ ├── mat_aos.h │ │ ├── mat_soa.h │ │ ├── quat_aos.h │ │ ├── quat_soa.h │ │ ├── vec_aos.h │ │ ├── vec_soa.h │ │ ├── vecidx_aos.h │ │ ├── vectormath_aos.h │ │ └── vectormath_soa.h │ └── vectormath.h └── vs2015/ ├── ddSampleD3D11/ │ ├── ddSampleD3D11.filters │ ├── ddSampleD3D11.sln │ ├── ddSampleD3D11.vcxproj │ └── ddShader.fx ├── ddSampleGLCore/ │ ├── ddSampleGLCore.sln │ ├── ddSampleGLCore.vcxproj │ └── ddSampleGLCore.vcxproj.filters ├── ddSampleGLLegacy/ │ ├── ddSampleGLCore.vcxproj │ ├── ddSampleGLCore.vcxproj.filters │ └── ddSampleGLLegacy.sln ├── ddSampleNullRenderer/ │ ├── ddSampleNullRenderer.sln │ ├── ddSampleNullRenderer.vcxproj │ └── ddSampleNullRenderer.vcxproj.filters ├── glfw-3.2-WIN32/ │ ├── COPYING.txt │ ├── include/ │ │ └── GLFW/ │ │ ├── glfw3.h │ │ └── glfw3native.h │ └── lib-vc2015/ │ ├── glfw3.lib │ └── glfw3dll.lib └── glfw-3.2-WIN64/ ├── COPYING.txt ├── include/ │ └── GLFW/ │ ├── glfw3.h │ └── glfw3native.h └── lib-vc2015/ ├── glfw3.lib └── glfw3dll.lib ================================================ FILE CONTENTS ================================================ ================================================ FILE: .travis.yml ================================================ language: cpp os: - linux - osx compiler: - gcc - clang before_install: # GCC update for linux, to ensure C++11 support. - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; sudo apt-get update -qq; fi # GLFW install on linux: - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw; sudo apt-get update -qq; sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev; fi # GLFW install on MacOS: (make sure brew can install GLFW in usr/local) - if [ $TRAVIS_OS_NAME == osx ]; then sudo chown -R $(whoami) /usr/local; brew update; brew install glfw3; fi install: # Finish the GCC install for linux: - if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get install -qq g++-5; export CXX="g++-5"; export CC="gcc-5"; fi script: - $CXX --version - make -C samples ================================================ FILE: README.md ================================================ # Debug Draw [![Build Status](https://travis-ci.org/glampert/debug-draw.svg)](https://travis-ci.org/glampert/debug-draw) An immediate-mode, renderer agnostic, lightweight debug drawing API for C++. ![Debug Draw](https://raw.githubusercontent.com/glampert/debug-draw/master/samples/images/shapes.png "Debug Draw sample") ## License This software is in the public domain. Where that dedication is not recognized, you are granted a perpetual, irrevocable license to copy, distribute, and modify the source code as you see fit. The source code is provided "as is", without warranty of any kind, express or implied. No attribution is required, but a mention about the author(s) is appreciated. ## Using Debug Draw Debug Draw is a single source file library, so the "header" forward declarations and the implementation are contained in the same file (`debug_draw.hpp`). This should facilitate deployment and integration with your own projects. All you have to do is `#include` the library file in one of your own source files and define `DEBUG_DRAW_IMPLEMENTATION` in that file to generate the implementation. You can also still include the library in other places. When `DEBUG_DRAW_IMPLEMENTATION` is not defined, it acts as a normal C++ header file. Example: In `my_program.cpp`: ```cpp #define DEBUG_DRAW_IMPLEMENTATION #include "debug_draw.hpp" ``` Now in `my_program.hpp` or any other header or source file, you can include it as a normal C++ header: ```cpp #include "debug_draw.hpp" ``` That's it, you should now be able to build Debug Draw into your own application. ### Interfacing with your renderer Debug Draw doesn't make assumptions about the underlaying renderer API, so it can be integrated very easily with Direct3D or OpenGL or any other rendering engine of your choice. All that is required is that you provide an implementation for the `dd::RenderInterface` abstract class, which provides Debug Draw with basic methods to draw points, lines and character glyphs. The following is what `dd::RenderInterface` looks like: ```cpp class RenderInterface { public: virtual void beginDraw(); virtual void endDraw(); virtual GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels); virtual void destroyGlyphTexture(GlyphTextureHandle glyphTex); virtual void drawPointList(const DrawVertex * points, int count, bool depthEnabled); virtual void drawLineList(const DrawVertex * lines, int count, bool depthEnabled); virtual void drawGlyphList(const DrawVertex * glyphs, int count, GlyphTextureHandle glyphTex); virtual ~RenderInterface() = 0; }; ``` Not all methods have to be implemented, you decide which features to support! Look into the source code for the declaration of `RenderInterface`. Each method is well commented and describes the expected behavior that you should implement. For reference implementations of the `RenderInterface` using standard APIs like OpenGL, refer to the `samples/` directory in this project. Once you implement a `RenderInterface` for your renderer, all you need to do before starting to use Debug Draw is to call `dd::initialize()` passing it a pointer to your custom `RenderInterface`: ```cpp MyRenderInterface renderIface; dd::initialize(&renderIface); ``` Note however that Debug Draw batches all primitives to reduce the number of calls to `RenderInterface`, so drawing will only actually take place by the time you call `dd::flush()`, which is normally done at the end of a frame, before flipping the screen buffers: ```cpp // You only have to pass the current time if you have timed debug // draws in the queues. Otherwise just omit the argument or pass 0. dd::flush(getTimeMilliseconds()); ``` So the overall setup should look something like the following: ```cpp class MyRenderInterface : public dd::RenderInterface { // Cherrypick the methods you want to implement or implement them all ... }; int main() { MyRenderInterface renderIface; dd::initialize(&renderIface); while (!quitting) { // Any other drawing that you already do ... // Call any dd:: functions to add debug primitives to the draw queues ... dd::flush(getTimeMilliseconds()); // Swap buffers to present the scene ... } dd::shutdown(); } ``` ### Configuration switches Debug Draw provides several compiler switches for library configuration and customization. Check the documentation in `debug_draw.hpp` for a list of all switches plus detailed description of each. ### Language/compiler requirements The library has very few language requirements. One of its main goals is to be painless to integrate and portable. The only requirement is a fairly recent C++ compiler with minimal Standard Library support. Some C++11 features are assumed, such as `nullptr` and ``. The samples included make heavier use of the C++ Standard Library to demonstrate Debug Draw usage with threads. RTTI and C++ Exceptions **are not used**, so you should have no problems integrating the library with projects that disable those features. The memory footprint is also small and you can manage the amount of memory that gets committed to the internal queues via preprocessor directives. We currently only allocate a small amount of dynamic memory at library startup to decompress the font glyphs for the debug text drawing functions and for the draw queues and library context data. ### Thread safety and explicit contexts By default, Debug Draw will use a static global context internally, providing a procedural-style API that *is not thread safe*. This is the "classic" Debug Draw mode that is the easiest to use and set up, but the library also supports two other modes that are thread safe and configurable at compile time: - `DEBUG_DRAW_PER_THREAD_CONTEXT`: If this is defined before the implementation, the library will use a thread-local context instead of the global shared default. This allows calling the library from different threads since each will keep its private context and draw queues. This mode provides the same public library interface but requires TLS (Thread Local Storage) support from the compiler. - `DEBUG_DRAW_EXPLICIT_CONTEXT`: If this is defined before the implementation, the library expects the user to supply a handle to a context. This mode exposes the `dd::ContextHandle` type and changes each function in the library to take this handle as the first argument. This mode makes the library fully stateless, so that each rendering thread that calls into the library can create and maintain its own instance of Debug Draw. The explicit context mode is a cleaner and more functional-style API and should be the preferred one for new users. The procedural mode is still kept as the default for compatibility with older library versions, but it is recommended that you use the explicit context mode by adding `#define DEBUG_DRAW_EXPLICIT_CONTEXT` together with `DEBUG_DRAW_IMPLEMENTATION`. In the future, the procedural stateful API will be deprecated in favor of the explicit one. ## Samples Drawing a box with a set of coordinate axes in its center: ```cpp const ddVec3 boxColor = { 0.0f, 0.8f, 0.8f }; const ddVec3 boxCenter = { 0.0f, 0.0f, 3.0f }; dd::box(boxCenter, boxColor, 1.5f, 1.5f, 1.5f); dd::cross(boxCenter, 1.0f); ``` ![box](https://raw.githubusercontent.com/glampert/debug-draw/master/samples/images/box.png "Box with coordinate axes") To visualize a matrix transform, you can use `dd::axisTriad()` to draw the transform as three arrows: ```cpp const ddMat4x4 transform = { // The identity matrix 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; dd::axisTriad(transform, 0.3f, 2.0f); ``` ![arrows](https://raw.githubusercontent.com/glampert/debug-draw/master/samples/images/arrows.png "Axis triad repesenting a 3D transform") More complex samples and examples on how to integrate Debug Draw with your own renderer can be found inside the `samples/` directory. Each function provided in the public API is also well documented in the header file. You will find a descriptive header comment before the prototype of each public function exported by the library. ================================================ FILE: debug_draw.hpp ================================================ // ================================================================================================ // -*- C++ -*- // File: debug_draw.hpp // Author: Guilherme R. Lampert // Brief: Debug Draw - an immediate-mode, renderer agnostic, lightweight debug drawing API. // ================================================================================================ #ifndef DEBUG_DRAW_HPP #define DEBUG_DRAW_HPP // ======================================================== // Library Overview: // ======================================================== // // --------- // LICENSE // --------- // This software is in the public domain. Where that dedication is not recognized, // you are granted a perpetual, irrevocable license to copy, distribute, and modify // this file as you see fit. // // The source code is provided "as is", without warranty of any kind, express or implied. // No attribution is required, but a mention about the author(s) is appreciated. // // ------------- // QUICK SETUP // ------------- // In *one* C++ source file, *before* including this file, do this: // // #define DEBUG_DRAW_IMPLEMENTATION // // To enable the implementation. Further includes of this // file *should not* redefine DEBUG_DRAW_IMPLEMENTATION. // Example: // // In my_program.cpp: // // #define DEBUG_DRAW_IMPLEMENTATION // #include "debug_draw.hpp" // // In my_program.hpp: // // #include "debug_draw.hpp" // // ---------------------- // COMPILATION SWITCHES // ---------------------- // // DEBUG_DRAW_CXX11_SUPPORTED // Enables the use of some C++11 features. If your compiler supports C++11 // or better, you should define this switch globally or before every inclusion // of this file. If it is not defined, we try to guess it from the value of the // '__cplusplus' built-in macro constant. // // DEBUG_DRAW_MAX_* // Sizes of internal intermediate buffers, which are allocated on initialization // by the implementation. If you need to draw more primitives than the sizes of // these buffers, you need to redefine the macros and recompile. // // DEBUG_DRAW_VERTEX_BUFFER_SIZE // Size in dd::DrawVertex elements of the intermediate vertex buffer used // to batch primitives before sending them to dd::RenderInterface. A bigger // buffer will reduce the number of calls to dd::RenderInterface when drawing // large sets of debug primitives. // // DEBUG_DRAW_OVERFLOWED(message) // An error handler called if any of the DEBUG_DRAW_MAX_* sizes overflow. // By default it just prints a message to stderr. // // DEBUG_DRAW_USE_STD_MATH // If defined to nonzero, uses cmath/math.h. If you redefine it to zero before // the library implementation, it will force the use of local replacements // for the Standard Library. This might be useful if you want to avoid the // dependency. It is defined to zero by default (i.e. we use cmath by default). // // DEBUG_DRAW_*_TYPE_DEFINED // The compound types used by Debug Draw can also be customized. // By default, ddVec3 and ddMat4x4 are plain C-arrays, but you can // redefine them to use your own classes or structures (see below). // ddStr is by default a std::string, but you can redefine it to // a custom string type if necessary. The only requirements are that // it provides a 'c_str()' method returning a null terminated // const char* string and an assignment operator (=). // // DEBUG_DRAW_STR_DEALLOC_FUNC(str) // If you define a custom string type for ddStr and it requires some // extra cleanup besides the class destructor, you might define this // function macro to perform said cleanup. It is called by dd::clear() // and dd::shutdown() on every instance of the internal DebugString buffer. // // DEBUG_DRAW_NO_DEFAULT_COLORS // If defined, doesn't add the set of predefined color constants inside // dd::colors:: namespace. Each color is a ddVec3, so you can define this // to prevent adding more global data to the binary if you don't need them. // // DEBUG_DRAW_PER_THREAD_CONTEXT // If defined, a per-thread global context will be created for Debug Draw. // This allows having an instance of the library for each thread in // your application. You must then call initialize/shutdown/flush/etc // for each thread that wishes to use the library. If this is not // defined it defaults to a single threaded global context. // // DEBUG_DRAW_EXPLICIT_CONTEXT // If defined, each Debug Draw function will expect and additional argument // (the first one) which is the library context instance. This is an alternative // to DEBUG_DRAW_PER_THREAD_CONTEXT to allow having multiple instances of the // library in the same application. This flag is mutually exclusive with // DEBUG_DRAW_PER_THREAD_CONTEXT. // // ------------------- // MEMORY ALLOCATION // ------------------- // Debug Draw will only perform a couple of memory allocations during startup to decompress // the built-in glyph bitmap used for debug text rendering and to allocate the vertex buffers // and intermediate draw/batch buffers and context data used internally. // // Memory allocation and deallocation for Debug Draw will be done via: // // DD_MALLOC(size) // DD_MFREE(ptr) // // These two macros can be redefined if you'd like to supply you own memory allocator. // By default, they are defined to use std::malloc and std::free, respectively. // Note: If you redefine one, you must also provide the other. // // -------------------------------- // INTERFACING WITH YOUR RENDERER // -------------------------------- // Debug Draw doesn't touch on any renderer-specific aspects or APIs, instead you provide // the library with all of it's rendering needs via the dd::RenderInterface abstract class. // // See the declaration of dd::RenderInterface for details. Not all methods are // required. In fact, you could also implement a full no-op RenderInterface that // disables debug drawing by simply inheriting from dd::RenderInterface and not overriding // any of the methods (or even easier, call dd::initialize(nullptr) to make everything a no-op). // // For examples on how to implement your own dd::RenderInterface, see the accompanying samples. // You can also find them in the source code repository for this project: // https://github.com/glampert/debug-draw // // ------------------ // CONVENTIONS USED // ------------------ // Points and lines are always specified in world-space positions. This also // applies to shapes drawn from lines, like boxes, spheres, cones, etc. // // 2D screen-text is in screen-space pixels (from 0,0 in the upper-left // corner of the screen to screen_width-1 and screen_height-1). // RenderInterface::drawGlyphList() also receives vertexes in screen-space. // // We make some usage of matrices for things like the projected text labels. // Matrix layout used is column-major and vectors multiply as columns. // This is the convention normally used by standard OpenGL. // // C++ Exceptions are not used. Little error checking is provided or // done inside the library. We favor simpler, faster and easier to maintain // code over more sophisticated error handling. The rationale is that a // debug drawing API doesn't have to be very robust, since it won't make // into the final release executable in most cases. // // ======================================================== // Configurable compilation switches: // ======================================================== // // If the user didn't specify if C++11 or above are supported, try to guess // from the value of '__cplusplus'. It should be 199711L for pre-C++11 compilers // and 201103L in those supporting C++11, but this is not a guarantee that all // C++11 features will be available and stable, so again, we are making a guess. // It is recommended to instead supply the DEBUG_DRAW_CXX11_SUPPORTED switch // yourself before including this file. // #ifndef DEBUG_DRAW_CXX11_SUPPORTED #if (__cplusplus > 199711L) #define DEBUG_DRAW_CXX11_SUPPORTED 1 #endif // __cplusplus #endif // DEBUG_DRAW_CXX11_SUPPORTED // // Max elements of each type at any given time. // We supply these reasonable defaults, but you can provide your // own tunned values to save memory or fit all of your debug data. // These are hard constraints. If not enough, change and recompile. // #ifndef DEBUG_DRAW_MAX_STRINGS #define DEBUG_DRAW_MAX_STRINGS 512 #endif // DEBUG_DRAW_MAX_STRINGS #ifndef DEBUG_DRAW_MAX_POINTS #define DEBUG_DRAW_MAX_POINTS 8192 #endif // DEBUG_DRAW_MAX_POINTS #ifndef DEBUG_DRAW_MAX_LINES #define DEBUG_DRAW_MAX_LINES 32768 #endif // DEBUG_DRAW_MAX_LINES // // Size in vertexes of a local buffer we use to sort elements // drawn with and without depth testing before submitting them to // the dd::RenderInterface. A larger buffer will require less flushes // (e.g. dd::RenderInterface calls) when drawing large amounts of // primitives. Less will obviously save more memory. Each DrawVertex // is about 32 bytes in size, we keep a context-specific array // with this many entries. // #ifndef DEBUG_DRAW_VERTEX_BUFFER_SIZE #define DEBUG_DRAW_VERTEX_BUFFER_SIZE 4096 #endif // DEBUG_DRAW_VERTEX_BUFFER_SIZE // // This macro is called with an error message if any of the above // sizes is overflowed during runtime. In a debug build, you might // keep this enabled to be able to log and find out if more space // is needed for the debug data arrays. Default output is stderr. // #ifndef DEBUG_DRAW_OVERFLOWED #include #define DEBUG_DRAW_OVERFLOWED(message) std::fprintf(stderr, "%s\n", message) #endif // DEBUG_DRAW_OVERFLOWED // // Use and for trigonometry functions by default. // If you wish to avoid those dependencies, DD provides local approximations // of the required functions as a portable replacement. Just define // DEBUG_DRAW_USE_STD_MATH to zero before including this file. // #ifndef DEBUG_DRAW_USE_STD_MATH #define DEBUG_DRAW_USE_STD_MATH 1 #endif // DEBUG_DRAW_USE_STD_MATH // ======================================================== // Overridable Debug Draw types: // ======================================================== #include #include // // Following typedefs are not members of the dd:: namespace to allow easy redefinition by the user. // If you provide a custom implementation for them before including this file, be sure to // also define the proper DEBUG_DRAW_*_TYPE_DEFINED switch to disable the default typedefs. // // The only requirement placed on the vector/matrix types is that they provide // an array subscript operator [] and have the expected number of elements. Apart // from that, they could be structs, classes, what-have-you. POD types are recommended // but not mandatory. // #ifndef DEBUG_DRAW_VEC3_TYPE_DEFINED // ddVec3: // A small array of floats with at least three elements, but // it could have more for alignment purposes, extra slots are ignored. // A custom ddVec3 type must provide the array subscript operator. typedef float ddVec3[3]; // ddVec3_In/ddVec3_Out: // Since our default ddVec3 is a plain C-array, it decays to a pointer // when passed as an input parameter to a function, so we can use it directly. // If you change it to some structured type, it might be more efficient // passing by const reference instead, however, some platforms have optimized // hardware registers for vec3s/vec4s, so passing by value might also be efficient. typedef const ddVec3 ddVec3_In; typedef ddVec3 ddVec3_Out; #define DEBUG_DRAW_VEC3_TYPE_DEFINED 1 #endif // DEBUG_DRAW_VEC3_TYPE_DEFINED #ifndef DEBUG_DRAW_MAT4X4_TYPE_DEFINED // ddMat4x4: // Homogeneous matrix of 16 floats, representing rotations as well as // translation/scaling and projections. The internal matrix layout used by this // library is COLUMN-MAJOR, vectors multiplying as columns (usual OpenGL convention). // Column-major matrix layout: // c.0 c.1 c.2 c.3 // r.0 | 0.x 4.x 8.x 12.x | // r.1 | 1.y 5.y 9.y 13.y | // r.2 | 2.z 6.z 10.z 14.z | // r.3 | 3.w 7.w 11.w 15.w | // If your custom matrix type uses row-major format internally, you'll // have to transpose them before passing your matrices to the DD functions. // We use the array subscript operator internally, so it must also be provided. typedef float ddMat4x4[4 * 4]; // ddMat4x4_In/ddMat4x4_Out: // Since our default ddMat4x4 is a plain C-array, it decays to a pointer // when passed as an input parameter to a function, so we can use it directly. // If you change it to some structured type, it might be more efficient // passing by const reference instead. typedef const ddMat4x4 ddMat4x4_In; typedef ddMat4x4 ddMat4x4_Out; #define DEBUG_DRAW_MAT4X4_TYPE_DEFINED 1 #endif // DEBUG_DRAW_MAT4X4_TYPE_DEFINED #ifndef DEBUG_DRAW_STRING_TYPE_DEFINED // ddStr: // String type used internally to store the debug text strings. // A custom string type must provide at least an assignment // operator (=) and a 'c_str()' method that returns a // null-terminated const char* string pointer. That's it. // An array subscript operator [] is not required for ddStr. #include typedef std::string ddStr; typedef const ddStr & ddStr_In; typedef ddStr & ddStr_Out; #define DEBUG_DRAW_STRING_TYPE_DEFINED 1 #endif // DEBUG_DRAW_STRING_TYPE_DEFINED namespace dd { // ======================================================== // Optional built-in colors in RGB float format: // ======================================================== #ifndef DEBUG_DRAW_NO_DEFAULT_COLORS namespace colors { extern const ddVec3 AliceBlue; extern const ddVec3 AntiqueWhite; extern const ddVec3 Aquamarine; extern const ddVec3 Azure; extern const ddVec3 Beige; extern const ddVec3 Bisque; extern const ddVec3 Black; extern const ddVec3 BlanchedAlmond; extern const ddVec3 Blue; extern const ddVec3 BlueViolet; extern const ddVec3 Brown; extern const ddVec3 BurlyWood; extern const ddVec3 CadetBlue; extern const ddVec3 Chartreuse; extern const ddVec3 Chocolate; extern const ddVec3 Coral; extern const ddVec3 CornflowerBlue; extern const ddVec3 Cornsilk; extern const ddVec3 Crimson; extern const ddVec3 Cyan; extern const ddVec3 DarkBlue; extern const ddVec3 DarkCyan; extern const ddVec3 DarkGoldenRod; extern const ddVec3 DarkGray; extern const ddVec3 DarkGreen; extern const ddVec3 DarkKhaki; extern const ddVec3 DarkMagenta; extern const ddVec3 DarkOliveGreen; extern const ddVec3 DarkOrange; extern const ddVec3 DarkOrchid; extern const ddVec3 DarkRed; extern const ddVec3 DarkSalmon; extern const ddVec3 DarkSeaGreen; extern const ddVec3 DarkSlateBlue; extern const ddVec3 DarkSlateGray; extern const ddVec3 DarkTurquoise; extern const ddVec3 DarkViolet; extern const ddVec3 DeepPink; extern const ddVec3 DeepSkyBlue; extern const ddVec3 DimGray; extern const ddVec3 DodgerBlue; extern const ddVec3 FireBrick; extern const ddVec3 FloralWhite; extern const ddVec3 ForestGreen; extern const ddVec3 Gainsboro; extern const ddVec3 GhostWhite; extern const ddVec3 Gold; extern const ddVec3 GoldenRod; extern const ddVec3 Gray; extern const ddVec3 Green; extern const ddVec3 GreenYellow; extern const ddVec3 HoneyDew; extern const ddVec3 HotPink; extern const ddVec3 IndianRed; extern const ddVec3 Indigo; extern const ddVec3 Ivory; extern const ddVec3 Khaki; extern const ddVec3 Lavender; extern const ddVec3 LavenderBlush; extern const ddVec3 LawnGreen; extern const ddVec3 LemonChiffon; extern const ddVec3 LightBlue; extern const ddVec3 LightCoral; extern const ddVec3 LightCyan; extern const ddVec3 LightGoldenYellow; extern const ddVec3 LightGray; extern const ddVec3 LightGreen; extern const ddVec3 LightPink; extern const ddVec3 LightSalmon; extern const ddVec3 LightSeaGreen; extern const ddVec3 LightSkyBlue; extern const ddVec3 LightSlateGray; extern const ddVec3 LightSteelBlue; extern const ddVec3 LightYellow; extern const ddVec3 Lime; extern const ddVec3 LimeGreen; extern const ddVec3 Linen; extern const ddVec3 Magenta; extern const ddVec3 Maroon; extern const ddVec3 MediumAquaMarine; extern const ddVec3 MediumBlue; extern const ddVec3 MediumOrchid; extern const ddVec3 MediumPurple; extern const ddVec3 MediumSeaGreen; extern const ddVec3 MediumSlateBlue; extern const ddVec3 MediumSpringGreen; extern const ddVec3 MediumTurquoise; extern const ddVec3 MediumVioletRed; extern const ddVec3 MidnightBlue; extern const ddVec3 MintCream; extern const ddVec3 MistyRose; extern const ddVec3 Moccasin; extern const ddVec3 NavajoWhite; extern const ddVec3 Navy; extern const ddVec3 OldLace; extern const ddVec3 Olive; extern const ddVec3 OliveDrab; extern const ddVec3 Orange; extern const ddVec3 OrangeRed; extern const ddVec3 Orchid; extern const ddVec3 PaleGoldenRod; extern const ddVec3 PaleGreen; extern const ddVec3 PaleTurquoise; extern const ddVec3 PaleVioletRed; extern const ddVec3 PapayaWhip; extern const ddVec3 PeachPuff; extern const ddVec3 Peru; extern const ddVec3 Pink; extern const ddVec3 Plum; extern const ddVec3 PowderBlue; extern const ddVec3 Purple; extern const ddVec3 RebeccaPurple; extern const ddVec3 Red; extern const ddVec3 RosyBrown; extern const ddVec3 RoyalBlue; extern const ddVec3 SaddleBrown; extern const ddVec3 Salmon; extern const ddVec3 SandyBrown; extern const ddVec3 SeaGreen; extern const ddVec3 SeaShell; extern const ddVec3 Sienna; extern const ddVec3 Silver; extern const ddVec3 SkyBlue; extern const ddVec3 SlateBlue; extern const ddVec3 SlateGray; extern const ddVec3 Snow; extern const ddVec3 SpringGreen; extern const ddVec3 SteelBlue; extern const ddVec3 Tan; extern const ddVec3 Teal; extern const ddVec3 Thistle; extern const ddVec3 Tomato; extern const ddVec3 Turquoise; extern const ddVec3 Violet; extern const ddVec3 Wheat; extern const ddVec3 White; extern const ddVec3 WhiteSmoke; extern const ddVec3 Yellow; extern const ddVec3 YellowGreen; } // namespace colors #endif // DEBUG_DRAW_NO_DEFAULT_COLORS // ======================================================== // Optional explicit context mode: // ======================================================== #ifdef DEBUG_DRAW_EXPLICIT_CONTEXT struct OpaqueContextType { }; typedef OpaqueContextType * ContextHandle; #define DD_EXPLICIT_CONTEXT_ONLY(...) __VA_ARGS__ #else // !DEBUG_DRAW_EXPLICIT_CONTEXT #define DD_EXPLICIT_CONTEXT_ONLY(...) /* nothing */ #endif // DEBUG_DRAW_EXPLICIT_CONTEXT // ======================================================== // Debug Draw functions: // - Durations are always in milliseconds. // - Colors are RGB floats in the [0,1] range. // - Positions are in world-space, unless stated otherwise. // ======================================================== // Add a point in 3D space to the debug draw queue. // Point is expressed in world-space coordinates. // Note that not all renderer support configurable point // size, so take the 'size' parameter as a hint only void point(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In pos, ddVec3_In color, float size = 1.0f, int durationMillis = 0, bool depthEnabled = true); // Add a 3D line to the debug draw queue. Note that // lines are expressed in world coordinates, and so are // all wireframe primitives which are built from lines. void line(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In from, ddVec3_In to, ddVec3_In color, int durationMillis = 0, bool depthEnabled = true); // Add a 2D text string as an overlay to the current view, using a built-in font. // Position is in screen-space pixels, origin at the top-left corner of the screen. // The third element (Z) of the position vector is ignored. // Note: Newlines and tabs are handled (1 tab = 4 spaces). void screenText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const char * str, ddVec3_In pos, ddVec3_In color, float scaling = 1.0f, int durationMillis = 0); // Add a 3D text label centered at the given world position that // gets projected to screen-space. The label always faces the viewer. // sx/sy, sw/sh are the viewport coordinates/size, in pixels. // 'vpMatrix' is the view * projection transform to map the text from 3D to 2D. void projectedText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const char * str, ddVec3_In pos, ddVec3_In color, ddMat4x4_In vpMatrix, int sx, int sy, int sw, int sh, float scaling = 1.0f, int durationMillis = 0); // Add a set of three coordinate axis depicting the position and orientation of the given transform. // 'size' defines the size of the arrow heads. 'length' defines the length of the arrow's base line. void axisTriad(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddMat4x4_In transform, float size, float length, int durationMillis = 0, bool depthEnabled = true); // Add a 3D line with an arrow-like end to the debug draw queue. // 'size' defines the arrow head size. 'from' and 'to' the length of the arrow's base line. void arrow(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In from, ddVec3_In to, ddVec3_In color, float size, int durationMillis = 0, bool depthEnabled = true); // Add an axis-aligned cross (3 lines converging at a point) to the debug draw queue. // 'length' defines the length of the crossing lines. // 'center' is the world-space point where the lines meet. void cross(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, float length, int durationMillis = 0, bool depthEnabled = true); // Add a wireframe circle to the debug draw queue. void circle(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In planeNormal, ddVec3_In color, float radius, float numSteps, int durationMillis = 0, bool depthEnabled = true); // Add a wireframe plane in 3D space to the debug draw queue. // If 'normalVecScale' is not zero, a line depicting the plane normal is also draw. void plane(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In planeNormal, ddVec3_In planeColor, ddVec3_In normalVecColor, float planeScale, float normalVecScale, int durationMillis = 0, bool depthEnabled = true); // Add a wireframe sphere to the debug draw queue. void sphere(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In color, float radius, int durationMillis = 0, bool depthEnabled = true); // Add a wireframe cone to the debug draw queue. // The cone 'apex' is the point where all lines meet. // The length of the 'dir' vector determines the thickness. // 'baseRadius' & 'apexRadius' are in degrees. void cone(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In apex, ddVec3_In dir, ddVec3_In color, float baseRadius, float apexRadius, int durationMillis = 0, bool depthEnabled = true); // Wireframe box from the eight points that define it. void box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const ddVec3 points[8], ddVec3_In color, int durationMillis = 0, bool depthEnabled = true); // Add a wireframe box to the debug draw queue. void box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In color, float width, float height, float depth, int durationMillis = 0, bool depthEnabled = true); // Add a wireframe Axis Aligned Bounding Box (AABB) to the debug draw queue. void aabb(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In mins, ddVec3_In maxs, ddVec3_In color, int durationMillis = 0, bool depthEnabled = true); // Add a wireframe frustum pyramid to the debug draw queue. // 'invClipMatrix' is the inverse of the matrix defining the frustum // (AKA clip) volume, which normally consists of the projection * view matrix. // E.g.: inverse(projMatrix * viewMatrix) void frustum(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddMat4x4_In invClipMatrix, ddVec3_In color, int durationMillis = 0, bool depthEnabled = true); // Add a vertex normal for debug visualization. // The normal vector 'normal' is assumed to be already normalized. void vertexNormal(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In origin, ddVec3_In normal, float length, int durationMillis = 0, bool depthEnabled = true); // Add a "tangent basis" at a given point in world space. // Color scheme used is: normal=WHITE, tangent=YELLOW, bi-tangent=MAGENTA. // The normal vector, tangent and bi-tangent vectors are assumed to be already normalized. void tangentBasis(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In origin, ddVec3_In normal, ddVec3_In tangent, ddVec3_In bitangent, float lengths, int durationMillis = 0, bool depthEnabled = true); // Makes a 3D square grid of lines along the X and Z planes. // 'y' defines the height in the Y axis where the grid is placed. // The grid will go from 'mins' to 'maxs' units in both the X and Z. // 'step' defines the gap between each line of the grid. void xzSquareGrid(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) float mins, float maxs, float y, float step, ddVec3_In color, int durationMillis = 0, bool depthEnabled = true); // Add a wireframe capsule to the debug draw queue. void capsule(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In axis, float length, float radius, ddVec3_In color, const int durationMillis = 0, const bool depthEnabled = true); // ======================================================== // Debug Draw vertex type: // The only drawing type the user has to interface with. // ======================================================== union DrawVertex { struct { float x, y, z; float r, g, b; float size; } point; struct { float x, y, z; float r, g, b; } line; struct { float x, y; float u, v; float r, g, b; } glyph; }; // // Opaque handle to a texture object. // Used by the debug text drawing functions. // struct OpaqueTextureType { }; typedef OpaqueTextureType * GlyphTextureHandle; // ======================================================== // Debug Draw rendering callbacks: // Implementation is provided by the user so we don't // tie this code directly to a specific rendering API. // ======================================================== class RenderInterface { public: // // These are called by dd::flush() before any drawing and after drawing is finished. // User can override these to perform any common setup for subsequent draws and to // cleanup afterwards. By default, no-ops stubs are provided. // virtual void beginDraw(); virtual void endDraw(); // // Create/free the glyph bitmap texture used by the debug text drawing functions. // The debug renderer currently only creates one of those on startup. // // You're not required to implement these two if you don't care about debug text drawing. // Default no-op stubs are provided by default, which disable debug text rendering. // // Texture dimensions are in pixels, data format is always 8-bits per pixel (Grayscale/GL_RED). // The pixel values range from 255 for a pixel within a glyph to 0 for a transparent pixel. // If createGlyphTexture() returns null, the renderer will disable all text drawing functions. // virtual GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels); virtual void destroyGlyphTexture(GlyphTextureHandle glyphTex); // // Batch drawing methods for the primitives used by the debug renderer. // If you don't wish to support a given primitive type, don't override the method. // virtual void drawPointList(const DrawVertex * points, int count, bool depthEnabled); virtual void drawLineList(const DrawVertex * lines, int count, bool depthEnabled); virtual void drawGlyphList(const DrawVertex * glyphs, int count, GlyphTextureHandle glyphTex); // User defined cleanup. Nothing by default. virtual ~RenderInterface() = 0; }; // ======================================================== // Housekeeping functions: // ======================================================== // Flags for dd::flush() enum FlushFlags { FlushPoints = 1 << 1, FlushLines = 1 << 2, FlushText = 1 << 3, FlushAll = (FlushPoints | FlushLines | FlushText) }; // Initialize with the user-supplied renderer interface. // Given object must remain valid until after dd::shutdown() is called! // If 'renderer' is null, the Debug Draw functions become no-ops, but // can still be safely called. bool initialize(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle * outCtx,) RenderInterface * renderer); // After this is called, it is safe to dispose the dd::RenderInterface instance // you passed to dd::initialize(). Shutdown will also attempt to free the glyph texture. void shutdown(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)); // Test if the Debug Draw library is currently initialized and has a render interface. bool isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)); // Test if there's data in the debug draw queue and dd::flush() should be called. bool hasPendingDraws(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)); // Manually removes all queued debug render data without drawing. // This is not normally called. To draw stuff, call dd::flush() instead. void clear(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)); // Actually calls the dd::RenderInterface to consume the debug draw queues. // Objects that have expired their lifetimes get removed. Pass the current // application time in milliseconds to remove timed objects that have expired. // Passing zero removes all objects after they get drawn, regardless of lifetime. void flush(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) std::int64_t currTimeMillis = 0, std::uint32_t flags = FlushAll); } // namespace dd // ================== End of header file ================== #endif // DEBUG_DRAW_HPP // ================== End of header file ================== // ================================================================================================ // // Debug Draw Implementation // // ================================================================================================ #ifdef DEBUG_DRAW_IMPLEMENTATION #ifndef DD_MALLOC #include #define DD_MALLOC std::malloc #define DD_MFREE std::free #endif // DD_MALLOC #if DEBUG_DRAW_USE_STD_MATH #include #include #endif // DEBUG_DRAW_USE_STD_MATH namespace dd { #if defined(FLT_EPSILON) && DEBUG_DRAW_USE_STD_MATH static const float FloatEpsilon = FLT_EPSILON; #else // !FLT_EPSILON || !DEBUG_DRAW_USE_STD_MATH static const float FloatEpsilon = 1e-14; #endif // FLT_EPSILON && DEBUG_DRAW_USE_STD_MATH #if defined(M_PI) && DEBUG_DRAW_USE_STD_MATH static const float PI = static_cast(M_PI); #else // !M_PI || !DEBUG_DRAW_USE_STD_MATH static const float PI = 3.1415926535897931f; #endif // M_PI && DEBUG_DRAW_USE_STD_MATH static const float HalfPI = PI * 0.5f; static const float TAU = PI * 2.0f; template static inline float degreesToRadians(const T degrees) { return (static_cast(degrees) * PI / 180.0f); } template static inline int arrayLength(const T (&)[Size]) { return Size; } // ======================================================== // Built-in color constants: // ======================================================== #ifndef DEBUG_DRAW_NO_DEFAULT_COLORS namespace colors { const ddVec3 AliceBlue = {0.941176f, 0.972549f, 1.000000f}; const ddVec3 AntiqueWhite = {0.980392f, 0.921569f, 0.843137f}; const ddVec3 Aquamarine = {0.498039f, 1.000000f, 0.831373f}; const ddVec3 Azure = {0.941176f, 1.000000f, 1.000000f}; const ddVec3 Beige = {0.960784f, 0.960784f, 0.862745f}; const ddVec3 Bisque = {1.000000f, 0.894118f, 0.768627f}; const ddVec3 Black = {0.000000f, 0.000000f, 0.000000f}; const ddVec3 BlanchedAlmond = {1.000000f, 0.921569f, 0.803922f}; const ddVec3 Blue = {0.000000f, 0.000000f, 1.000000f}; const ddVec3 BlueViolet = {0.541176f, 0.168627f, 0.886275f}; const ddVec3 Brown = {0.647059f, 0.164706f, 0.164706f}; const ddVec3 BurlyWood = {0.870588f, 0.721569f, 0.529412f}; const ddVec3 CadetBlue = {0.372549f, 0.619608f, 0.627451f}; const ddVec3 Chartreuse = {0.498039f, 1.000000f, 0.000000f}; const ddVec3 Chocolate = {0.823529f, 0.411765f, 0.117647f}; const ddVec3 Coral = {1.000000f, 0.498039f, 0.313726f}; const ddVec3 CornflowerBlue = {0.392157f, 0.584314f, 0.929412f}; const ddVec3 Cornsilk = {1.000000f, 0.972549f, 0.862745f}; const ddVec3 Crimson = {0.862745f, 0.078431f, 0.235294f}; const ddVec3 Cyan = {0.000000f, 1.000000f, 1.000000f}; const ddVec3 DarkBlue = {0.000000f, 0.000000f, 0.545098f}; const ddVec3 DarkCyan = {0.000000f, 0.545098f, 0.545098f}; const ddVec3 DarkGoldenRod = {0.721569f, 0.525490f, 0.043137f}; const ddVec3 DarkGray = {0.662745f, 0.662745f, 0.662745f}; const ddVec3 DarkGreen = {0.000000f, 0.392157f, 0.000000f}; const ddVec3 DarkKhaki = {0.741176f, 0.717647f, 0.419608f}; const ddVec3 DarkMagenta = {0.545098f, 0.000000f, 0.545098f}; const ddVec3 DarkOliveGreen = {0.333333f, 0.419608f, 0.184314f}; const ddVec3 DarkOrange = {1.000000f, 0.549020f, 0.000000f}; const ddVec3 DarkOrchid = {0.600000f, 0.196078f, 0.800000f}; const ddVec3 DarkRed = {0.545098f, 0.000000f, 0.000000f}; const ddVec3 DarkSalmon = {0.913725f, 0.588235f, 0.478431f}; const ddVec3 DarkSeaGreen = {0.560784f, 0.737255f, 0.560784f}; const ddVec3 DarkSlateBlue = {0.282353f, 0.239216f, 0.545098f}; const ddVec3 DarkSlateGray = {0.184314f, 0.309804f, 0.309804f}; const ddVec3 DarkTurquoise = {0.000000f, 0.807843f, 0.819608f}; const ddVec3 DarkViolet = {0.580392f, 0.000000f, 0.827451f}; const ddVec3 DeepPink = {1.000000f, 0.078431f, 0.576471f}; const ddVec3 DeepSkyBlue = {0.000000f, 0.749020f, 1.000000f}; const ddVec3 DimGray = {0.411765f, 0.411765f, 0.411765f}; const ddVec3 DodgerBlue = {0.117647f, 0.564706f, 1.000000f}; const ddVec3 FireBrick = {0.698039f, 0.133333f, 0.133333f}; const ddVec3 FloralWhite = {1.000000f, 0.980392f, 0.941176f}; const ddVec3 ForestGreen = {0.133333f, 0.545098f, 0.133333f}; const ddVec3 Gainsboro = {0.862745f, 0.862745f, 0.862745f}; const ddVec3 GhostWhite = {0.972549f, 0.972549f, 1.000000f}; const ddVec3 Gold = {1.000000f, 0.843137f, 0.000000f}; const ddVec3 GoldenRod = {0.854902f, 0.647059f, 0.125490f}; const ddVec3 Gray = {0.501961f, 0.501961f, 0.501961f}; const ddVec3 Green = {0.000000f, 0.501961f, 0.000000f}; const ddVec3 GreenYellow = {0.678431f, 1.000000f, 0.184314f}; const ddVec3 HoneyDew = {0.941176f, 1.000000f, 0.941176f}; const ddVec3 HotPink = {1.000000f, 0.411765f, 0.705882f}; const ddVec3 IndianRed = {0.803922f, 0.360784f, 0.360784f}; const ddVec3 Indigo = {0.294118f, 0.000000f, 0.509804f}; const ddVec3 Ivory = {1.000000f, 1.000000f, 0.941176f}; const ddVec3 Khaki = {0.941176f, 0.901961f, 0.549020f}; const ddVec3 Lavender = {0.901961f, 0.901961f, 0.980392f}; const ddVec3 LavenderBlush = {1.000000f, 0.941176f, 0.960784f}; const ddVec3 LawnGreen = {0.486275f, 0.988235f, 0.000000f}; const ddVec3 LemonChiffon = {1.000000f, 0.980392f, 0.803922f}; const ddVec3 LightBlue = {0.678431f, 0.847059f, 0.901961f}; const ddVec3 LightCoral = {0.941176f, 0.501961f, 0.501961f}; const ddVec3 LightCyan = {0.878431f, 1.000000f, 1.000000f}; const ddVec3 LightGoldenYellow = {0.980392f, 0.980392f, 0.823529f}; const ddVec3 LightGray = {0.827451f, 0.827451f, 0.827451f}; const ddVec3 LightGreen = {0.564706f, 0.933333f, 0.564706f}; const ddVec3 LightPink = {1.000000f, 0.713726f, 0.756863f}; const ddVec3 LightSalmon = {1.000000f, 0.627451f, 0.478431f}; const ddVec3 LightSeaGreen = {0.125490f, 0.698039f, 0.666667f}; const ddVec3 LightSkyBlue = {0.529412f, 0.807843f, 0.980392f}; const ddVec3 LightSlateGray = {0.466667f, 0.533333f, 0.600000f}; const ddVec3 LightSteelBlue = {0.690196f, 0.768627f, 0.870588f}; const ddVec3 LightYellow = {1.000000f, 1.000000f, 0.878431f}; const ddVec3 Lime = {0.000000f, 1.000000f, 0.000000f}; const ddVec3 LimeGreen = {0.196078f, 0.803922f, 0.196078f}; const ddVec3 Linen = {0.980392f, 0.941176f, 0.901961f}; const ddVec3 Magenta = {1.000000f, 0.000000f, 1.000000f}; const ddVec3 Maroon = {0.501961f, 0.000000f, 0.000000f}; const ddVec3 MediumAquaMarine = {0.400000f, 0.803922f, 0.666667f}; const ddVec3 MediumBlue = {0.000000f, 0.000000f, 0.803922f}; const ddVec3 MediumOrchid = {0.729412f, 0.333333f, 0.827451f}; const ddVec3 MediumPurple = {0.576471f, 0.439216f, 0.858824f}; const ddVec3 MediumSeaGreen = {0.235294f, 0.701961f, 0.443137f}; const ddVec3 MediumSlateBlue = {0.482353f, 0.407843f, 0.933333f}; const ddVec3 MediumSpringGreen = {0.000000f, 0.980392f, 0.603922f}; const ddVec3 MediumTurquoise = {0.282353f, 0.819608f, 0.800000f}; const ddVec3 MediumVioletRed = {0.780392f, 0.082353f, 0.521569f}; const ddVec3 MidnightBlue = {0.098039f, 0.098039f, 0.439216f}; const ddVec3 MintCream = {0.960784f, 1.000000f, 0.980392f}; const ddVec3 MistyRose = {1.000000f, 0.894118f, 0.882353f}; const ddVec3 Moccasin = {1.000000f, 0.894118f, 0.709804f}; const ddVec3 NavajoWhite = {1.000000f, 0.870588f, 0.678431f}; const ddVec3 Navy = {0.000000f, 0.000000f, 0.501961f}; const ddVec3 OldLace = {0.992157f, 0.960784f, 0.901961f}; const ddVec3 Olive = {0.501961f, 0.501961f, 0.000000f}; const ddVec3 OliveDrab = {0.419608f, 0.556863f, 0.137255f}; const ddVec3 Orange = {1.000000f, 0.647059f, 0.000000f}; const ddVec3 OrangeRed = {1.000000f, 0.270588f, 0.000000f}; const ddVec3 Orchid = {0.854902f, 0.439216f, 0.839216f}; const ddVec3 PaleGoldenRod = {0.933333f, 0.909804f, 0.666667f}; const ddVec3 PaleGreen = {0.596078f, 0.984314f, 0.596078f}; const ddVec3 PaleTurquoise = {0.686275f, 0.933333f, 0.933333f}; const ddVec3 PaleVioletRed = {0.858824f, 0.439216f, 0.576471f}; const ddVec3 PapayaWhip = {1.000000f, 0.937255f, 0.835294f}; const ddVec3 PeachPuff = {1.000000f, 0.854902f, 0.725490f}; const ddVec3 Peru = {0.803922f, 0.521569f, 0.247059f}; const ddVec3 Pink = {1.000000f, 0.752941f, 0.796078f}; const ddVec3 Plum = {0.866667f, 0.627451f, 0.866667f}; const ddVec3 PowderBlue = {0.690196f, 0.878431f, 0.901961f}; const ddVec3 Purple = {0.501961f, 0.000000f, 0.501961f}; const ddVec3 RebeccaPurple = {0.400000f, 0.200000f, 0.600000f}; const ddVec3 Red = {1.000000f, 0.000000f, 0.000000f}; const ddVec3 RosyBrown = {0.737255f, 0.560784f, 0.560784f}; const ddVec3 RoyalBlue = {0.254902f, 0.411765f, 0.882353f}; const ddVec3 SaddleBrown = {0.545098f, 0.270588f, 0.074510f}; const ddVec3 Salmon = {0.980392f, 0.501961f, 0.447059f}; const ddVec3 SandyBrown = {0.956863f, 0.643137f, 0.376471f}; const ddVec3 SeaGreen = {0.180392f, 0.545098f, 0.341176f}; const ddVec3 SeaShell = {1.000000f, 0.960784f, 0.933333f}; const ddVec3 Sienna = {0.627451f, 0.321569f, 0.176471f}; const ddVec3 Silver = {0.752941f, 0.752941f, 0.752941f}; const ddVec3 SkyBlue = {0.529412f, 0.807843f, 0.921569f}; const ddVec3 SlateBlue = {0.415686f, 0.352941f, 0.803922f}; const ddVec3 SlateGray = {0.439216f, 0.501961f, 0.564706f}; const ddVec3 Snow = {1.000000f, 0.980392f, 0.980392f}; const ddVec3 SpringGreen = {0.000000f, 1.000000f, 0.498039f}; const ddVec3 SteelBlue = {0.274510f, 0.509804f, 0.705882f}; const ddVec3 Tan = {0.823529f, 0.705882f, 0.549020f}; const ddVec3 Teal = {0.000000f, 0.501961f, 0.501961f}; const ddVec3 Thistle = {0.847059f, 0.749020f, 0.847059f}; const ddVec3 Tomato = {1.000000f, 0.388235f, 0.278431f}; const ddVec3 Turquoise = {0.250980f, 0.878431f, 0.815686f}; const ddVec3 Violet = {0.933333f, 0.509804f, 0.933333f}; const ddVec3 Wheat = {0.960784f, 0.870588f, 0.701961f}; const ddVec3 White = {1.000000f, 1.000000f, 1.000000f}; const ddVec3 WhiteSmoke = {0.960784f, 0.960784f, 0.960784f}; const ddVec3 Yellow = {1.000000f, 1.000000f, 0.000000f}; const ddVec3 YellowGreen = {0.603922f, 0.803922f, 0.196078f}; } // namespace colors #endif // DEBUG_DRAW_NO_DEFAULT_COLORS // ======================================================== // Embedded bitmap font for debug text rendering: // ======================================================== struct FontChar { std::uint16_t x; std::uint16_t y; }; struct FontCharSet { enum { MaxChars = 256 }; const std::uint8_t * bitmap; int bitmapWidth; int bitmapHeight; int bitmapColorChannels; int bitmapDecompressSize; int charBaseHeight; int charWidth; int charHeight; int charCount; FontChar chars[MaxChars]; }; #if DEBUG_DRAW_CXX11_SUPPORTED #define DD_ALIGNED_BUFFER(name) alignas(16) static const std::uint8_t name[] #else // !C++11 #if defined(__GNUC__) // Clang & GCC #define DD_ALIGNED_BUFFER(name) static const std::uint8_t name[] __attribute__((aligned(16))) #elif defined(_MSC_VER) // Visual Studio #define DD_ALIGNED_BUFFER(name) __declspec(align(16)) static const std::uint8_t name[] #else // Unknown compiler #define DD_ALIGNED_BUFFER(name) static const std::uint8_t name[] /* hope for the best! */ #endif // Compiler id #endif // DEBUG_DRAW_CXX11_SUPPORTED // // Data generated from font 'Monoid18' by font-tool. // Command line: monoid-18.fnt monoid-18.png monoid-18.h Monoid18 --static --compress --structs --hex --encoding=lzw // // The Monoid font, copyright (c) 2015 Andreas Larsen and contributors, // is released under the MIT license. See: https://github.com/larsenwork/monoid // // The following glyph bitmap is an LZW compressed graymap. // ~7.55 KB of data. // // It is better to ensure it is aligned to a, say 16 bytes boundary, // because we cast the first few bytes to uint32s. // // font-tool: https://github.com/glampert/font-tool // LZW compression: https://github.com/glampert/compression-algorithms // DD_ALIGNED_BUFFER(s_fontMonoid18Bitmap) = "\x2F\x1E\x00\x00\x78\xF1\x00\x00\x00\x00\x06\x14\x38\x90\x60\x41\x83\x07\x11\x26\x54\xB8" "\x90\x61\x43\x87\x0F\x21\x46\x94\x38\x91\x62\x45\x8B\x17\x31\x66\xD4\x88\x70\x43\x13\x8C" "\x15\x80\x0D\xD8\x98\x10\x0D\x98\x84\x4D\x36\x8C\x8C\x28\x40\xC1\x01\x95\x2F\x1F\x06\x10" "\x10\x00\x26\xC0\x44\xFE\x5C\x5A\xA4\xF4\x8F\x4E\xCD\x81\x01\xF8\xFD\x4B\x70\x30\x40\x3F" "\x3F\x3E\x17\x32\xFA\xB7\xB4\x5F\xCA\x8C\x67\xFC\xD1\x04\xB0\x2F\x0D\x52\x82\x74\x96\xF2" "\x54\xD9\xC4\x5D\xD6\xA5\xBF\x10\x36\x5B\xBA\xE3\x60\x81\x7E\xFD\xA4\x2E\x3C\xC0\xE8\xDB" "\xD2\x77\xC1\x2A\x34\xF4\xF2\xEF\x52\x42\x7E\x3D\xAD\x1E\x74\xB5\x34\x13\xB4\xA5\x11\x9E" "\x46\x05\x78\x37\x6F\xC0\x25\x4B\xDB\xFE\xAB\xB2\x51\x0E\xE2\x7E\xFF\xDE\xF9\x73\xA6\xF7" "\x9F\xBF\xA5\x14\x0E\xEE\xFC\xC2\xD0\x44\x56\x7F\xEF\xB2\xB2\x60\xA8\xCF\xDF\x50\x84\x84" "\x0B\x13\x8C\xF0\xAF\x5F\xCE\x2F\xFF\xC0\x62\x84\x4A\x13\x28\xDE\xC2\xD8\xFC\xC5\xA5\xE0" "\xAF\x5B\x40\x1A\x16\x0F\xF8\xF3\x67\x02\x40\x17\x7F\x09\x4B\xB0\x06\x30\xE4\x5F\x6F\x83" "\xC1\xFB\x31\xDC\xF7\x4F\x4D\x5A\x2B\xFF\xD8\x2D\x9C\xF2\x8F\x94\x42\xD4\xA9\x05\x7E\xF8" "\x57\x35\xE0\x3E\x6E\x19\x8D\x07\xE4\x47\xBE\xF0\xB2\xE3\x83\x9D\x2B\x1A\x5F\x91\xF9\x66" "\x00\xB3\x11\x66\xFB\x07\x02\xA0\xB2\x7F\xA2\x0D\x12\xE5\x1F\x26\x14\x3A\xAC\xBB\x81\x70" "\x4B\xEB\xA0\x7C\xFE\x01\xCC\x2E\xDB\x16\x6A\x86\xC0\x8C\xC4\x3B\x10\x80\x01\xFA\x71\xCE" "\xA2\x59\xDA\x9A\xC5\xC3\x7F\xBE\x01\x46\x23\x09\x11\x4A\xE4\x1F\x6F\x9A\xE8\x86\x2E\x00" "\xE4\x6B\xAD\xA2\xC6\x34\x00\x08\x3F\x83\x34\xF8\x67\x32\x80\x6A\xBC\xB1\x20\x08\xFE\xE1" "\x47\x21\x34\xFE\xF9\x00\xA0\x06\xAC\x00\xC3\x0A\x67\x04\x43\x88\xB9\xD8\x1E\x74\xE8\x3B" "\x8C\xA6\xC3\x0C\x00\x66\xB4\xB2\x28\x00\xCB\xBC\x5A\x2A\xC9\x81\x5A\x3A\xC0\xCB\x03\x14" "\x10\xC0\x3B\x08\x0B\xDA\x26\xAB\x76\x00\x30\xB1\x1F\x91\x2A\x92\x61\xC5\xFB\xB6\x24\x48" "\x97\x7F\x66\x10\xE8\x9E\x06\x0F\xDA\xE5\x1F\xB2\x10\x82\xCA\x00\x00\xD2\xC8\x32\xCE\x82" "\xD2\xF9\x27\xC6\x31\x9D\x24\xD3\xA2\xC3\xFC\x51\xE3\xB1\xE8\x30\x12\xC0\x0F\x7F\x1A\x20" "\xA0\x01\x7E\xFE\x10\x93\xA0\x2B\xB3\xFC\xE7\xA8\x26\x13\x32\x81\x08\xE2\xD4\xFC\xD3\x22" "\x0C\xFF\xA9\x03\x00\x34\xDE\x7B\xCE\xC1\x80\x0E\x78\xB5\xA0\x0C\xFE\x41\xB3\xCF\xE3\x3C" "\xA8\xAC\x89\x06\x14\xF8\x63\xD0\x81\xDC\xD4\x11\xD4\x83\x36\x88\x6B\x30\xF2\x04\xF8\x8D" "\xA0\x06\x32\x99\x45\xD5\x80\x76\x90\xC5\xA0\x40\xB3\x7A\x46\x41\x8B\x66\x7C\x72\x20\x60" "\x3C\xEC\x36\x98\x09\x4F\x53\xF4\x20\x4B\x58\x33\xF5\xA2\x1D\xBC\xF2\xC7\x8A\x8D\x96\xF9" "\xEF\x56\x00\xCC\xD8\x33\x20\x57\x7E\x15\x48\x3F\xFE\x16\xD2\x96\x20\x7B\x2A\xAB\x03\x84" "\x7E\x30\x31\x21\x98\xA5\x00\x0C\x08\xA8\xAC\x20\x05\xA0\x92\x5F\x47\xF1\x0A\x2F\x01\x08" "\x90\x2D\x49\x7D\x21\x92\x49\x00\x01\x0E\xC0\x14\x80\x8B\x35\x35\x88\x5C\x17\x0D\xB2\x98" "\xE3\x91\x3B\x26\x08\x24\xAF\xFA\x31\xED\xA2\xE4\x34\x2C\x08\x2A\x78\xF7\x0B\x28\x9B\x7A" "\x01\x62\xB9\x21\x8A\x05\x02\x23\xB1\x4E\x4D\x71\x2A\xA0\x19\xFE\x29\x25\x02\x75\x60\x03" "\x68\xE6\x6B\x19\xAD\x80\x07\xD6\x44\x92\x83\xE6\x87\xD2\x3B\xD6\xA2\xC6\x3A\xD5\xF2\xDA" "\x80\x1A\x5E\x13\x21\xAA\xAB\x7E\x7A\xAA\x45\x2A\x50\xD1\xC7\x8C\xB4\x89\xD9\xA0\x97\xE3" "\xAD\x13\x00\x1E\x9F\x6E\xB7\x60\x44\x15\x52\x00\x0C\x84\xF1\x25\xA8\x31\x21\x03\x98\x6E" "\x16\x40\xB0\x23\xA8\xEC\x12\x00\x12\x70\xB2\x19\x29\x6A\x62\x16\x7F\xC0\x68\x02\x0C\x7F" "\x80\xF1\x88\x22\x2A\xBE\x81\x46\x72\xC8\x24\x87\xC6\x9B\xAB\x01\xC8\x5A\x01\xC3\x67\x31" "\x89\x20\xC8\x2B\x0F\xDD\x72\xCC\xD5\x23\xAF\x6C\x21\x31\x0A\xF6\xA0\x97\x55\xA8\x8C\x07" "\x1E\x82\xA2\x99\x56\x5B\x19\xC2\x99\xA0\xE4\x96\x6A\x79\x20\xA7\xD9\x8C\x00\x4B\x79\x05" "\x02\x2A\xBB\x80\xF4\xF9\x87\x08\x2A\xBC\x5E\x28\x80\xAA\x97\x22\x3D\xA2\xF5\x12\x6A\x18" "\xA7\x4A\xBC\x8A\x45\x23\xD4\x56\x98\x2F\xA3\x42\x8D\x25\xE8\x8C\x7F\x20\x00\x60\xAF\xA5" "\xDC\x09\x86\x66\x3D\xF9\xAC\x5D\x5C\x82\x50\x25\x42\x2C\x45\x0C\x8A\xA0\x85\xE0\x79\x20" "\xA2\x81\x4D\xF9\x39\x2F\xA0\x1A\xAD\xB6\xA8\x85\x52\xFC\xC1\x83\x16\xF0\xA0\x1F\xA5\x98" "\x5F\x41\x82\x92\xA5\xF5\x19\xCC\x76\x99\xAB\x4C\x02\x14\xC0\x9A\x0A\x54\x80\x1D\x86\xCA" "\x08\x6A\x68\xB5\xC0\x88\xA0\xCB\x17\x06\x69\x0C\xE0\x00\xC0\x03\x40\xA8\x01\x00\x0D\x50" "\x16\x41\x78\x34\xB6\x9B\x69\x30\x20\xED\xEA\x4E\x70\xFE\x41\x9C\x8A\xE8\xE7\x50\x00\x01" "\x12\x6B\x9C\xE7\x90\xA8\x01\x00\x7A\x06\xD1\xC7\x3B\x80\x08\x44\x7F\xB0\xE7\x20\x0D\xDC" "\x07\xA5\x00\x50\x23\x34\x00\xA4\x0B\x66\xB3\x12\x6A\x4C\xF4\xB6\x8B\x30\x48\x56\xD0\xE2" "\x8E\x43\x04\x04\x2E\xF5\x29\x84\x02\xCA\x01\x08\x73\x84\x25\x11\x2A\x54\x46\x86\x00\x28" "\x40\xEE\x24\x26\x95\x06\x56\xCC\x28\x08\x69\x80\x83\xC4\x53\x8A\xC0\xFD\x03\x84\x14\x51" "\x63\x55\xAE\xE3\x0F\x73\x61\x64\x3B\x16\x1A\xC8\x74\x00\x51\xB2\x92\x09\x04\x3A\x10\x59" "\x23\x40\x22\x20\xAB\x13\x56\xE4\x15\xE4\x6B\x96\x57\x0E\x58\x91\x6C\xB1\x10\x22\x28\x69" "\x48\xF1\x26\x97\xB0\x89\xD4\xC8\x1F\x6D\xF9\xCC\x52\x86\xA0\x12\xD2\xA8\x4C\x20\x2D\xF0" "\x0C\x68\x96\x82\xBA\x81\x68\xC6\x90\x94\xF4\x09\x0F\xBA\x92\x15\x40\x5C\x47\x93\x00\x00" "\x81\x15\x9A\x90\x4B\x5D\xE6\x72\x5D\x67\x4B\x12\x55\xC0\x33\x90\x06\x54\xF0\x1F\xEE\xA8" "\x62\x44\x28\xF0\x18\xAF\x78\xC3\x67\x1B\x99\xCB\x22\x0C\xA2\x80\x4C\x24\xE6\x33\xDF\xE8" "\x5E\x40\xCC\x82\x96\x56\x06\xB3\x20\x04\xF0\x12\x42\xF6\xC0\xBC\xE6\x71\x53\x22\xDF\xD4" "\x88\x02\xFC\x51\x97\x9A\x1C\x8C\x94\x10\xD9\x89\x2B\x09\x72\x48\x72\xAA\xA6\x05\x26\xB0" "\xE7\x3D\xED\x19\xC9\x79\xEE\x13\x20\x96\xF4\xC9\x17\x3C\x37\x91\x0A\xCC\x82\x4D\x0F\x91" "\x27\x3F\x11\x9A\x50\x85\xF2\x13\x98\x0B\x75\xE8\x43\x21\x1A\x51\x89\x4E\x94\xA2\x15\xB5" "\xE8\x45\x31\x9A\x51\x8D\x6E\x94\xA3\x1D\xF5\xE8\x47\x41\x1A\x52\x91\x8E\x94\xA4\x25\x35" "\xE9\x49\x51\x9A\x52\x95\xAE\x14\xA1\x8C\x00\xC3\xFD\x20\x42\x03\x46\xE8\x73\x20\x44\xB0" "\xE9\x4D\x15\xB2\x81\x9B\xDA\xB4\x99\x03\xA1\x41\xDD\x20\x12\x50\x96\xA2\x94\x53\xFF\x80" "\x66\x43\x2A\xA0\x4C\xF8\x15\x64\x79\xE9\xCA\x21\x00\xB8\xB6\x94\xA5\x16\x64\x3A\x47\x75" "\x48\x04\x82\x42\xC4\xA1\x1E\x04\x62\x83\xAC\x68\x04\x16\x07\xBC\x85\x60\xE3\x1F\xC0\x30" "\x41\x4E\x0A\x42\x03\xB5\xFE\x2F\x79\x50\x21\x82\x5A\x69\x70\xCD\x81\xF0\xC0\x32\x98\x70" "\x08\x03\x1E\x03\x0C\xB4\x9E\xB4\xA1\x08\x69\x58\xB5\x8E\x39\x10\xF7\x30\x40\xA1\x6E\x82" "\x27\x50\x54\xB8\x10\xE3\x3C\xF5\x65\x0C\x61\x40\x50\x16\xC3\x10\x06\x59\x35\xA5\x87\xC4" "\x0D\x34\x4C\xA1\x4C\x98\x1A\x64\x8C\xEA\x44\x28\x86\xE0\xC9\xC3\xA9\x2E\x84\x70\xBE\x7C" "\xAA\x40\xBA\xE8\x0F\xC2\x2A\x84\x7A\xD6\x63\xE9\x21\x4B\xA6\x86\x37\x1D\xE4\x88\x7B\x3C" "\xC8\x25\x42\x3B\x90\x04\xB0\x03\xA8\x06\x39\x28\x0F\xB5\x9A\x90\xD2\xBA\x2C\x79\x03\xE9" "\xAC\x42\x0A\xE0\x8F\x5A\x56\x36\xB7\x00\x00\x8A\xEE\xEC\xF6\x8F\xD1\x1A\x64\x00\xD3\xB1" "\xEB\x43\x22\xF0\x98\xE0\xC6\x73\xBB\x06\xD9\x47\x6E\x87\xEB\xBD\xE2\xFE\x71\xB9\x9F\xD3" "\x9E\x42\x86\x10\x8C\x6F\x2D\x24\xBD\xEB\x45\xE8\x6F\x01\x62\x16\xE8\x0E\x64\x00\xB3\x60" "\x84\xF2\xD6\xF1\x0F\x69\x35\x04\x04\x96\x89\xAC\x5D\x98\x94\x10\x1E\x81\xB7\xAD\xE3\x15" "\x88\x80\x7A\x4B\x90\x76\x05\xD6\x65\x4B\x71\xE5\xF7\xAA\xC4\x4F\xF8\x02\x60\x27\xDD\x9D" "\x48\xA1\xC2\x78\x10\x53\x0E\x48\x79\xFC\xF0\x07\x83\x07\x22\x9F\x4F\x31\x24\xBC\x03\x29" "\x71\x9F\x9C\x68\x10\x65\x18\x98\x6A\xAE\x6C\x71\x42\xE1\x8B\x2E\x7F\x14\x94\x6C\xB5\x7A" "\x2A\x11\xC6\xD2\x10\x13\xFD\x23\x18\x8B\x1C\x08\x23\xBA\x82\xC4\x86\x9C\x38\x20\x44\x36" "\x88\x0E\x52\x5C\x10\x65\x24\x36\x21\x2D\xA8\x43\x1D\x7C\x6C\x10\x27\x43\x39\xA1\xDC\xF8" "\xAF\x42\xC4\x23\xD6\x8D\x50\x09\x64\x05\x79\x0D\x9D\x1C\x32\x80\xAC\x4C\xD7\x60\x58\xF2" "\x23\x69\x0B\x7C\xDA\x81\xD0\x2A\xC1\x03\x51\x86\xFE\xB6\xEA\x10\x74\x44\x58\x25\xBD\xF0" "\x54\xC8\x1E\xD3\x66\x84\x14\xCA\x1B\x34\xD8\xEB\x40\x36\x50\x87\x1C\x0F\x39\xCD\x0F\x19" "\xA3\x9E\x03\xA2\x8C\xF2\xC6\x99\x28\xFC\x60\xF2\x46\x0A\x50\xC1\x05\x06\x85\x84\x0D\x41" "\x2C\x43\x82\x40\x67\x85\x18\x19\x4E\x6A\x16\xC8\xF7\x10\x0D\x10\xF7\x78\x9A\xD1\x00\xD0" "\x87\x85\x2D\xF2\xD8\xA2\x1D\x04\x04\x4B\xA1\xAC\x77\x3C\x9B\x90\xE4\x12\x98\xB1\x06\x4E" "\xF4\x3F\xE4\x4A\x10\x3D\xA9\xB2\xD4\xF3\xCC\xEE\x3F\x5C\x8B\x10\x0D\xD4\xF5\x66\xA8\x1E" "\x08\x7C\x39\xCD\x69\xFA\xF6\xE3\xD1\x04\x41\x32\x99\x2F\xE2\x05\x20\xDA\x27\x21\xD2\x7E" "\x07\xB5\x53\x3A\xEC\x7F\x5C\x57\x21\xBF\x0E\xF6\xB0\xBC\x63\x6C\x13\x17\xBA\x21\x8D\x81" "\xF6\xB2\x67\xBC\x10\x05\x80\x00\x04\x9B\x45\xB1\xA6\xCF\xE6\x60\x75\xB3\xDB\xDD\x19\x31" "\x01\x23\x00\x31\x92\x56\x1B\xF5\xAE\x8F\x09\x30\x75\xFB\x11\x5A\x7E\x9C\xDB\xB4\xC2\xB5" "\x75\x6A\x57\x9B\x10\xEA\xFD\xDB\x83\x4B\x19\xF1\xD6\xE4\xAD\x90\x17\x4B\xDC\xE1\x2A\x99" "\xCE\x79\x2F\xC2\x80\xA5\xFC\x01\x22\x09\x08\x4A\x07\x11\x62\x58\x86\x00\x85\x76\x8A\x2D" "\x70\x43\x32\xF6\x0F\x6C\x27\xA4\x78\x1C\x17\x6E\xC4\x13\xB2\x01\x2B\xF8\xC3\x95\x32\xA7" "\x39\x69\x61\x9E\x91\x83\xDD\x59\x23\x7D\x68\x2E\x36\xD9\x51\x6F\x81\x34\xA0\x09\x8F\xA9" "\xA3\x42\x0A\x35\x0B\x10\x44\xCC\x20\x34\x68\x41\x3D\x01\x58\x6B\x01\xB6\x20\xAE\x1A\x7E" "\x8C\x1C\x1B\xE2\xBB\xA0\x31\x3D\xDE\x18\x07\xF7\xD7\xBB\x2E\xEE\x88\x34\x32\xC9\x13\x2D" "\x2A\xD6\x19\xF2\x6B\xE9\x86\x4C\x50\x4F\x8D\xEA\xDA\x7D\xBB\x6D\x88\x24\xD5\xEB\x15\x01" "\x1A\x3C\xEF\x9E\xD0\x03\x90\x3A\xA1\x8C\x50\x03\x88\x11\xC2\x83\x4C\x44\x39\x20\x3B\xB5" "\x69\x4E\x0D\xDF\x53\x81\xF0\xA0\x8C\x10\xA9\x4E\x46\x98\xE3\x2E\xF4\x12\xAC\xD7\x95\xA7" "\x68\x63\x2A\x4D\xF1\xCC\x5B\x9E\xF3\x0F\xF5\x2A\x42\x3E\xDF\x79\xD1\x8F\x9E\xF4\xA5\x37" "\xFD\xE9\x51\x9F\x7A\xD5\xAF\x9E\xF5\xAD\x77\xFD\xEB\x61\x1F\x7B\xD9\xCF\x9E\xF6\xB5\x8F" "\x08\x01\xB8\x9E\x10\x8E\x35\x04\xF7\x2F\xC9\xFD\x45\x03\x80\xFB\xD0\x97\xD4\x77\xDF\x5E" "\xDD\x2F\x51\x8D\xE3\xA5\x3C\x83\xC6\x05\x29\x45\x56\xF4\x9A\x90\xB9\x2D\xC5\x1B\x42\xBF" "\x75\xD5\x78\x5D\x10\xDC\x00\x7E\x2A\x9D\x42\x35\xAB\x4C\xD3\x57\x82\x5C\xDC\x2D\x75\x27" "\xDE\x32\x73\x5D\x90\x06\x74\x43\x9B\x19\x15\x0F\x9C\x6F\xA5\xC6\x05\xF2\x2F\x32\xFF\x80" "\x3F\x41\xFC\xE3\x0F\x68\x58\xA6\xD9\x01\xB9\x21\x34\x40\x83\x66\x7A\xE1\x33\x82\x08\x95" "\x42\x8D\x05\x6A\xC5\x3B\x20\x23\x88\xCC\xAF\x85\x26\x66\x81\x7E\x08\x88\x12\xE3\xE1\x8E" "\xED\x1B\x82\x61\x16\x02\xB0\x9D\x08\xE2\x3A\x2A\x83\xEF\x10\xAA\x46\xEE\xAF\xE0\x78\x68" "\x81\xF4\x64\x31\x02\x80\x68\xD2\x0F\x00\xBA\xA8\xFD\xF4\x43\x6D\xA8\x2A\x37\x00\x62\x11" "\x1A\x50\xFB\xD2\xED\x20\x0A\x25\xFB\x10\x28\xB7\xD0\x41\x85\xE4\x89\x01\x84\x83\xFB\x02" "\x42\x3E\x62\xED\x27\x7E\xA1\x32\xBE\xC1\xD6\x12\x0A\x04\xD1\x4C\xFE\x68\x4B\x85\xF4\xA4" "\xBB\x80\xE6\xBF\x92\x63\x7D\x6A\xC4\xB3\x92\x2B\x04\x0D\x22\x01\x80\x2D\xE4\x56\x0D\xEC" "\x4E\x03\xCE\xE4\x49\x3F\xB4\xC8\x3B\xE6\x0B\x20\xA6\x43\x5A\x16\x4B\xA3\x94\x70\xD3\x1E" "\xB0\x88\xD4\xA9\x8B\xE0\x0D\x20\x60\x24\x20\x40\xCB\x20\xC4\x83\x88\xCC\x83\xC4\x24\xCF" "\x20\xE6\x4C\x4A\xBC\x30\x7E\x78\x6E\x04\x15\x62\x8C\x18\x0E\x21\x82\x03\x0B\x01\x42\x0D" "\x94\xC5\xC8\x16\xA1\x5B\x3C\x04\x1A\x52\x50\x0D\x98\x4F\x20\xAA\xE0\x19\x34\x10\x00\x62" "\x21\x18\xF4\xA9\x14\xA0\xC1\x05\x69\xC4\xFE\x96\x70\x30\x26\x8D\x3C\xC8\x6E\x7D\x40\x4D" "\x20\xBE\xCB\x20\x7C\x90\x49\x78\xA4\x10\x09\x65\xD1\x70\x84\x35\x4C\x80\x06\xB8\x8F\x1F" "\x36\x63\x80\x14\x6F\x20\x6A\x84\x3D\xD6\x28\x01\x94\xEB\x21\xFA\x20\x0E\xC5\x2B\x87\xCE" "\xA1\x53\x8E\x4E\x20\xF8\x00\xCC\x02\x02\x1D\x6A\x70\x20\x80\x24\x61\x98\x43\x6B\x84\xCD" "\x46\x42\x51\x10\x7D\xAB\x27\x78\x04\x10\xC4\x4F\x20\x80\xA4\x6E\x56\x63\x81\x8E\xE8\x80" "\x60\xE1\x1F\x42\x89\x8B\x66\xAB\x20\xDE\x6E\xBF\xBC\xEB\x1B\x94\x89\xDF\x0E\x62\x2E\xEA" "\x66\x8D\xF4\xA3\x1D\x88\xE0\xF7\x0E\x22\x38\xF4\xA8\x1A\x0D\xC2\x9B\x0E\xC0\x52\xCE\x82" "\x74\x92\x63\xAA\x30\xA4\x0C\x01\xA0\x6C\xC8\x63\x3A\x3C\xF1\x13\x11\x71\x20\x98\xE0\x72" "\x00\xC2\xCA\x0C\xA2\x8B\x7A\x42\x14\xFA\x41\x01\xF4\x21\xC3\x00\xE2\x30\x6C\x43\xE4\x0C" "\x02\x01\xFF\x61\x16\xBA\x82\x20\x07\x02\x11\x82\x04\x21\xDA\xA5\x51\x04\x4D\x31\xF0\xAC" "\x32\xAC\x80\x6F\xB4\x6C\x20\x92\xF1\x55\xD6\x08\x1F\x3C\xC3\xB6\x0C\x62\x2F\x28\xF0\xF8" "\x3C\xAD\x31\xC6\x30\x78\xF8\x81\x76\x02\xF2\x20\x34\x2E\x2A\x1A\xC3\xF8\x42\x66\xC2\x12" "\x42\x3C\xD0\xE0\x8C\x8E\x62\x1F\xCA\x90\x47\xFA\xE1\x7E\x08\x80\x68\xAE\x6C\x20\x78\xA4" "\x7A\x46\x03\x16\xCD\xF0\xC3\x6A\xA6\x39\x0E\xA2\x0E\x80\x41\x2A\x96\xE4\x20\x46\x4D\x3D" "\x58\x08\x63\x1A\x80\x1B\xE0\x6E\x1A\xB5\x72\xDC\xD4\x2C\x38\x86\x87\x2C\x4B\x03\x20\x92" "\x51\x8A\x4C\x0C\x32\x70\x68\x8B\x32\xC2\x07\xC1\x60\x52\xFE\x84\x1F\xCE\x4C\x20\xEC\x0C" "\x44\xB2\xC2\x0F\x09\x82\x41\x00\xE1\x00\x36\x60\x3A\x56\xAE\x20\xB2\x27\x27\xFF\xA8\x65" "\xF2\xC1\xC0\xF6\xA1\xFF\x00\x00\x1F\x5A\xA6\x87\x90\x8B\x37\x14\x42\x0C\x09\x4D\xCD\xF6" "\x22\xD4\x00\x60\x2E\x22\x4B\x1B\xF2\x11\x21\xA8\x44\x19\x17\x42\x1F\x1A\xB3\x22\xF6\x21" "\x18\xFA\xA1\x3B\x80\x02\xD5\x32\x01\x65\x0E\x42\x3C\x58\xD1\x2B\x13\x62\x2F\x6A\x31\xD6" "\x56\xCC\xD3\x7E\x93\xA9\x28\x0D\x0C\xC0\xA0\x0E\xFC\x21\x18\x84\xCA\x24\xBD\x06\x68\x4A" "\x8E\x0D\x4F\x4B\x3C\x8C\x92\x20\x34\x6E\x32\xCC\x22\x2E\x0F\xA2\x31\x9A\x91\x9B\xA6\x83" "\x2B\xAD\x31\x21\x98\x63\x08\x3F\x8D\x8E\xEC\xA5\x2D\x85\x27\xDC\x04\xA2\x2C\x17\x22\x38" "\x37\xA5\x1D\xB3\x44\xCD\xEE\xC1\x6B\x18\xA4\xF1\x9C\x13\xE9\xE6\x52\x21\x98\x71\x00\x62" "\x20\x10\x55\xD1\xCC\xF6\x29\x28\x62\x43\x22\x17\x62\xCE\x52\xF0\x3E\x2C\x28\xD1\xBC\xA6" "\x3E\xBC\xC3\x8F\xD4\x53\x21\xD0\x93\x20\x4C\x00\x04\xEC\x09\x04\x5A\xA0\x80\x44\xD3\x01" "\x9D\xA7\x89\x30\x32\xFE\x12\x42\x23\x19\x62\x3B\xC0\x40\x06\x71\x50\xB0\x8C\xE7\x6F\x16" "\xE2\xDE\xF2\x4D\x23\xA2\x04\x20\x90\x4C\xDC\x6C\xE6\x20\x0E\xE3\xCA\xF2\xA1\x2D\xDD\xE3" "\x12\x7D\xD2\x3A\x9D\x72\xE4\xF8\xC1\x3A\xED\x42\xEC\x06\xA3\x39\x7D\x12\x4F\x1C\xC2\xC8" "\xF2\xA6\x2D\x7F\xD4\x8B\x0E\x82\x39\xB2\x23\x7B\x2C\x13\x15\x97\x82\x47\x19\x42\x4F\xEC" "\x83\x41\x06\x54\x66\xF6\xB0\x20\x34\x2E\x65\x00\x02\x2B\xA2\x13\x56\x24\x63\x21\xF4\xE3" "\x80\x98\x00\x14\x43\x46\x20\xFC\xE0\x1C\xFF\xD0\xB9\x04\x02\x2B\x02\x33\x20\x48\x12\x3C" "\xE7\xF3\x20\x4C\x24\x7D\x16\x22\x18\xAF\x88\x28\xA6\x03\x84\xDA\x85\x85\x76\x0E\x32\x27" "\x22\xCB\x66\xE1\x31\x16\x32\x20\x90\x4C\x47\x0B\x42\x40\xFE\xC1\x14\x54\x04\x48\xE3\xAD" "\x27\x0B\x02\x5D\x78\xCC\x2F\xCA\x4E\x3D\xDE\xC2\x14\x62\xC9\xFA\xAE\xB1\x88\x26\x35\x96" "\x0C\xF3\xD8\x10\x23\x88\xFC\xA1\x86\x74\xF2\x34\x2A\xC3\x53\xC5\x6D\x3A\xEC\x52\x20\xA8" "\x47\x47\x38\xC9\x52\x03\x82\xEC\x2A\xF4\x21\x9A\xA0\x5A\x9A\xAF\x20\xC8\xE5\x18\x0D\xC2" "\x25\x8B\x29\x17\xCF\x33\x3B\x11\xA2\x09\xB0\x24\x80\x10\xA2\x78\xB2\xC2\x1D\xA6\x74\xFC" "\x2C\x4C\x58\xC9\x47\x57\xCD\xB0\x6A\x40\x55\x04\xBD\xAB\x53\x28\x49\x1F\xB4\xD2\x07\xFF" "\xC1\x30\xF7\x62\x4D\x07\x62\xEF\x5E\xA2\x25\x1A\x82\x55\x09\x02\x63\xFE\x2C\x23\xCC\x29" "\x21\x82\x6F\x5C\x75\x8E\x1F\x37\xAA\x4C\xDD\xD4\xF6\xD8\xF5\x21\x64\xE1\x31\xEA\xB3\x5D" "\xE5\x15\x22\x1E\xE3\x19\x8A\x75\x5E\xF1\x95\x20\x0E\x60\xF8\xF2\xB5\x5F\xFD\xF5\x5F\x01" "\x36\x60\x05\x76\x60\x09\xB6\x60\x0D\xF6\x60\x11\x36\x61\x15\x76\x61\x19\xB6\x61\x01\x62" "\x26\x18\x82\x5F\x1D\x76\xA2\xB6\x91\xAA\x9C\x54\x50\x2B\xC3\x5B\x01\xA2\x50\xD6\x75\xA2" "\x74\xAA\x61\x0F\x09\x29\xA9\xC6\x56\x7F\xE2\x31\x08\xB5\xA2\x9C\xC6\x03\xF1\x35\x64\x7F" "\xAE\xBF\xDA\x61\x56\x09\x82\x14\x54\x6E\xA3\x76\x48\x61\x59\x16\xA1\x14\x41\x1D\x05\x82" "\x06\xAC\x89\x20\x24\x91\xC6\x2A\x91\x46\x49\x24\x20\x86\x76\x20\xD2\x8B\x43\x3E\xD2\x43" "\xDC\xCB\x20\xD4\xE0\x1B\xDE\xE1\x1B\x22\x87\x51\x01\xA2\x19\x42\x09\x10\x9C\xF6\x1D\xAA" "\xB2\xA6\x9C\x56\x16\x0E\xE0\x17\xA4\x16\x00\x9A\x81\xF1\xDC\xE1\x1D\xB8\x36\x54\x9E\x01" "\x1A\xBE\xE1\x44\x0F\xA2\x19\x6C\x0A\x6A\x4D\x01\x66\x97\x03\x39\xA1\x36\xAE\xBA\xE1\x1D" "\xC2\xF2\x4C\xCD\x32\x20\x12\x20\x18\xA0\x01\xC4\x8E\x76\x16\x44\x04\x21\xB8\x65\x16\x96" "\xD6\x20\x1A\x34\x20\x1A\x23\xC1\x82\xF1\xE8\x70\xC3\x26\x45\x51\x20\x28\x26\x9C\xAA\x86" "\x4F\x01\xA0\x50\xB2\x84\x72\xF9\x01\x51\x1D\x66\x75\xA0\xB5\x88\xDA\xEE\x48\xB3\x64\x49" "\x13\x08\x61\xBA\xAE\x6A\x32\x34\x6F\x41\xA5\xBA\xDC\xB1\xE1\xFA\x67\x25\x73\x4E\xC9\x7E" "\xE5\x14\x07\x02\x68\xF0\xD0\x47\x51\xF7\x71\x09\xC2\x52\x0E\x40\x11\xFC\x61\x03\x1A\xE0" "\x77\xED\x11\x20\xBA\xA8\xFA\x00\x22\x00\xB4\xF5\x59\xA9\x83\x36\x1A\xCD\x78\x00\xA0\x33" "\x84\xB1\xFB\xC0\x82\x00\xCC\x04\x1C\xFF\xC1\x23\x08\x40\x2D\x2D\x6C\x3A\xD6\xE5\x00\xD4" "\xB2\x1C\xEF\xB2\x27\x02\xA5\x35\x0A\xE0\x88\x72\xE8\x66\x03\x80\x41\xB0\x35\x20\x30\x46" "\x52\xBC\xA6\x1F\x2F\x85\x85\x82\xF3\x00\x4C\xC1\x73\x64\x57\x20\x7C\x50\x47\xBA\x28\x7D" "\x9F\xA4\x81\x1A\x2B\x21\x6A\x64\x0E\x1A\x62\x3A\xC4\x0E\x3A\xFD\xEF\x79\xC9\x17\x20\x34" "\x0E\x11\x6B\xC4\x42\x0E\x91\xB6\x34\x44\x3C\xC4\xC5\x4F\xCC\xA8\x1F\x8E\x0A\x11\xBC\x26" "\x64\x97\x88\x68\x5C\x91\xB8\xD4\x6C\x8D\x82\x13\xC9\x20\xE5\x7B\x42\x34\x46\x03\x62\x3B" "\xBE\x76\x7F\x35\x48\xD9\x6A\xC4\x1D\x36\x40\xCD\xF6\x81\x48\x01\x62\x2E\x0A\x06\x40\xBD" "\x4B\x58\xB2\xA1\xFD\xEE\x52\x4E\xD3\x81\x66\xBE\xA3\x36\x38\x58\x6A\x3A\x2D\x5C\xBC\x83" "\x11\x8A\xF0\x74\x7F\x18\x6E\x8E\xEF\x4F\x42\xA1\x32\x08\xAB\x0F\xEA\x65\x2F\xA4\x84\x37" "\x8B\x08\x42\xF8\x77\xBC\xDA\x45\x4B\x66\x01\xF0\xF2\x10\xE7\x54\x09\x82\x1D\x58\x20\x16" "\x34\x3C\x79\x2D\x8C\x21\x97\x8A\x23\xB8\x0D\x83\x78\x8A\x15\x82\xFC\x68\x2D\x5F\x58\x48" "\x84\x2F\x13\x94\x00\x60\x19\x70\x58\x20\x94\x60\x66\x4D\x4D\x2B\x51\x58\x43\x17\xC2\x0A" "\x82\x01\x95\x70\x4D\x8D\x71\xAE\x6E\x7C\xD8\xB7\x1E\x8E\x8C\x65\x24\xC5\x10\x19\x77\x19" "\xF9\xD3\xD0\xD8\xC8\x42\xD6\x33\x12\xEE\x4D\xF1\x16\x00\xC4\x83\x0A\xCE\xA8\x09\xD2\xA1" "\x3B\xF2\xA1\x0C\x83\x63\x32\x68\x25\x7D\xBB\x73\x94\x87\xF1\x21\x04\x40\x06\x17\xF2\xA0" "\xEA\x37\x83\x68\x4B\x58\x16\x19\x8E\x0D\x94\x74\xF6\xB8\x94\xAD\x11\x92\x29\xE9\x27\x01" "\xE0\x8E\x8D\xD8\x2D\xDD\x38\x21\x82\x23\x0D\x68\xE0\x1F\x0E\x60\x12\xF8\x21\x63\x3A\xD6" "\x34\x01\x20\x0E\x54\x13\x81\x88\xA8\x8A\x55\x16\x00\xD0\x01\x16\x0F\xEA\x6E\x02\x82\x95" "\x6B\x18\x8C\xEB\xE5\x83\xEC\x85\x87\xCD\xF8\x88\x51\xC3\x96\xCD\xB3\x72\x5F\x32\x54\x91" "\xF8\x20\xF4\x01\x18\x32\xC1\x47\x64\x00\x71\x54\xD2\x20\xE6\xC2\x0A\xB6\x41\x2B\x81\x82" "\x49\x68\x38\xDE\x9A\x95\x21\x8E\xE6\x52\x17\x22\x39\x5C\x0E\x00\x90\x0C\x1C\x55\x08\x43" "\x4E\x16\x00\x10\x70\xC4\x8A\x62\xA0\x47\x99\x62\x26\x49\x46\x2E\xF8\x96\xF1\x42\x3C\xEA" "\x98\x9C\x2B\x19\x00\xF4\x64\x45\xCC\x62\x29\xEE\x99\x4B\x97\x42\x94\xA7\x02\x06\x01\x80" "\x5C\x34\x68\x2E\xD0\xAE\x21\xC2\x14\xA1\x0F\x0A\x1F\x01\x43\x75\xA9\x97\x3C\xA8\x67\x5D" "\x93\xCB\xA3\xC9\xA5\x63\x67\x99\x97\x6B\xF9\x69\x48\x0E\x89\x5B\xC1\x4C\xDD\x79\xBC\x0E" "\x09\xC2\xD4\x66\xCE\x22\x7A\x20\x2A\x3A\xA3\x91\x71\x29\x66\xA1\x1D\x5E\x77\x20\x2E\xDA" "\x1D\x4C\xE1\x1B\xB2\x96\x78\xA0\x61\x16\x9A\x7A\x29\x12\xB2\x8C\x1B\x62\x89\xFF\x61\xFF" "\x92\xBA\x3C\x3A\x75\x29\x26\x79\x20\xE8\x34\x13\x54\x24\x5E\xE3\xA9\x9B\x69\xF9\x9B\xBD" "\x66\xCE\xBE\x61\x16\xBC\xB7\xAC\xB1\x29\xCF\x14\x82\x5E\x3A\x98\x92\x52\x8B\x4D\x1A\x63" "\x83\x01\x42\x3C\x76\x39\x06\xB5\x84\x07\x2A\x76\x20\x28\x28\x2B\xA8\x77\x58\x09\xAF\x3C" "\x2E\x16\x13\x98\x02\x04\x52\xD1\xB7\xD4\x40\xB6\xC8\x28\x21\x1C\xFB\x44\xB4\x18\x0F\xB7" "\x6B\x46\x1A\xCA\xC8\x1A\xE0\xE2\x28\x57\xFC\xE6\x62\xAF\x99\xD1\x85\x2F\x16\x26\x64\xE2" "\x21\xBC\x49\x62\x83\x0F\x62\x54\xE2\x62\x1A\xF9\xD8\x00\x98\x00\x24\x96\x90\x82\x97\x9C" "\xBC\xE4\x99\x11\xE2\x35\x02\x95\x60\x6D\x07\x29\x57\xAA\x1B\x82\xA1\x2F\x96\x42\x59\x0B" "\x36\xB7\x7F\x6E\xA5\x46\xD7\x1F\x5E\x35\x60\x8B\x82\x4F\x93\x3B\xF5\x20\x46\x01\x26\xB6" "\x9F\x94\xD5\x9F\x9E\x7B\xBA\xA9\xBB\xBA\xAD\xFB\xBA\xB1\x3B\xBB\xB5\x7B\xBB\xB9\xBB\xBB" "\xBD\x1B\xA5\x84\xEF\xBB\x33\xEA\xAF\x33\x62\xFA\xB6\xFA\x22\xC8\x1B\x22\xD2\xDB\xBA\x75" "\x9B\x21\xF6\xCD\x43\xDC\xA1\x35\x2F\xA2\xBD\xDD\xDA\xBB\xE9\x9B\xE2\xE4\xF4\x25\xEE\xDB" "\xAA\xED\x7B\xB8\x49\x0C\x27\x90\x62\xBF\x6F\x97\xBB\xF9\x41\x0D\x88\xC0\x6D\xE1\x36\x20" "\xB8\x82\x6C\xBB\xF6\x6B\xE1\xA4\x21\x78\x40\x72\xBE\x21\x13\xC2\x55\x6B\x43\xA4\x02\xF4" "\x41\x83\x36\xC0\x14\x24\xB0\x67\x7D\xEB\x0B\x4C\xC0\x1D\xBE\xA1\x6C\x0F\x22\x02\xA0\x16" "\x6A\xA1\xA1\xB0\xFF\x95\xFC\x98\x02\xE2\x14\xA8\x9B\x1A\x60\x77\x7B\xF7\x77\x2B\xE5\x20" "\x6E\xC8\x33\x12\x1C\xC2\x36\xD7\x20\x80\x26\x4B\x48\x76\x59\x9D\xEA\x36\x3B\xE5\xB8\xDB" "\x55\x7B\x01\x80\x7B\xC9\xF1\x28\xFF\xE1\x37\x36\xE0\x31\xC4\x45\x72\x3B\x85\x4F\x07\xC0" "\xC3\xE6\x47\x00\x62\x41\x3F\x7F\x94\x08\x9A\xF7\xBC\x4D\xED\x1F\x02\x2A\xB6\x97\xF5\x17" "\x82\x6F\x7A\x0D\x51\x2A\x02\x85\x72\xFB\xF5\x46\xF3\x5A\x18\x17\xB8\xC8\xE2\x70\x08\x4C" "\x61\x9A\x0E\x35\x13\x32\xC1\x14\xDA\x3A\x3C\xD6\x12\x43\x10\x91\x80\x6D\x88\xCD\xBB\x70" "\x8D\x93\x24\x81\x1D\xEB\x79\xFB\xB5\x87\x71\xA6\x89\xEA\xA6\x46\x34\xA8\x66\xDF\x11\xCC" "\x02\x80\x26\xA2\x19\x73\x64\x38\x20\xEA\x79\x20\xE6\xA2\xAA\x5B\x79\x3C\x3D\x6D\xB1\x71" "\xDB\xAC\xBD\x67\x0F\x7D\x30\x85\x8B\x4B\xC7\x83\xFC\xD3\xBB\x58\x18\x81\x24\x44\xBD\xAB" "\x65\x16\x39\x11\x77\x86\xD0\xF3\x75\xA6\x9D\xD1\x89\x2A\x9D\x96\xDF\xED\xC4\xA1\xB6\x0C" "\xEB\xB7\x90\x09\x82\x39\x88\x9C\x1F\x0E\x59\x00\xDD\x02\x6A\x61\x7D\x65\x3D\xDD\x68\x55" "\xD3\x8B\x25\x9A\x73\x55\xFD\xD3\xEB\xC6\x9A\x4D\x3D\x80\x5D\xB9\x5E\x6A\xC4\x1B\x9C\xDB" "\xB9\x04\xDC\xF5\x64\x1D\xB5\xC4\x54\x61\x08\x5D\xD9\xB4\x79\x21\xA8\x19\x20\xA0\x7D\xD6" "\x7F\x9C\xAA\xA6\x1D\x73\xBE\xC7\x7B\x15\xDD\x60\xB7\x5D\x20\x18\x04\x13\x1A\xC0\xB1\x45" "\xFD\xB4\x82\x72\x9F\xFF\xA1\x9F\xFF\xD9\x20\xEE\x7D\x21\x2A\x93\x0E\xFB\x61\xA0\xC3\x3D" "\x97\x8B\x7D\x5E\xDF\x3D\x20\x36\xCC\xA8\x6F\x6E\xD9\x9F\xC3\x32\x5E\x15\xA5\x2F\x64\x3A" "\xD6\xC7\x2C\x7A\x57\x3A\xB4\xA7\xA5\x8F\x6C\xD5\x0E\x40\xE2\xDD\xFD\xD8\x97\x05\x10\x32" "\x81\x07\x1A\xE0\xDB\xC7\x2B\x19\x0F\xD5\x14\xFE\xD8\xC2\xB0\xFA\x70\xB8\xFC\x86\x2E\xD0" "\x7C\xB2\x77\x29\xD0\xD6\xAB\xCD\xB9\x98\x66\x41\xB0\x0D\x56\xFC\xD6\x5B\x20\xF2\xB3\xDE" "\x19\x42\x0D\x7E\x67\x06\x01\x00\xB1\x5D\x67\xBD\xC3\x2A\x2B\xB2\xB7\xB1\xB5\x44\x3E\x85" "\x89\x98\xDA\x01\xC3\x43\x5B\x61\x07\xA0\x78\x88\x9C\x21\xFA\x11\x62\x75\xAF\xC2\xEF\xD1" "\xB5\x19\xC2\x9B\xAC\x5E\xEB\xAB\x1B\x72\xA4\xDA\x32\xF0\x5A\xBC\x19\x8D\xD4\xB9\xCD\xEC" "\x47\xAF\x5C\xC1\x5C\xED\xDD\xFE\xED\xE1\x3E\xEE\xE5\x7E\xEE\xE9\xBE\xEE\xED\xFE\xEE\xF1" "\x3E\xEF\xF5\x7E\xEF\xF9\xBE\xEF\xFD\xFE\xEF\x01\x3F\xF0\x05\x7F\xF0\x09\xBF\xF0\x0D\xFF" "\xF0\x11\x3F\xF1\x15\x7F\xF1\x19\xBF\xF1\x1D\xFF\xF1\x21\x3F\xF2\x25\x7F\xF2\x29\xBF\xF2" "\x2D\xFF\xF2\x31\x3F\xF3\x35\x7F\xF3\x39\xBF\xF3\x3D\xFF\xF3\x41\x3F\xF4\x45\x7F\xF4\x37" "\x4A\xF8\x68\x9B\xAB\x7A\x6F\x24\x20\xA6\xED\x1D\x8A\x7F\x4C\xD7\x6F\x4E\x53\x20\x1A\x23" "\x21\x83\x51\xAB\x02\x80\x34\x6C\x8B\x22\xAF\x06\x2A\xAA\x48\xD1\x0A\xE2\xD0\x68\xDA\x91" "\xAF\x85\xD4\xB3\x24\xA8\x01\x02\x76\xB2\xC4\x15\xC9\xEF\x2D\x78\xC0\x10\x65\xC1\x33\xB4" "\x9C\xB6\xB2\x82\xF9\x9D\x1F\xFA\xE3\x2D\xBF\xD3\xD8\xCD\xAB\x5A\x1B\x8C\x7F\xE7\xF7\x67" "\x01\x0B\x70\x29\x42\xB0\x31\x82\xEB\x88\x9A\x6F\x28\x69\xAC\x28\x15\x2C\x76\x93\x6C\x17" "\x84\x0C\x55\x03\x59\xF8\x6D\x3D\x86\xC1\xDF\x2D\x80\xC8\xF8\x6F\xE8\x1B\x50\xFE\x08\x33" "\x34\x28\x80\x28\x2B\x9C\x01\x08\x28\x30\x60\x03\x7F\xFF\xFC\x99\x82\xF6\xEF\x1F\xA6\x81" "\x0E\xF9\xFD\x7B\xF7\x6E\xE1\x3F\x80\x0E\x09\x1A\x44\xA8\xF0\x1F\xA9\x8B\x00\xCE\xFC\xEB" "\x77\xF1\x8C\xBF\x00\x0E\x41\xF2\x73\xA8\xE3\xA0\xC9\x8B\xFC\xE8\x78\x8C\xE9\x31\xDD\xBF" "\x19\x17\x0B\xF8\x13\x39\x50\xC9\xBF\x4B\x1E\x13\xFD\x5B\x24\xB0\x40\x3F\x7F\x09\x2E\x2E" "\x2B\x39\xF2\x1F\x08\x87\x5E\x6A\x5E\xD4\xA6\x73\x20\xC9\x96\x54\x95\xCA\x7C\x29\x33\x60" "\x82\x83\x2D\xB6\x0E\xD4\x1A\x10\xC4\xBE\x9E\x1E\xB5\x31\x14\x08\xA2\xDF\x3F\x16\x31\xC5" "\x02\x20\x6B\x36\xEA\xBF\x52\x6A\xD9\xBA\x3D\xB9\xF0\xCB\x49\xAC\x02\x41\xFE\x1B\x32\x10" "\x1F\x4B\x8F\x70\xC1\x7A\xA4\x52\x31\xA6\xA8\xC0\x83\xFF\x31\xF0\x38\x80\x9F\xD1\x80\x94" "\xFE\xFD\xF1\x28\xC7\xEF\x5F\x7F\x03\x1C\x7E\xC0\xEC\x30\x00\xBF\x6E\x23\x39\x07\xAC\xBA" "\xF5\xB0\x47\x9E\x55\x10\x0B\x3C\x1C\x40\x9F\x3F\x03\x0E\x4B\x2C\x1E\x18\xDA\xB4\x61\x98" "\x02\x67\xD7\x76\x08\xE2\x1F\x37\xD0\xFF\x78\x53\x5D\xD8\xCF\xEA\x47\xD4\x80\xA7\x0E\x59" "\x88\x3A\x20\x6B\xD8\x01\x27\xFB\x8B\xEC\x91\xC1\xBF\x94\x01\x57\xC6\x92\xF9\x34\x3C\xF7" "\xE5\x1E\x55\xF7\x65\x0E\x60\x40\x3F\xE4\x01\x35\x88\x4E\x7F\x5A\xFD\x43\xDF\x32\xE5\xFC" "\xFB\x60\x1D\x00\xEB\x38\x4C\x1D\x22\xF2\x9F\x43\xBD\x54\xE6\x92\x7D\x01\xF9\xD7\xD4\x40" "\x40\x29\x38\x10\x81\x47\x51\xD5\x0F\x18\xF1\xA5\xE6\x5C\x3F\x80\xFC\xF3\x1A\x00\xF9\xB8" "\xC3\xC8\x74\xFC\x1D\xB8\x1F\x00\x8D\x85\xE8\x50\x25\xFF\x30\x11\x50\x3E\xD9\x6D\x95\xCF" "\x3F\x11\x34\xA6\xE1\x69\x02\x45\x70\x40\x40\x5E\x4C\x87\x0E\x67\x5D\x40\x25\x9F\x8F\x6F" "\x95\xE8\xD0\x0C\x73\xC1\xC6\xDA\x24\x02\x0A\xB4\xCC\x54\x03\xF1\x58\x42\x6F\x0E\x1D\xD9" "\x60\x40\x4A\x7A\xD4\xE4\x49\xFD\x08\x90\x4D\x81\xCD\xA9\x77\x46\x3F\x07\xE4\x23\x12\x4F" "\x43\x50\xF1\x61\x75\xB0\xC1\xB7\xA4\x47\x38\xF9\x03\x80\x19\x44\xC6\xB4\xD2\x42\xDE\x9D" "\xF7\x4F\x05\x00\x84\xC6\x4E\x40\xAE\x4C\x07\x94\x06\x03\xED\xB2\x65\x67\xF4\xA1\x07\x24" "\x58\xEC\xFD\x03\x06\x7D\x4F\x0E\x74\xE2\x9F\x03\x29\x33\x1D\x48\x52\xC6\x16\xA2\xA3\x0E" "\x45\x4A\x28\x92\x15\xE2\xC9\xD1\xA0\x7D\x01\xC0\x13\x20\xEC\x88\x64\x86\x99\x41\x22\x46" "\x93\x4D\x60\xE1\xF7\x8D\x3F\x9E\x21\x86\x56\x8F\x9A\xFD\x87\x46\x61\x49\xD1\x37\x64\x1A" "\x03\xE9\x43\xE7\x55\x84\x7E\x58\x29\x62\x3B\x50\xF4\x4D\x26\x3C\xAC\x76\xE0\x70\x6A\x02" "\x90\xE9\x52\x94\x52\xA7\x6C\x48\x17\x39\xAB\x17\xA5\xAA\x29\xF3\x0F\x05\x15\x76\xA9\x94" "\x3E\x0B\xBD\x56\x68\x58\xA8\x6E\xA5\x98\x45\x88\xB9\x88\x22\x6C\xAD\x2C\xA4\x9D\x47\x2C" "\xFC\xF3\x67\xB6\xF9\x35\xAB\xE7\x4D\xFD\x9C\x0B\x9F\x4F\xF3\xF1\x9B\x15\xB9\x03\x6D\x10" "\x0C\x45\x21\x7D\x66\xD8\x1F\x01\x10\xD0\x80\x1A\x0B\xA5\xE8\xD0\x2B\xFF\xD8\x66\xAD\xC1" "\x08\x2B\xCC\xF0\x45\x0F\x47\x9C\xDC\xB5\x4A\x51\x90\x9B\xB8\x5C\x02\xB0\xC4\xB4\x20\x1B" "\x28\xE2\x7A\x45\xB9\x0B\x56\xC7\xBF\xC0\x06\x01\x45\xE1\xC5\x04\xDF\x6B\xFC\xD4\xA1\xCF" "\x1C\x1B\x16\x77\x16\x56\xB6\xE6\xF5\xE3\xA7\xFE\x8A\x48\x80\x09\xDD\xFC\xD3\x4E\x4C\x65" "\x0D\xFC\x4F\x90\x4A\x6A\x0A\x2D\x00\x48\x0F\xBC\xB4\x79\x12\xFF\x1A\x50\x63\x4E\x7E\x8C" "\x1E\x08\x0D\x70\xCB\xE8\x7E\x24\x8A\xB8\xCF\xAE\x88\x65\x6B\xC5\x36\xF4\x7A\x44\x1A\x1A" "\x11\xBC\xD8\x4A\x71\x67\x02\xC0\x73\x40\xDA\x7C\x48\x92\x47\x38\x2E\x2A\xAC\xC9\x00\xD0" "\xF4\xE8\x43\xEE\xCC\x12\xCC\x2C\x07\xC5\x54\xAD\xC6\x86\x01\x2E\x78\x1D\x11\x14\x2E\xE9" "\xA6\x24\x1F\xE0\x8F\xD1\xA6\x76\x0B\xEC\xA2\x70\xC7\x14\x1A\xB3\x60\x61\x2E\x10\x6E\x46" "\xC7\x70\x5C\x4C\xA4\xA5\x51\x85\x48\x53\xF4\xD3\xC0\x3E\xA8\xB2\xED\x53\xE4\x2C\xD7\xC9" "\xB8\x43\xA2\x04\x1B\xED\xDE\x00\xAC\xD4\xF0\x43\x63\x03\x70\xA2\x8C\x90\x62\x65\x15\x48" "\xFA\xB9\xC4\xFB\x56\x86\xFF\xF5\x78\xA1\x01\xCE\x50\x66\xE5\xFD\xD6\x27\xA2\xAA\x26\x77" "\x1E\x10\x4D\x79\x65\xF3\xCF\x0E\x31\x61\xF3\x0C\x30\x00\x75\x5C\xC7\x3F\x4E\xC6\x94\xCE" "\xE9\x8E\x79\x64\x2B\xF9\x03\x61\x53\x3B\x88\xB7\x77\xEC\x87\xD7\x2E\xFB\x2A\x90\xAD\x82" "\x05\xD0\x8F\x6F\xEA\x9C\x0A\xDB\xFD\x17\xE1\xC3\x39\x7E\x21\x4D\x3B\x00\x21\x40\xCB\x79" "\x0D\x31\x8A\x81\x9D\x88\xAA\x17\x9D\x9C\x75\x6A\x73\x00\xE8\xC5\x5E\x02\xF2\xAD\x78\xC9" "\xC4\x56\x2D\x60\x46\xB0\xA2\xD3\x91\x81\x44\x4E\x82\x7A\x33\x19\x50\x7A\x36\x2E\x48\xB5" "\xE5\x22\x1D\x33\xDA\xFB\xE0\x75\xAE\xE8\x21\x66\x85\x0E\x71\x21\xF4\x3E\x22\x9D\xE7\xF9" "\x6C\x84\x60\x21\x8A\xA0\xAC\x53\xBD\x6F\xF9\x0D\x00\xBB\xF8\x07\x5F\x96\x62\xA7\x80\x0C" "\xB1\x76\x09\x30\x88\xA7\x64\x52\x16\x30\x08\x44\x01\xDC\x20\x22\xE7\xFE\x15\x10\xF5\x34" "\xE1\x20\x19\x3B\xA1\x40\x56\x90\x1B\x87\x64\xAF\x14\x04\x10\x5B\x04\xF0\x62\x28\xD8\x64" "\xAF\x21\x01\xD9\x80\x19\x73\xF8\xAD\x03\xD6\x50\x87\x5B\x01\xCC\x37\x24\x62\xC7\x77\x4C" "\xED\x8C\x31\xC1\x0F\x03\x03\xE2\x32\x58\x09\x69\x64\x00\x50\x0C\x0B\x65\x42\x41\x0C\xCA" "\x84\x58\x07\x31\x85\xC0\x8A\x86\x98\xEA\xC1\xE7\x1D\xD0\x98\x85\x29\xDC\xB1\x10\xC1\x24" "\x10\x00\x84\x91\xDD\x40\x0A\x92\xB4\xB4\xE8\x11\x2C\x11\xC8\x48\x42\x16\x62\x97\x38\xF2" "\x04\x8E\x39\x0C\xC8\x3E\xFC\x71\x47\x89\xE4\x31\x79\x9F\x54\x4E\xDE\x58\x69\xBC\x8B\xD0" "\x26\x65\x01\x39\x51\x11\x07\xC2\x36\x06\xB2\x0D\x66\x32\x09\xCD\x0B\x63\x52\x01\x60\x50" "\xC4\x1F\x50\x44\x8C\xD8\x54\xC6\x96\x81\x79\x63\x03\x4E\xBC\xA5\xC8\x6E\x19\x90\x03\x0C" "\x6E\x21\xEF\x68\xC2\x56\x9A\x69\x1D\x6C\x26\x93\x9B\xE7\x99\x8E\xF9\x70\x58\xB5\x8B\x40" "\x6D\x60\xB1\xBC\x1D\x3B\xDB\xE9\x4E\x99\x08\xE0\x00\x04\x78\x67\x4C\x04\x40\x80\x7B\xD2" "\xD3\x23\x14\xB4\x26\x3D\xE3\x69\xA3\x7C\x02\x34\xA0\x02\x1D\x28\x41\x0B\xFA\xCE\x8E\xFD" "\xE3\x1B\xA6\x78\x86\x41\x1B\xEA\xD0\x87\x42\x34\xA2\x12\xBD\x88\x09\xDA\x71\xC3\x89\x62" "\x34\xA3\x1A\xDD\x28\x47\x05\x42\x80\x03\x08\xA0\xA3\x22\x1D\x29\x49\x4B\x6A\xD2\x93\xA2" "\x34\xA5\x2A\x5D\x29\x4B\x5B\xEA\xD2\x97\xC2\x34\xA6\x32\x9D\x29\x4D\x6B\x6A\xD3\x9B\xE2" "\x34\xA7\x3A\xDD\x29\x4F\x7B\xEA\xD3\x9F\x02\x35\xA8\x42\x1D\xEA\x46\xED\x49\x80\x90\xCE" "\xF4\x9E\x47\x25\x6A\x41\x3F\x46\xC1\x55\xA1\x73\x96\xEB\x64\xE5\x27\xF9\xF9\x31\x92\x5D" "\x84\x07\xDF\x48\x1A\x3F\x9F\x26\xD5\x45\xA5\x93\x22\xEB\x04\x8C\x74\x82\x21\xCE\xAD\x58" "\xE1\x99\x2F\x33\xA2\x74\xA0\x71\xD6\xAD\x44\xA7\x90\x40\x15\x97\x25\x9A\xE8\x11\x7D\xBC" "\x72\x22\x1F\xC2\xEB\x44\x22\xF2\x0F\xAB\x4A\xEA\x43\x67\xFB\x87\x3B\x4C\x31\x0B\x68\xF8" "\xA3\x97\x0F\x89\xC8\x2B\xA7\xCA\x1F\xC6\xDE\x71\xAC\x90\x65\x62\x3F\x20\x74\x91\x00\xAC" "\x63\x21\x0A\x3D\xAC\x3F\x20\x98\x3C\x3B\xAE\x15\x2C\x17\x54\xAC\x4F\x0B\x65\x2B\xF7\xC0" "\xE6\xAA\x5C\x8C\xC9\x55\xAF\xDA\x18\x77\x48\xB3\x48\x56\x5C\xED\x1C\xFD\x12\x81\x66\x08" "\xD2\x21\xAE\xF8\xC7\x33\xB8\x06\x96\x42\x55\xA0\x2C\xBA\xF3\x88\xC8\x66\xC1\x0F\x11\xE6" "\x14\x3D\x2B\x41\x2E\x6B\xDD\xD7\xB9\xD6\xA2\x86\x6D\xCC\x85\xA1\x6C\x53\x8B\x1A\x45\xC0" "\x29\x20\x1D\x9B\x6E\xD7\x04\xC2\x80\xCE\x6E\x25\x1D\x6D\xF2\xCF\xF6\xE6\xAA\x94\x0A\x1C" "\xC4\xB2\xFB\x51\xAD\x1C\x57\xF9\xB1\xFF\xED\xA7\x7A\xB4\x95\xC9\x55\xF5\xC1\x2C\xF8\x22" "\xE6\x63\xFB\xF0\xAC\x43\x32\xE0\xA9\xC8\x15\x93\xA7\x76\x2B\x00\x44\x9C\x96\x5F\xE7\xFE" "\x0B\xBA\xEA\x41\xDE\x23\x67\xDB\xDE\x71\xD2\xE7\x52\xC0\xAB\xA5\xCF\x00\x2C\x93\x00\x11" "\x2F\x52\x5B\x14\xF0\x97\xEE\x81\xBE\xBD\xB1\xD7\x76\xF4\x6D\xD3\x45\xBA\x80\x1A\x06\x73" "\xAE\xAB\x86\x51\xF1\x39\x07\xF2\x14\x4A\xA1\xB8\xB9\x03\x09\x00\x6E\x49\x3B\x90\x30\x09" "\x44\x64\xBF\x13\xF0\xC0\x0C\x7C\x60\x0A\x3F\xF7\x1F\x80\xA8\x03\x91\x89\xAC\x86\x60\x9C" "\xD8\x2F\x3C\x30\x45\x26\x32\x61\x8A\xB7\x3C\x43\x0D\x45\xAE\x03\x0D\xB2\xF2\x0D\x46\x34" "\xD9\xC9\x98\x74\xEF\xE3\x62\x5C\x27\x26\x67\x62\x16\x06\x09\xB0\x40\xE0\x23\x4C\xEE\x90" "\x39\xB9\xEA\x64\x67\x88\xDF\x47\xDF\x59\x5E\x74\xC2\x02\xD9\x43\x32\xC1\xFA\x49\x45\x38" "\xF1\xCE\x10\xBE\x08\x28\xBA\xEC\xBE\xE4\x7C\xD2\x1F\x06\xC6\xCF\x96\x35\x09\xC8\x9E\x82" "\xC4\x34\xEC\x12\xA6\x88\xDA\xFC\x5C\x7F\xB4\x60\x03\x92\x96\x74\x05\x2E\x91\x64\xAB\x24" "\xEC\x00\x8A\x30\x13\x26\x2A\x30\xE9\xAD\x65\x65\x11\x07\x68\x00\xA9\x1B\x30\xCF\x38\x02" "\xE0\xC5\x98\xFA\x73\x67\x36\x50\xEA\x0A\x4C\xE8\x1F\xBE\x75\x48\x52\x0A\x16\x90\x00\xF9" "\xD8\xA6\x24\xB1\x4D\x00\xCA\x52\x68\xEB\x38\x3A\xC1\x24\x76\x08\xE5\x68\x1D\xD8\xCB\xB1" "\x78\x77\xD6\x6D\x9A\xB1\x29\x7C\x95\x8B\x10\x8B\xD1\x02\x29\x4B\x1D\xC0\x60\x6D\x2B\x64" "\x36\xD9\x34\x45\x0F\x6E\x82\x23\xA2\x3E\x20\xB8\xB6\x08\x1C\x08\xED\x36\x8C\xD5\xF9\x26" "\x6B\xD9\xD4\xF2\xC7\xAC\xAD\xE6\xED\x1F\xBB\x84\xBF\x00\x60\x1B\x9C\xA5\xAD\xD3\x42\x01" "\x25\xCD\x32\xD1\x12\x90\x85\x3D\x6E\x81\xF0\xA8\x44\xAA\x95\xEF\x83\xE3\xC8\x9E\xFA\x0D" "\x52\x69\xC0\x46\xCD\x00\xBE\xE8\xB9\xBA\x6C\xC0\x04\x12\x07\x01\x0D\xDA\xF3\x53\x71\xB9" "\xC8\xC6\x01\xE1\xA4\x40\x5C\x26\xD7\x4C\xBA\x17\x35\x21\x44\xB5\x9B\xAB\x0B\xEF\x81\x2C" "\xE3\x1F\xF2\x73\x48\x08\x9D\xDD\xDD\x8E\x83\x57\x2F\x50\x15\x08\xBF\x4B\xCB\x19\xF8\xBC" "\xE8\x22\x5D\xF1\x06\x27\x23\x50\x16\x8D\xA3\xBB\xC5\x3F\x1B\x08\xBB\xBC\xD1\x6E\x34\xF4" "\xCF\x87\x0E\x2E\x54\x04\x32\x2B\xC1\x50\xFC\x83\xE7\x27\x27\xC8\xB7\x86\xBB\x4B\x44\x02" "\x8A\x45\x88\x46\x0D\x7E\x10\x7E\x80\x0B\xBE\x63\x16\x5B\x75\xB8\x43\xF8\x7A\x90\x77\xF8" "\x03\xB0\xFF\x16\xC8\x00\x2E\x08\x8D\x30\x6F\x35\xE9\xB0\x69\x65\x5E\x25\x2B\x91\x3A\x4A" "\x47\xBD\x33\x4E\xD7\x66\x83\x81\xC7\xA5\xDC\x91\x22\x64\xC6\xD5\xB3\x6C\x4E\x1F\xB4\xEC" "\x38\x20\x4D\x18\x3B\x61\xAD\xD0\xCD\x4F\x06\x49\xC1\x31\x01\x83\x5A\x23\x22\x8B\xA3\x69" "\x7B\xDA\x5F\xD5\x4B\x32\xDD\x8A\x98\x26\x58\x52\x9D\x5D\x4A\x9A\x3F\xBE\xB1\x4C\xA4\x4C" "\x15\x24\x26\x60\xAA\x75\x02\x20\x00\xA4\x8E\xF4\xA3\x04\x70\x39\x4A\x65\x0F\x7B\xD6\xE3" "\x3E\xF7\xBA\xDF\x3D\xEF\x7B\xEF\xFB\xDF\x03\x3F\xF8\xC2\x1F\x3E\xF1\x8B\x6F\xFC\xE3\x23" "\x3F\xF9\xCA\x5F\x3E\xF3\x9B\xEF\xFC\xE7\x43\x3F\xFA\xD2\x9F\x3E\xF5\xAB\x6F\xFD\xEB\x63" "\x3F\xFB\xDA\xDF\x3E\xF7\xBB\xEF\xFD\xEF\x83\x3F\xFC\xE2\x1F\x3F\xF9\xCB\x6F\xFE\xF3\xA3" "\x3F\xFD\xEA\x5F\x3F\xFB\xDB\xEF\xFE\xF7\xC3\xFF\xF8"; #undef DD_ALIGNED_BUFFER static const FontCharSet s_fontMonoid18CharSet = { /* bitmap = */ s_fontMonoid18Bitmap, /* bitmapWidth = */ 256, /* bitmapHeight = */ 256, /* bitmapColorChannels = */ 1, /* bitmapDecompressSize = */ 65536, /* charBaseHeight = */ 20, /* charWidth = */ 17, /* charHeight = */ 30, /* charCount = */ 96, { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 150 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 60 }, { 17, 60 }, { 68, 0 }, { 153, 0 }, { 119, 0 }, { 34, 0 }, { 204, 30 }, { 119, 30 }, { 102, 30 }, { 0, 0 }, { 102, 0 }, { 170, 30 }, { 136, 0 }, { 187, 30 }, { 221, 0 }, { 34, 60 }, { 187, 60 }, { 170, 60 }, { 153, 60 }, { 136, 60 }, { 119, 60 }, { 102, 60 }, { 85, 60 }, { 68, 60 }, { 51, 60 }, { 136, 30 }, { 153, 30 }, { 17, 30 }, { 85, 0 }, { 0, 30 }, { 221, 30 }, { 204, 0 }, { 170, 210 }, { 153, 210 }, { 136, 210 }, { 119, 210 }, { 102, 210 }, { 85, 210 }, { 68, 210 }, { 51, 210 }, { 34, 210 }, { 17, 210 }, { 0, 210 }, { 238, 180 }, { 221, 180 }, { 204, 180 }, { 187, 180 }, { 170, 180 }, { 153, 180 }, { 136, 180 }, { 119, 180 }, { 102, 180 }, { 85, 180 }, { 68, 180 }, { 51, 180 }, { 34, 180 }, { 17, 180 }, { 0, 180 }, { 85, 30 }, { 187, 0 }, { 68, 30 }, { 170, 0 }, { 51, 0 }, { 238, 30 }, { 119, 120 }, { 102, 120 }, { 85, 120 }, { 68, 120 }, { 51, 120 }, { 34, 120 }, { 17, 120 }, { 0, 120 }, { 238, 90 }, { 221, 90 }, { 204, 90 }, { 187, 90 }, { 170, 90 }, { 153, 90 }, { 136, 90 }, { 119, 90 }, { 102, 90 }, { 85, 90 }, { 68, 90 }, { 51, 90 }, { 34, 90 }, { 17, 90 }, { 0, 90 }, { 238, 60 }, { 221, 60 }, { 204, 60 }, { 51, 30 }, { 238, 0 }, { 34, 30 }, { 17, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } }; // ======================================================== // LZW decompression helpers for the font bitmap: // ======================================================== // These must match the font-tool encoder! static const int LzwNil = -1; static const int LzwMaxDictBits = 12; static const int LzwStartBits = 9; static const int LzwFirstCode = (1 << (LzwStartBits - 1)); // 256 static const int LzwMaxDictEntries = (1 << LzwMaxDictBits); // 4096 struct LzwDictionary { // Dictionary entries 0-255 are always reserved to the byte/ASCII range. struct Entry { int code; int value; }; int size; Entry entries[LzwMaxDictEntries]; LzwDictionary(); int findIndex(int code, int value) const; bool add(int code, int value); bool flush(int & codeBitsWidth); }; struct LzwBitStreamReader { const std::uint8_t * stream; // Pointer to the external bit stream. Not owned by the reader. int sizeInBytes; // Size of the stream in bytes. Might include padding. int sizeInBits; // Size of the stream in bits, padding not include. int currBytePos; // Current byte being read in the stream. int nextBitPos; // Bit position within the current byte to access next. 0 to 7. int numBitsRead; // Total bits read from the stream so far. Never includes byte-rounding. LzwBitStreamReader(const std::uint8_t * bitStream, int byteCount, int bitCount); bool readNextBit(int & outBit); int readBits(int bitCount); }; // ======================================================== // LzwDictionary: // ======================================================== LzwDictionary::LzwDictionary() { // First 256 dictionary entries are reserved to the byte/ASCII // range. Additional entries follow for the character sequences // found in the input. Up to 4096 - 256 (LzwMaxDictEntries - LzwFirstCode). size = LzwFirstCode; for (int i = 0; i < size; ++i) { entries[i].code = LzwNil; entries[i].value = i; } } int LzwDictionary::findIndex(const int code, const int value) const { if (code == LzwNil) { return value; } for (int i = 0; i < size; ++i) { if (entries[i].code == code && entries[i].value == value) { return i; } } return LzwNil; } bool LzwDictionary::add(const int code, const int value) { if (size == LzwMaxDictEntries) { return false; } entries[size].code = code; entries[size].value = value; ++size; return true; } bool LzwDictionary::flush(int & codeBitsWidth) { if (size == (1 << codeBitsWidth)) { ++codeBitsWidth; if (codeBitsWidth > LzwMaxDictBits) { // Clear the dictionary (except the first 256 byte entries). codeBitsWidth = LzwStartBits; size = LzwFirstCode; return true; } } return false; } // ======================================================== // LzwBitStreamReader: // ======================================================== LzwBitStreamReader::LzwBitStreamReader(const std::uint8_t * bitStream, const int byteCount, const int bitCount) : stream(bitStream) , sizeInBytes(byteCount) , sizeInBits(bitCount) , currBytePos(0) , nextBitPos(0) , numBitsRead(0) { } bool LzwBitStreamReader::readNextBit(int & outBit) { if (numBitsRead >= sizeInBits) { return false; // We are done. } const int mask = 1 << nextBitPos; outBit = !!(stream[currBytePos] & mask); ++numBitsRead; if (++nextBitPos == 8) { nextBitPos = 0; ++currBytePos; } return true; } int LzwBitStreamReader::readBits(const int bitCount) { int num = 0; for (int b = 0; b < bitCount; ++b) { int bit; if (!readNextBit(bit)) { break; } const int mask = 1 << b; num = (num & ~mask) | (-bit & mask); } return num; } // ======================================================== // lzwDecompress() and helpers: // ======================================================== static bool lzwOutputByte(int code, std::uint8_t *& output, int outputSizeBytes, int & bytesDecodedSoFar) { if (code < 0 || code >= 256) { return false; } if (bytesDecodedSoFar >= outputSizeBytes) { return false; } *output++ = static_cast(code); ++bytesDecodedSoFar; return true; } static bool lzwOutputSequence(const LzwDictionary & dict, int code, std::uint8_t *& output, int outputSizeBytes, int & bytesDecodedSoFar, int & firstByte) { // A sequence is stored backwards, so we have to write // it to a temp then output the buffer in reverse. int i = 0; std::uint8_t sequence[LzwMaxDictEntries]; do { sequence[i++] = dict.entries[code].value & 0xFF; code = dict.entries[code].code; } while (code >= 0); firstByte = sequence[--i]; for (; i >= 0; --i) { if (!lzwOutputByte(sequence[i], output, outputSizeBytes, bytesDecodedSoFar)) { return false; } } return true; } static int lzwDecompress(const void * compressedData, int compressedSizeBytes, int compressedSizeBits, void * uncompressedData, int uncompressedSizeBytes) { if (compressedData == nullptr || uncompressedData == nullptr) { return 0; } if (compressedSizeBytes <= 0 || compressedSizeBits <= 0 || uncompressedSizeBytes <= 0) { return 0; } int code = LzwNil; int prevCode = LzwNil; int codeBitsWidth = LzwStartBits; int firstByte = 0; int bytesDecoded = 0; const std::uint8_t * compressedPtr = reinterpret_cast(compressedData); std::uint8_t * uncompressedPtr = reinterpret_cast(uncompressedData); // We'll reconstruct the dictionary based on the bit stream codes. LzwBitStreamReader bitStream(compressedPtr, compressedSizeBytes, compressedSizeBits); LzwDictionary dictionary; // We check to avoid an overflow of the user buffer. // If the buffer is smaller than the decompressed size, we // break the loop and return the current decompression count. while (bitStream.numBitsRead < bitStream.sizeInBits) { if (codeBitsWidth > LzwMaxDictBits) { break; } code = bitStream.readBits(codeBitsWidth); if (prevCode == LzwNil) { if (!lzwOutputByte(code, uncompressedPtr, uncompressedSizeBytes, bytesDecoded)) { break; } firstByte = code; prevCode = code; continue; } if (code >= dictionary.size) { if (!lzwOutputSequence(dictionary, prevCode, uncompressedPtr, uncompressedSizeBytes, bytesDecoded, firstByte)) { break; } if (!lzwOutputByte(firstByte, uncompressedPtr, uncompressedSizeBytes, bytesDecoded)) { break; } } else { if (!lzwOutputSequence(dictionary, code, uncompressedPtr, uncompressedSizeBytes, bytesDecoded, firstByte)) { break; } } if (!dictionary.add(prevCode, firstByte)) { break; } if (dictionary.flush(codeBitsWidth)) { prevCode = LzwNil; } else { prevCode = code; } } return bytesDecoded; } // ======================================================== // Built-in font glyph bitmap decompression: // ======================================================== // If you decide to change the font, these are the only things that // need to be updated. The s_font* variables are never referenced // directly in the code, these functions are used instead. static inline const std::uint8_t * getRawFontBitmapData() { return s_fontMonoid18Bitmap; } static inline const FontCharSet & getFontCharSet() { return s_fontMonoid18CharSet; } static std::uint8_t * decompressFontBitmap() { const std::uint32_t * compressedData = reinterpret_cast(getRawFontBitmapData()); // First two uint32s are the compressed size in // bytes followed by the compressed size in bits. const int compressedSizeBytes = *compressedData++; const int compressedSizeBits = *compressedData++; // Allocate the decompression buffer: const int uncompressedSizeBytes = getFontCharSet().bitmapDecompressSize; std::uint8_t * uncompressedData = static_cast(DD_MALLOC(uncompressedSizeBytes)); // Out of memory? Font rendering will be disable. if (uncompressedData == nullptr) { return nullptr; } // Decode the bitmap pixels (stored with an LZW-flavor of compression): const int bytesDecoded = lzwDecompress(compressedData, compressedSizeBytes, compressedSizeBits, uncompressedData, uncompressedSizeBytes); // Unexpected decompression size? Probably a data mismatch in the font-tool. if (bytesDecoded != uncompressedSizeBytes) { DD_MFREE(uncompressedData); return nullptr; } // Must later free with DD_MFREE(). return uncompressedData; } // ======================================================== // Internal Debug Draw queues and helper types/functions: // ======================================================== struct DebugString { std::int64_t expiryDateMillis; ddVec3 color; float posX; float posY; float scaling; ddStr text; bool centered; }; struct DebugPoint { std::int64_t expiryDateMillis; ddVec3 position; ddVec3 color; float size; bool depthEnabled; }; struct DebugLine { std::int64_t expiryDateMillis; ddVec3 posFrom; ddVec3 posTo; ddVec3 color; bool depthEnabled; }; struct InternalContext DD_EXPLICIT_CONTEXT_ONLY(: public OpaqueContextType) { int vertexBufferUsed; int debugStringsCount; int debugPointsCount; int debugLinesCount; std::int64_t currentTimeMillis; // Latest time value (in milliseconds) from dd::flush(). GlyphTextureHandle glyphTexHandle; // Our built-in glyph bitmap. If kept null, no text is rendered. RenderInterface * renderInterface; // Ref to the external renderer. Can be null for a no-op debug draw. DrawVertex vertexBuffer[DEBUG_DRAW_VERTEX_BUFFER_SIZE]; // Vertex buffer we use to expand the lines/points before calling on RenderInterface. DebugString debugStrings[DEBUG_DRAW_MAX_STRINGS]; // Debug strings queue (2D screen-space strings + 3D projected labels). DebugPoint debugPoints[DEBUG_DRAW_MAX_POINTS]; // 3D debug points queue. DebugLine debugLines[DEBUG_DRAW_MAX_LINES]; // 3D debug lines queue. InternalContext(RenderInterface * renderer) : vertexBufferUsed(0) , debugStringsCount(0) , debugPointsCount(0) , debugLinesCount(0) , currentTimeMillis(0) , glyphTexHandle(nullptr) , renderInterface(renderer) { } }; // ======================================================== // Library context mode selection: // ======================================================== #if (defined(DEBUG_DRAW_PER_THREAD_CONTEXT) && defined(DEBUG_DRAW_EXPLICIT_CONTEXT)) #error "DEBUG_DRAW_PER_THREAD_CONTEXT and DEBUG_DRAW_EXPLICIT_CONTEXT are mutually exclusive!" #endif // DEBUG_DRAW_PER_THREAD_CONTEXT && DEBUG_DRAW_EXPLICIT_CONTEXT #if defined(DEBUG_DRAW_EXPLICIT_CONTEXT) // // Explicit context passed as argument // #define DD_CONTEXT static_cast(ctx) #elif defined(DEBUG_DRAW_PER_THREAD_CONTEXT) // // Per-thread global context (MT safe) // #if defined(__GNUC__) || defined(__clang__) // GCC/Clang #define DD_THREAD_LOCAL static __thread #elif defined(_MSC_VER) // Visual Studio #define DD_THREAD_LOCAL static __declspec(thread) #else // Try C++11 thread_local #if DEBUG_DRAW_CXX11_SUPPORTED #define DD_THREAD_LOCAL static thread_local #else // !DEBUG_DRAW_CXX11_SUPPORTED #error "Unsupported compiler - unknown TLS model" #endif // DEBUG_DRAW_CXX11_SUPPORTED #endif // TLS model DD_THREAD_LOCAL InternalContext * s_threadContext = nullptr; #define DD_CONTEXT s_threadContext #undef DD_THREAD_LOCAL #else // Debug Draw context selection // // Global static context (single threaded operation) // static InternalContext * s_globalContext = nullptr; #define DD_CONTEXT s_globalContext #endif // Debug Draw context selection // ======================================================== #if DEBUG_DRAW_USE_STD_MATH static inline float floatAbs(float x) { return fabsf(x); } static inline float floatSin(float radians) { return sinf(radians); } static inline float floatCos(float radians) { return cosf(radians); } static inline float floatInvSqrt(float x) { return (1.0f / sqrtf(x)); } #else // !DEBUG_DRAW_USE_STD_MATH // ======================================================== // Fast approximations of math functions used by Debug Draw // ======================================================== union Float2UInt { float asFloat; std::uint32_t asUInt; }; static inline float floatRound(float x) { // Probably slower than std::floor(), also depends of FPU settings, // but we only need this for that special sin/cos() case anyways... const int i = static_cast(x); return (x >= 0.0f) ? static_cast(i) : static_cast(i - 1); } static inline float floatAbs(float x) { // Mask-off the sign bit Float2UInt i; i.asFloat = x; i.asUInt &= 0x7FFFFFFF; return i.asFloat; } static inline float floatInvSqrt(float x) { // Modified version of the emblematic Q_rsqrt() from Quake 3. // See: http://en.wikipedia.org/wiki/Fast_inverse_square_root Float2UInt i; float y, r; y = x * 0.5f; i.asFloat = x; i.asUInt = 0x5F3759DF - (i.asUInt >> 1); r = i.asFloat; r = r * (1.5f - (r * r * y)); return r; } static inline float floatSin(float radians) { static const float A = -2.39e-08; static const float B = 2.7526e-06; static const float C = 1.98409e-04; static const float D = 8.3333315e-03; static const float E = 1.666666664e-01; if (radians < 0.0f || radians >= TAU) { radians -= floatRound(radians / TAU) * TAU; } if (radians < PI) { if (radians > HalfPI) { radians = PI - radians; } } else { radians = (radians > (PI + HalfPI)) ? (radians - TAU) : (PI - radians); } const float s = radians * radians; return radians * (((((A * s + B) * s - C) * s + D) * s - E) * s + 1.0f); } static inline float floatCos(float radians) { static const float A = -2.605e-07; static const float B = 2.47609e-05; static const float C = 1.3888397e-03; static const float D = 4.16666418e-02; static const float E = 4.999999963e-01; if (radians < 0.0f || radians >= TAU) { radians -= floatRound(radians / TAU) * TAU; } float d; if (radians < PI) { if (radians > HalfPI) { radians = PI - radians; d = -1.0f; } else { d = 1.0f; } } else { if (radians > (PI + HalfPI)) { radians = radians - TAU; d = 1.0f; } else { radians = PI - radians; d = -1.0f; } } const float s = radians * radians; return d * (((((A * s + B) * s - C) * s + D) * s - E) * s + 1.0f); } #endif // DEBUG_DRAW_USE_STD_MATH // ======================================================== // ddVec3 helpers: // ======================================================== enum VecElements { X, Y, Z, W }; static inline void vecSet(ddVec3_Out dest, const float x, const float y, const float z) { dest[X] = x; dest[Y] = y; dest[Z] = z; } static inline void vecCopy(ddVec3_Out dest, ddVec3_In src) { dest[X] = src[X]; dest[Y] = src[Y]; dest[Z] = src[Z]; } static inline void vecAdd(ddVec3_Out result, ddVec3_In a, ddVec3_In b) { result[X] = a[X] + b[X]; result[Y] = a[Y] + b[Y]; result[Z] = a[Z] + b[Z]; } static inline void vecSub(ddVec3_Out result, ddVec3_In a, ddVec3_In b) { result[X] = a[X] - b[X]; result[Y] = a[Y] - b[Y]; result[Z] = a[Z] - b[Z]; } static inline void vecScale(ddVec3_Out result, ddVec3_In v, const float s) { result[X] = v[X] * s; result[Y] = v[Y] * s; result[Z] = v[Z] * s; } static inline void vecNormalize(ddVec3_Out result, ddVec3_In v) { const float lenSqr = v[X] * v[X] + v[Y] * v[Y] + v[Z] * v[Z]; const float invLen = floatInvSqrt(lenSqr); result[X] = v[X] * invLen; result[Y] = v[Y] * invLen; result[Z] = v[Z] * invLen; } static inline void vecCross(ddVec3_Out result, ddVec3_In a, ddVec3_In b) { result[X] = a[Y] * b[Z] - a[Z] * b[Y]; result[Y] = a[Z] * b[X] - a[X] * b[Z]; result[Z] = a[X] * b[Y] - a[Y] * b[X]; } static inline void vecOrthogonalBasis(ddVec3_Out left, ddVec3_Out up, ddVec3_In v) { // Produces two orthogonal vectors for normalized vector v. float lenSqr, invLen; if (floatAbs(v[Z]) > 0.7f) { lenSqr = v[Y] * v[Y] + v[Z] * v[Z]; invLen = floatInvSqrt(lenSqr); up[X] = 0.0f; up[Y] = v[Z] * invLen; up[Z] = -v[Y] * invLen; left[X] = lenSqr * invLen; left[Y] = -v[X] * up[Z]; left[Z] = v[X] * up[Y]; } else { lenSqr = v[X] * v[X] + v[Y] * v[Y]; invLen = floatInvSqrt(lenSqr); left[X] = -v[Y] * invLen; left[Y] = v[X] * invLen; left[Z] = 0.0f; up[X] = -v[Z] * left[Y]; up[Y] = v[Z] * left[X]; up[Z] = lenSqr * invLen; } } // ======================================================== // ddMat4x4 helpers: // ======================================================== static inline void matTransformPointXYZ(ddVec3_Out result, ddVec3_In p, ddMat4x4_In m) { result[X] = (m[0] * p[X]) + (m[4] * p[Y]) + (m[8] * p[Z]) + m[12]; // p[W] assumed to be 1 result[Y] = (m[1] * p[X]) + (m[5] * p[Y]) + (m[9] * p[Z]) + m[13]; result[Z] = (m[2] * p[X]) + (m[6] * p[Y]) + (m[10] * p[Z]) + m[14]; } static inline void matTransformPointXYZW(float result[4], ddVec3_In p, ddMat4x4_In m) { result[X] = (m[0] * p[X]) + (m[4] * p[Y]) + (m[8] * p[Z]) + m[12]; // p[W] assumed to be 1 result[Y] = (m[1] * p[X]) + (m[5] * p[Y]) + (m[9] * p[Z]) + m[13]; result[Z] = (m[2] * p[X]) + (m[6] * p[Y]) + (m[10] * p[Z]) + m[14]; result[W] = (m[3] * p[X]) + (m[7] * p[Y]) + (m[11] * p[Z]) + m[15]; } static inline float matTransformPointXYZW2(ddVec3_Out result, const float p[3], ddMat4x4_In m) { result[X] = (m[0] * p[X]) + (m[4] * p[Y]) + (m[8] * p[Z]) + m[12]; // p[W] assumed to be 1 result[Y] = (m[1] * p[X]) + (m[5] * p[Y]) + (m[9] * p[Z]) + m[13]; result[Z] = (m[2] * p[X]) + (m[6] * p[Y]) + (m[10] * p[Z]) + m[14]; float rw = (m[3] * p[X]) + (m[7] * p[Y]) + (m[11] * p[Z]) + m[15]; return rw; } // ======================================================== // Misc local functions for draw queue management: // ======================================================== enum DrawMode { DrawModePoints, DrawModeLines, DrawModeText }; static void flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const DrawMode mode, const bool depthEnabled) { if (DD_CONTEXT->vertexBufferUsed == 0) { return; } switch (mode) { case DrawModePoints : DD_CONTEXT->renderInterface->drawPointList(DD_CONTEXT->vertexBuffer, DD_CONTEXT->vertexBufferUsed, depthEnabled); break; case DrawModeLines : DD_CONTEXT->renderInterface->drawLineList(DD_CONTEXT->vertexBuffer, DD_CONTEXT->vertexBufferUsed, depthEnabled); break; case DrawModeText : DD_CONTEXT->renderInterface->drawGlyphList(DD_CONTEXT->vertexBuffer, DD_CONTEXT->vertexBufferUsed, DD_CONTEXT->glyphTexHandle); break; } // switch (mode) DD_CONTEXT->vertexBufferUsed = 0; } static void pushPointVert(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const DebugPoint & point) { // Make room for one more vert: if ((DD_CONTEXT->vertexBufferUsed + 1) >= DEBUG_DRAW_VERTEX_BUFFER_SIZE) { flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModePoints, point.depthEnabled); } DrawVertex & v = DD_CONTEXT->vertexBuffer[DD_CONTEXT->vertexBufferUsed++]; v.point.x = point.position[X]; v.point.y = point.position[Y]; v.point.z = point.position[Z]; v.point.r = point.color[X]; v.point.g = point.color[Y]; v.point.b = point.color[Z]; v.point.size = point.size; } static void pushLineVert(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const DebugLine & line) { // Make room for two more verts: if ((DD_CONTEXT->vertexBufferUsed + 2) >= DEBUG_DRAW_VERTEX_BUFFER_SIZE) { flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeLines, line.depthEnabled); } DrawVertex & v0 = DD_CONTEXT->vertexBuffer[DD_CONTEXT->vertexBufferUsed++]; DrawVertex & v1 = DD_CONTEXT->vertexBuffer[DD_CONTEXT->vertexBufferUsed++]; v0.line.x = line.posFrom[X]; v0.line.y = line.posFrom[Y]; v0.line.z = line.posFrom[Z]; v0.line.r = line.color[X]; v0.line.g = line.color[Y]; v0.line.b = line.color[Z]; v1.line.x = line.posTo[X]; v1.line.y = line.posTo[Y]; v1.line.z = line.posTo[Z]; v1.line.r = line.color[X]; v1.line.g = line.color[Y]; v1.line.b = line.color[Z]; } static void pushGlyphVerts(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const DrawVertex verts[4]) { static const int indexes[6] = { 0, 1, 2, 2, 1, 3 }; // Make room for one more glyph (2 tris): if ((DD_CONTEXT->vertexBufferUsed + 6) >= DEBUG_DRAW_VERTEX_BUFFER_SIZE) { flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeText, false); } for (int i = 0; i < 6; ++i) { DD_CONTEXT->vertexBuffer[DD_CONTEXT->vertexBufferUsed++].glyph = verts[indexes[i]].glyph; } } static void pushStringGlyphs(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) float x, float y, const char * text, ddVec3_In color, const float scaling) { // Invariants for all characters: const float initialX = x; const float scaleU = static_cast(getFontCharSet().bitmapWidth); const float scaleV = static_cast(getFontCharSet().bitmapHeight); const float fixedWidth = static_cast(getFontCharSet().charWidth); const float fixedHeight = static_cast(getFontCharSet().charHeight); const float tabW = fixedWidth * 4.0f * scaling; // TAB = 4 spaces. const float chrW = fixedWidth * scaling; const float chrH = fixedHeight * scaling; for (; *text != '\0'; ++text) { const int charVal = *text; if (charVal >= FontCharSet::MaxChars) { continue; } if (charVal == ' ') { x += chrW; continue; } if (charVal == '\t') { x += tabW; continue; } if (charVal == '\n') { y += chrH; x = initialX; continue; } const FontChar fontChar = getFontCharSet().chars[charVal]; const float u0 = (fontChar.x + 0.5f) / scaleU; const float v0 = (fontChar.y + 0.5f) / scaleV; const float u1 = u0 + (fixedWidth / scaleU); const float v1 = v0 + (fixedHeight / scaleV); DrawVertex verts[4]; verts[0].glyph.x = x; verts[0].glyph.y = y; verts[0].glyph.u = u0; verts[0].glyph.v = v0; verts[0].glyph.r = color[X]; verts[0].glyph.g = color[Y]; verts[0].glyph.b = color[Z]; verts[1].glyph.x = x; verts[1].glyph.y = y + chrH; verts[1].glyph.u = u0; verts[1].glyph.v = v1; verts[1].glyph.r = color[X]; verts[1].glyph.g = color[Y]; verts[1].glyph.b = color[Z]; verts[2].glyph.x = x + chrW; verts[2].glyph.y = y; verts[2].glyph.u = u1; verts[2].glyph.v = v0; verts[2].glyph.r = color[X]; verts[2].glyph.g = color[Y]; verts[2].glyph.b = color[Z]; verts[3].glyph.x = x + chrW; verts[3].glyph.y = y + chrH; verts[3].glyph.u = u1; verts[3].glyph.v = v1; verts[3].glyph.r = color[X]; verts[3].glyph.g = color[Y]; verts[3].glyph.b = color[Z]; pushGlyphVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) verts); x += chrW; } } static float calcTextWidth(const char * text, const float scaling) { const float fixedWidth = static_cast(getFontCharSet().charWidth); const float tabW = fixedWidth * 4.0f * scaling; // TAB = 4 spaces. const float chrW = fixedWidth * scaling; float x = 0.0f; for (; *text != '\0'; ++text) { // Tabs are handled differently (4 spaces) if (*text == '\t') { x += tabW; } else // Non-tab char (including whitespace) { x += chrW; } } return x; } static void drawDebugStrings(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)) { const int count = DD_CONTEXT->debugStringsCount; if (count == 0) { return; } const DebugString * const debugStrings = DD_CONTEXT->debugStrings; for (int i = 0; i < count; ++i) { const DebugString & dstr = debugStrings[i]; if (dstr.centered) { // 3D Labels are centered at the point of origin, e.g. center-aligned. const float offset = calcTextWidth(dstr.text.c_str(), dstr.scaling) * 0.5f; pushStringGlyphs(DD_EXPLICIT_CONTEXT_ONLY(ctx,) dstr.posX - offset, dstr.posY, dstr.text.c_str(), dstr.color, dstr.scaling); } else { // Left-aligned pushStringGlyphs(DD_EXPLICIT_CONTEXT_ONLY(ctx,) dstr.posX, dstr.posY, dstr.text.c_str(), dstr.color, dstr.scaling); } } flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeText, false); } static void drawDebugPoints(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)) { const int count = DD_CONTEXT->debugPointsCount; if (count == 0) { return; } const DebugPoint * const debugPoints = DD_CONTEXT->debugPoints; // // First pass, points with depth test ENABLED: // int numDepthlessPoints = 0; for (int i = 0; i < count; ++i) { const DebugPoint & point = debugPoints[i]; if (point.depthEnabled) { pushPointVert(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point); } numDepthlessPoints += !point.depthEnabled; } flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModePoints, true); // // Second pass draws points with depth DISABLED: // if (numDepthlessPoints > 0) { for (int i = 0; i < count; ++i) { const DebugPoint & point = debugPoints[i]; if (!point.depthEnabled) { pushPointVert(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point); } } flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModePoints, false); } } static void drawDebugLines(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)) { const int count = DD_CONTEXT->debugLinesCount; if (count == 0) { return; } const DebugLine * const debugLines = DD_CONTEXT->debugLines; // // First pass, lines with depth test ENABLED: // int numDepthlessLines = 0; for (int i = 0; i < count; ++i) { const DebugLine & line = debugLines[i]; if (line.depthEnabled) { pushLineVert(DD_EXPLICIT_CONTEXT_ONLY(ctx,) line); } numDepthlessLines += !line.depthEnabled; } flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeLines, true); // // Second pass draws lines with depth DISABLED: // if (numDepthlessLines > 0) { for (int i = 0; i < count; ++i) { const DebugLine & line = debugLines[i]; if (!line.depthEnabled) { pushLineVert(DD_EXPLICIT_CONTEXT_ONLY(ctx,) line); } } flushDebugVerts(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DrawModeLines, false); } } template static void clearDebugQueue(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) T * queue, int & queueCount) { const std::int64_t time = DD_CONTEXT->currentTimeMillis; if (time == 0) { queueCount = 0; return; } int index = 0; T * pElem = queue; // Concatenate elements that still need to be draw on future frames: for (int i = 0; i < queueCount; ++i, ++pElem) { if (pElem->expiryDateMillis > time) { if (index != i) { queue[index] = *pElem; } ++index; } } queueCount = index; } static void setupGlyphTexture(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)) { if (DD_CONTEXT->renderInterface == nullptr) { return; } if (DD_CONTEXT->glyphTexHandle != nullptr) { DD_CONTEXT->renderInterface->destroyGlyphTexture(DD_CONTEXT->glyphTexHandle); DD_CONTEXT->glyphTexHandle = nullptr; } std::uint8_t * decompressedBitmap = decompressFontBitmap(); if (decompressedBitmap == nullptr) { return; // Failed to decompressed. No font rendering available. } DD_CONTEXT->glyphTexHandle = DD_CONTEXT->renderInterface->createGlyphTexture( getFontCharSet().bitmapWidth, getFontCharSet().bitmapHeight, decompressedBitmap); // No longer needed. DD_MFREE(decompressedBitmap); } // ======================================================== // Public Debug Draw interface: // ======================================================== bool initialize(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle * outCtx,) RenderInterface * renderer) { if (renderer == nullptr) { return false; } void * buffer = DD_MALLOC(sizeof(InternalContext)); if (buffer == nullptr) { return false; } InternalContext * newCtx = ::new(buffer) InternalContext(renderer); #ifdef DEBUG_DRAW_EXPLICIT_CONTEXT if ((*outCtx) != nullptr) { shutdown(*outCtx); } (*outCtx) = newCtx; #else // !DEBUG_DRAW_EXPLICIT_CONTEXT if (DD_CONTEXT != nullptr) { shutdown(); } DD_CONTEXT = newCtx; #endif // DEBUG_DRAW_EXPLICIT_CONTEXT setupGlyphTexture(DD_EXPLICIT_CONTEXT_ONLY(*outCtx)); return true; } void shutdown(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)) { if (DD_CONTEXT != nullptr) { // If this macro is defined, the user-provided ddStr type // needs some extra cleanup before shutdown, so we run for // all entries in the debugStrings[] array. // // We could call std::string::clear() here, but clear() // doesn't deallocate memory in std string, so we might // as well let the default destructor do the cleanup, // when using the default (AKA std::string) ddStr. #ifdef DEBUG_DRAW_STR_DEALLOC_FUNC for (int i = 0; i < DEBUG_DRAW_MAX_STRINGS; ++i) { DEBUG_DRAW_STR_DEALLOC_FUNC(DD_CONTEXT->debugStrings[i].text); } #endif // DEBUG_DRAW_STR_DEALLOC_FUNC if (DD_CONTEXT->renderInterface != nullptr && DD_CONTEXT->glyphTexHandle != nullptr) { DD_CONTEXT->renderInterface->destroyGlyphTexture(DD_CONTEXT->glyphTexHandle); } DD_CONTEXT->~InternalContext(); // Destroy first DD_MFREE(DD_CONTEXT); #ifndef DEBUG_DRAW_EXPLICIT_CONTEXT DD_CONTEXT = nullptr; #endif // DEBUG_DRAW_EXPLICIT_CONTEXT } } bool isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)) { return (DD_CONTEXT != nullptr && DD_CONTEXT->renderInterface != nullptr); } bool hasPendingDraws(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return false; } return (DD_CONTEXT->debugStringsCount + DD_CONTEXT->debugPointsCount + DD_CONTEXT->debugLinesCount) > 0; } void flush(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const std::int64_t currTimeMillis, const std::uint32_t flags) { if (!hasPendingDraws(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } // Save the last know time value for next dd::line/dd::point calls. DD_CONTEXT->currentTimeMillis = currTimeMillis; // Let the user set common render states. DD_CONTEXT->renderInterface->beginDraw(); // Issue the render calls: if (flags & FlushLines) { drawDebugLines(DD_EXPLICIT_CONTEXT_ONLY(ctx)); } if (flags & FlushPoints) { drawDebugPoints(DD_EXPLICIT_CONTEXT_ONLY(ctx)); } if (flags & FlushText) { drawDebugStrings(DD_EXPLICIT_CONTEXT_ONLY(ctx)); } // And cleanup if needed. DD_CONTEXT->renderInterface->endDraw(); // Remove all expired objects, regardless of draw flags: clearDebugQueue(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DD_CONTEXT->debugStrings, DD_CONTEXT->debugStringsCount); clearDebugQueue(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DD_CONTEXT->debugPoints, DD_CONTEXT->debugPointsCount); clearDebugQueue(DD_EXPLICIT_CONTEXT_ONLY(ctx,) DD_CONTEXT->debugLines, DD_CONTEXT->debugLinesCount); } void clear(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx)) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } // Let the user cleanup the debug strings: #ifdef DEBUG_DRAW_STR_DEALLOC_FUNC for (int i = 0; i < DEBUG_DRAW_MAX_STRINGS; ++i) { DEBUG_DRAW_STR_DEALLOC_FUNC(DD_CONTEXT->debugStrings[i].text); } #endif // DEBUG_DRAW_STR_DEALLOC_FUNC DD_CONTEXT->vertexBufferUsed = 0; DD_CONTEXT->debugStringsCount = 0; DD_CONTEXT->debugPointsCount = 0; DD_CONTEXT->debugLinesCount = 0; } void point(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In pos, ddVec3_In color, const float size, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } if (DD_CONTEXT->debugPointsCount == DEBUG_DRAW_MAX_POINTS) { DEBUG_DRAW_OVERFLOWED("DEBUG_DRAW_MAX_POINTS limit reached! Dropping further debug point draws."); return; } DebugPoint & point = DD_CONTEXT->debugPoints[DD_CONTEXT->debugPointsCount++]; point.expiryDateMillis = DD_CONTEXT->currentTimeMillis + durationMillis; point.depthEnabled = depthEnabled; point.size = size; vecCopy(point.position, pos); vecCopy(point.color, color); } void line(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In from, ddVec3_In to, ddVec3_In color, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } if (DD_CONTEXT->debugLinesCount == DEBUG_DRAW_MAX_LINES) { DEBUG_DRAW_OVERFLOWED("DEBUG_DRAW_MAX_LINES limit reached! Dropping further debug line draws."); return; } DebugLine & line = DD_CONTEXT->debugLines[DD_CONTEXT->debugLinesCount++]; line.expiryDateMillis = DD_CONTEXT->currentTimeMillis + durationMillis; line.depthEnabled = depthEnabled; vecCopy(line.posFrom, from); vecCopy(line.posTo, to); vecCopy(line.color, color); } void screenText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const char * const str, ddVec3_In pos, ddVec3_In color, const float scaling, const int durationMillis) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } if (DD_CONTEXT->glyphTexHandle == nullptr) { return; } if (DD_CONTEXT->debugStringsCount == DEBUG_DRAW_MAX_STRINGS) { DEBUG_DRAW_OVERFLOWED("DEBUG_DRAW_MAX_STRINGS limit reached! Dropping further debug string draws."); return; } DebugString & dstr = DD_CONTEXT->debugStrings[DD_CONTEXT->debugStringsCount++]; dstr.expiryDateMillis = DD_CONTEXT->currentTimeMillis + durationMillis; dstr.posX = pos[X]; dstr.posY = pos[Y]; dstr.scaling = scaling; dstr.text = str; dstr.centered = false; vecCopy(dstr.color, color); } void projectedText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const char * const str, ddVec3_In pos, ddVec3_In color, ddMat4x4_In vpMatrix, const int sx, const int sy, const int sw, const int sh, const float scaling, const int durationMillis) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } if (DD_CONTEXT->glyphTexHandle == nullptr) { return; } if (DD_CONTEXT->debugStringsCount == DEBUG_DRAW_MAX_STRINGS) { DEBUG_DRAW_OVERFLOWED("DEBUG_DRAW_MAX_STRINGS limit reached! Dropping further debug string draws."); return; } float tempPoint[4]; matTransformPointXYZW(tempPoint, pos, vpMatrix); // Bail if W ended up as zero. if (floatAbs(tempPoint[W]) < FloatEpsilon) { return; } // Bail if point is behind camera. if (tempPoint[Z] < -tempPoint[W] || tempPoint[Z] > tempPoint[W]) { return; } // Perspective divide (we only care about the 2D part now): tempPoint[X] /= tempPoint[W]; tempPoint[Y] /= tempPoint[W]; // Map to window coordinates: float scrX = ((tempPoint[X] * 0.5f) + 0.5f) * sw + sx; float scrY = ((tempPoint[Y] * 0.5f) + 0.5f) * sh + sy; // Need to invert the direction because on OGL the screen origin is the bottom-left corner. // NOTE: This is not renderer agnostic, I think... Should add a #define or something! scrY = static_cast(sh) - scrY; DebugString & dstr = DD_CONTEXT->debugStrings[DD_CONTEXT->debugStringsCount++]; dstr.expiryDateMillis = DD_CONTEXT->currentTimeMillis + durationMillis; dstr.posX = scrX; dstr.posY = scrY; dstr.scaling = scaling; dstr.text = str; dstr.centered = true; vecCopy(dstr.color, color); } void axisTriad(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddMat4x4_In transform, const float size, const float length, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } ddVec3 p0, p1, p2, p3; ddVec3 xEnd, yEnd, zEnd; ddVec3 origin, cR, cG, cB; vecSet(cR, 1.0f, 0.0f, 0.0f); vecSet(cG, 0.0f, 1.0f, 0.0f); vecSet(cB, 0.0f, 0.0f, 1.0f); vecSet(origin, 0.0f, 0.0f, 0.0f); vecSet(xEnd, length, 0.0f, 0.0f); vecSet(yEnd, 0.0f, length, 0.0f); vecSet(zEnd, 0.0f, 0.0f, length); matTransformPointXYZ(p0, origin, transform); matTransformPointXYZ(p1, xEnd, transform); matTransformPointXYZ(p2, yEnd, transform); matTransformPointXYZ(p3, zEnd, transform); arrow(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p0, p1, cR, size, durationMillis, depthEnabled); // X: red axis arrow(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p0, p2, cG, size, durationMillis, depthEnabled); // Y: green axis arrow(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p0, p3, cB, size, durationMillis, depthEnabled); // Z: blue axis } void arrow(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In from, ddVec3_In to, ddVec3_In color, const float size, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } static const float arrowStep = 30.0f; // In degrees static const float arrowSin[45] = { 0.0f, 0.5f, 0.866025f, 1.0f, 0.866025f, 0.5f, -0.0f, -0.5f, -0.866025f, -1.0f, -0.866025f, -0.5f, 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, 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, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; static const float arrowCos[45] = { 1.0f, 0.866025f, 0.5f, -0.0f, -0.5f, -0.866026f, -1.0f, -0.866025f, -0.5f, 0.0f, 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, 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, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; // Body line: line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, color, durationMillis, depthEnabled); // Aux vectors to compute the arrowhead: ddVec3 up, right, forward; vecSub(forward, to, from); vecNormalize(forward, forward); vecOrthogonalBasis(right, up, forward); vecScale(forward, forward, size); // Arrowhead is a cone (sin/cos tables used here): float degrees = 0.0f; for (int i = 0; degrees < 360.0f; degrees += arrowStep, ++i) { float scale; ddVec3 v1, v2, temp; scale = 0.5f * size * arrowCos[i]; vecScale(temp, right, scale); vecSub(v1, to, forward); vecAdd(v1, v1, temp); scale = 0.5f * size * arrowSin[i]; vecScale(temp, up, scale); vecAdd(v1, v1, temp); scale = 0.5f * size * arrowCos[i + 1]; vecScale(temp, right, scale); vecSub(v2, to, forward); vecAdd(v2, v2, temp); scale = 0.5f * size * arrowSin[i + 1]; vecScale(temp, up, scale); vecAdd(v2, v2, temp); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v1, to, color, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v1, v2, color, durationMillis, depthEnabled); } } void cross(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, const float length, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } ddVec3 from, to; ddVec3 cR, cG, cB; vecSet(cR, 1.0f, 0.0f, 0.0f); vecSet(cG, 0.0f, 1.0f, 0.0f); vecSet(cB, 0.0f, 0.0f, 1.0f); const float cx = center[X]; const float cy = center[Y]; const float cz = center[Z]; const float hl = length * 0.5f; // Half on each side. // Red line: X - length/2 to X + length/2 vecSet(from, cx - hl, cy, cz); vecSet(to, cx + hl, cy, cz); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, cR, durationMillis, depthEnabled); // Green line: Y - length/2 to Y + length/2 vecSet(from, cx, cy - hl, cz); vecSet(to, cx, cy + hl, cz); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, cG, durationMillis, depthEnabled); // Blue line: Z - length/2 to Z + length/2 vecSet(from, cx, cy, cz - hl); vecSet(to, cx, cy, cz + hl); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, cB, durationMillis, depthEnabled); } void circle(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In planeNormal, ddVec3_In color, const float radius, const float numSteps, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } ddVec3 left, up; ddVec3 point, lastPoint; vecOrthogonalBasis(left, up, planeNormal); vecScale(up, up, radius); vecScale(left, left, radius); vecAdd(lastPoint, center, up); for (int i = 1; i <= numSteps; ++i) { const float radians = TAU * i / numSteps; ddVec3 vs, vc; vecScale(vs, left, floatSin(radians)); vecScale(vc, up, floatCos(radians)); vecAdd(point, center, vs); vecAdd(point, point, vc); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastPoint, point, color, durationMillis, depthEnabled); vecCopy(lastPoint, point); } } void plane(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In planeNormal, ddVec3_In planeColor, ddVec3_In normalVecColor, const float planeScale, const float normalVecScale, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } ddVec3 v1, v2, v3, v4; ddVec3 tangent, bitangent; vecOrthogonalBasis(tangent, bitangent, planeNormal); // A little bit of preprocessor voodoo to make things more interesting :P #define DD_PLANE_V(v, op1, op2) \ v[X] = (center[X] op1 (tangent[X] * planeScale) op2 (bitangent[X] * planeScale)); \ v[Y] = (center[Y] op1 (tangent[Y] * planeScale) op2 (bitangent[Y] * planeScale)); \ v[Z] = (center[Z] op1 (tangent[Z] * planeScale) op2 (bitangent[Z] * planeScale)) DD_PLANE_V(v1, -, -); DD_PLANE_V(v2, +, -); DD_PLANE_V(v3, +, +); DD_PLANE_V(v4, -, +); #undef DD_PLANE_V // Draw the wireframe plane quadrilateral: line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v1, v2, planeColor, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v2, v3, planeColor, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v3, v4, planeColor, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) v4, v1, planeColor, durationMillis, depthEnabled); // Optionally add a line depicting the plane normal: if (normalVecScale != 0.0f) { ddVec3 normalVec; normalVec[X] = (planeNormal[X] * normalVecScale) + center[X]; normalVec[Y] = (planeNormal[Y] * normalVecScale) + center[Y]; normalVec[Z] = (planeNormal[Z] * normalVecScale) + center[Z]; line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) center, normalVec, normalVecColor, durationMillis, depthEnabled); } } void sphere(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In color, const float radius, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } static const int stepSize = 15; ddVec3 cache[360 / stepSize]; ddVec3 radiusVec; vecSet(radiusVec, 0.0f, 0.0f, radius); vecAdd(cache[0], center, radiusVec); for (int n = 1; n < arrayLength(cache); ++n) { vecCopy(cache[n], cache[0]); } ddVec3 lastPoint, temp; for (int i = stepSize; i <= 360; i += stepSize) { const float s = floatSin(degreesToRadians(i)); const float c = floatCos(degreesToRadians(i)); lastPoint[X] = center[X]; lastPoint[Y] = center[Y] + radius * s; lastPoint[Z] = center[Z] + radius * c; for (int n = 0, j = stepSize; j <= 360; j += stepSize, ++n) { temp[X] = center[X] + floatSin(degreesToRadians(j)) * radius * s; temp[Y] = center[Y] + floatCos(degreesToRadians(j)) * radius * s; temp[Z] = lastPoint[Z]; line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastPoint, temp, color, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastPoint, cache[n], color, durationMillis, depthEnabled); vecCopy(cache[n], lastPoint); vecCopy(lastPoint, temp); } } } void cone(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In apex, ddVec3_In dir, ddVec3_In color, const float baseRadius, const float apexRadius, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } static const int stepSize = 20; ddVec3 axis[3]; ddVec3 top, temp0, temp1, temp2; ddVec3 p1, p2, lastP1, lastP2; vecCopy(axis[2], dir); vecNormalize(axis[2], axis[2]); vecOrthogonalBasis(axis[0], axis[1], axis[2]); axis[1][X] = -axis[1][X]; axis[1][Y] = -axis[1][Y]; axis[1][Z] = -axis[1][Z]; vecAdd(top, apex, dir); vecScale(temp1, axis[1], baseRadius); vecAdd(lastP2, top, temp1); if (apexRadius == 0.0f) { for (int i = stepSize; i <= 360; i += stepSize) { vecScale(temp1, axis[0], floatSin(degreesToRadians(i))); vecScale(temp2, axis[1], floatCos(degreesToRadians(i))); vecAdd(temp0, temp1, temp2); vecScale(temp0, temp0, baseRadius); vecAdd(p2, top, temp0); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastP2, p2, color, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p2, apex, color, durationMillis, depthEnabled); vecCopy(lastP2, p2); } } else // A degenerate cone with open apex: { vecScale(temp1, axis[1], apexRadius); vecAdd(lastP1, apex, temp1); for (int i = stepSize; i <= 360; i += stepSize) { vecScale(temp1, axis[0], floatSin(degreesToRadians(i))); vecScale(temp2, axis[1], floatCos(degreesToRadians(i))); vecAdd(temp0, temp1, temp2); vecScale(temp1, temp0, apexRadius); vecScale(temp2, temp0, baseRadius); vecAdd(p1, apex, temp1); vecAdd(p2, top, temp2); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastP1, p1, color, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) lastP2, p2, color, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) p1, p2, color, durationMillis, depthEnabled); vecCopy(lastP1, p1); vecCopy(lastP2, p2); } } } void box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const ddVec3 points[8], ddVec3_In color, const int durationMillis, const bool depthEnabled) { // Build the lines from points using clever indexing tricks: // (& 3 is a fancy way of doing % 4, but avoids the expensive modulo operation) for (int i = 0; i < 4; ++i) { line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points[i], points[(i + 1) & 3], color, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points[4 + i], points[4 + ((i + 1) & 3)], color, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points[i], points[4 + i], color, durationMillis, depthEnabled); } } void box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In color, const float width, const float height, const float depth, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } const float cx = center[X]; const float cy = center[Y]; const float cz = center[Z]; const float w = width * 0.5f; const float h = height * 0.5f; const float d = depth * 0.5f; // Create all the 8 points: ddVec3 points[8]; #define DD_BOX_V(v, op1, op2, op3) \ v[X] = cx op1 w; \ v[Y] = cy op2 h; \ v[Z] = cz op3 d DD_BOX_V(points[0], -, +, +); DD_BOX_V(points[1], -, +, -); DD_BOX_V(points[2], +, +, -); DD_BOX_V(points[3], +, +, +); DD_BOX_V(points[4], -, -, +); DD_BOX_V(points[5], -, -, -); DD_BOX_V(points[6], +, -, -); DD_BOX_V(points[7], +, -, +); #undef DD_BOX_V box(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points, color, durationMillis, depthEnabled); } void aabb(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In mins, ddVec3_In maxs, ddVec3_In color, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } ddVec3 bb[2]; ddVec3 points[8]; vecCopy(bb[0], mins); vecCopy(bb[1], maxs); // Expand min/max bounds: for (int i = 0; i < arrayLength(points); ++i) { points[i][X] = bb[(i ^ (i >> 1)) & 1][X]; points[i][Y] = bb[(i >> 1) & 1][Y]; points[i][Z] = bb[(i >> 2) & 1][Z]; } // Build the lines: box(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points, color, durationMillis, depthEnabled); } void frustum(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddMat4x4_In invClipMatrix, ddVec3_In color, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } // Start with the standard clip volume, then bring it back to world space. static const float planes[8][3] = { // near plane { -1.0f, -1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { 1.0f, 1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f }, // far plane { -1.0f, -1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f } }; ddVec3 points[8]; float wCoords[8]; // Transform the planes by the inverse clip matrix: for (int i = 0; i < arrayLength(planes); ++i) { wCoords[i] = matTransformPointXYZW2(points[i], planes[i], invClipMatrix); } // Divide by the W component of each: for (int i = 0; i < arrayLength(planes); ++i) { // But bail if any W ended up as zero. if (floatAbs(wCoords[W]) < FloatEpsilon) { return; } points[i][X] /= wCoords[i]; points[i][Y] /= wCoords[i]; points[i][Z] /= wCoords[i]; } // Connect the dots: box(DD_EXPLICIT_CONTEXT_ONLY(ctx,) points, color, durationMillis, depthEnabled); } void vertexNormal(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In origin, ddVec3_In normal, const float length, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } ddVec3 normalVec; ddVec3 normalColor; vecSet(normalColor, 1.0f, 1.0f, 1.0f); normalVec[X] = (normal[X] * length) + origin[X]; normalVec[Y] = (normal[Y] * length) + origin[Y]; normalVec[Z] = (normal[Z] * length) + origin[Z]; line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) origin, normalVec, normalColor, durationMillis, depthEnabled); } void tangentBasis(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In origin, ddVec3_In normal, ddVec3_In tangent, ddVec3_In bitangent, const float lengths, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } ddVec3 cN, cT, cB; ddVec3 vN, vT, vB; vecSet(cN, 1.0f, 1.0f, 1.0f); // Vertex normals are WHITE vecSet(cT, 1.0f, 1.0f, 0.0f); // Tangents are YELLOW vecSet(cB, 1.0f, 0.0f, 1.0f); // Bi-tangents are MAGENTA vN[X] = (normal[X] * lengths) + origin[X]; vN[Y] = (normal[Y] * lengths) + origin[Y]; vN[Z] = (normal[Z] * lengths) + origin[Z]; vT[X] = (tangent[X] * lengths) + origin[X]; vT[Y] = (tangent[Y] * lengths) + origin[Y]; vT[Z] = (tangent[Z] * lengths) + origin[Z]; vB[X] = (bitangent[X] * lengths) + origin[X]; vB[Y] = (bitangent[Y] * lengths) + origin[Y]; vB[Z] = (bitangent[Z] * lengths) + origin[Z]; line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) origin, vN, cN, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) origin, vT, cT, durationMillis, depthEnabled); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) origin, vB, cB, durationMillis, depthEnabled); } void xzSquareGrid(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) const float mins, const float maxs, const float y, const float step, ddVec3_In color, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } ddVec3 from, to; for (float i = mins; i <= maxs; i += step) { // Horizontal line (along the X) vecSet(from, mins, y, i); vecSet(to, maxs, y, i); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, color, durationMillis, depthEnabled); // Vertical line (along the Z) vecSet(from, i, y, mins); vecSet(to, i, y, maxs); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) from, to, color, durationMillis, depthEnabled); } } void capsule(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,) ddVec3_In center, ddVec3_In axis, float length, float radius, ddVec3_In color, const int durationMillis, const bool depthEnabled) { if (!isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ctx))) { return; } // Normalize the axis vector float magnitude = sqrt(axis[X] * axis[X] + axis[Y] * axis[Y] + axis[Z] * axis[Z]); if (magnitude == 0.0f) { return; // Invalid axis, exit gracefully } ddVec3 dir; vecScale(dir, axis, 1.0f / magnitude); // Compute endpoints (centers of the hemispheres) ddVec3 temp; vecScale(temp, dir, length / 2.0f); ddVec3 p1, p2; vecSub(p1, center, temp); // Start point vecAdd(p2, center, temp); // End point // Find vectors u and v perpendicular to dir for the cross-section plane ddVec3 u, v, tempVec; // Choose a vector not parallel to dir if (fabs(dir[X]) <= fabs(dir[Y]) && fabs(dir[X]) <= fabs(dir[Z])) { vecSet(tempVec, 1.0f, 0.0f, 0.0f); } else if (fabs(dir[Y]) <= fabs(dir[Z])) { vecSet(tempVec, 0.0f, 1.0f, 0.0f); } else { vecSet(tempVec, 0.0f, 0.0f, 1.0f); } vecCross(u, tempVec, dir); float uMag = sqrt(u[X] * u[X] + u[Y] * u[Y] + u[Z] * u[Z]); vecScale(u, u, 1.0f / uMag); vecCross(v, dir, u); // v is already unit length since dir and u are orthonormal static const int stepSize = 15; // Draw the cylinder for (int j = 0; j < 360; j += stepSize) { float theta = degreesToRadians((float)j); float theta2 = degreesToRadians((float)(j + stepSize)); ddVec3 point1, point2, point3, point4; float c = floatCos(theta); float s = floatSin(theta); float c2 = floatCos(theta2); float s2 = floatSin(theta2); // Circle at p1 vecSet(point1, p1[X] + radius * (c * u[X] + s * v[X]), p1[Y] + radius * (c * u[Y] + s * v[Y]), p1[Z] + radius * (c * u[Z] + s * v[Z])); vecSet(point2, p1[X] + radius * (c2 * u[X] + s2 * v[X]), p1[Y] + radius * (c2 * u[Y] + s2 * v[Y]), p1[Z] + radius * (c2 * u[Z] + s2 * v[Z])); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point2, color, durationMillis, depthEnabled); // Circle at p2 vecSet(point3, p2[X] + radius * (c * u[X] + s * v[X]), p2[Y] + radius * (c * u[Y] + s * v[Y]), p2[Z] + radius * (c * u[Z] + s * v[Z])); vecSet(point4, p2[X] + radius * (c2 * u[X] + s2 * v[X]), p2[Y] + radius * (c2 * u[Y] + s2 * v[Y]), p2[Z] + radius * (c2 * u[Z] + s2 * v[Z])); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point3, point4, color, durationMillis, depthEnabled); // Connecting line between circles line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point3, color, durationMillis, depthEnabled); } // Draw hemisphere at p1 (dome along -dir) ddVec3 d1; vecScale(d1, dir, -1.0f); // Direction for p1 hemisphere for (int i = 0; i <= 90; i += stepSize) { float phi = degreesToRadians((float)i); float s = floatSin(phi); float c = floatCos(phi); for (int j = 0; j < 360; j += stepSize) { float theta = degreesToRadians((float)j); float theta2 = degreesToRadians((float)(j + stepSize)); ddVec3 point1, point2; vecSet(point1, p1[X] + radius * (s * floatCos(theta) * u[X] + s * floatSin(theta) * v[X] + c * d1[X]), p1[Y] + radius * (s * floatCos(theta) * u[Y] + s * floatSin(theta) * v[Y] + c * d1[Y]), p1[Z] + radius * (s * floatCos(theta) * u[Z] + s * floatSin(theta) * v[Z] + c * d1[Z])); vecSet(point2, p1[X] + radius * (s * floatCos(theta2) * u[X] + s * floatSin(theta2) * v[X] + c * d1[X]), p1[Y] + radius * (s * floatCos(theta2) * u[Y] + s * floatSin(theta2) * v[Y] + c * d1[Y]), p1[Z] + radius * (s * floatCos(theta2) * u[Z] + s * floatSin(theta2) * v[Z] + c * d1[Z])); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point2, color, durationMillis, depthEnabled); if (i < 90) { float phi2 = degreesToRadians((float)(i + stepSize)); float s2 = floatSin(phi2); float c2 = floatCos(phi2); ddVec3 point3; vecSet(point3, p1[X] + radius * (s2 * floatCos(theta) * u[X] + s2 * floatSin(theta) * v[X] + c2 * d1[X]), p1[Y] + radius * (s2 * floatCos(theta) * u[Y] + s2 * floatSin(theta) * v[Y] + c2 * d1[Y]), p1[Z] + radius * (s2 * floatCos(theta) * u[Z] + s2 * floatSin(theta) * v[Z] + c2 * d1[Z])); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point3, color, durationMillis, depthEnabled); } } } // Draw hemisphere at p2 (dome along +dir) for (int i = 0; i <= 90; i += stepSize) { float phi = degreesToRadians((float)i); float s = floatSin(phi); float c = floatCos(phi); for (int j = 0; j < 360; j += stepSize) { float theta = degreesToRadians((float)j); float theta2 = degreesToRadians((float)(j + stepSize)); ddVec3 point1, point2; vecSet(point1, p2[X] + radius * (s * floatCos(theta) * u[X] + s * floatSin(theta) * v[X] + c * dir[X]), p2[Y] + radius * (s * floatCos(theta) * u[Y] + s * floatSin(theta) * v[Y] + c * dir[Y]), p2[Z] + radius * (s * floatCos(theta) * u[Z] + s * floatSin(theta) * v[Z] + c * dir[Z])); vecSet(point2, p2[X] + radius * (s * floatCos(theta2) * u[X] + s * floatSin(theta2) * v[X] + c * dir[X]), p2[Y] + radius * (s * floatCos(theta2) * u[Y] + s * floatSin(theta2) * v[Y] + c * dir[Y]), p2[Z] + radius * (s * floatCos(theta2) * u[Z] + s * floatSin(theta2) * v[Z] + c * dir[Z])); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point2, color, durationMillis, depthEnabled); if (i < 90) { float phi2 = degreesToRadians((float)(i + stepSize)); float s2 = floatSin(phi2); float c2 = floatCos(phi2); ddVec3 point3; vecSet(point3, p2[X] + radius * (s2 * floatCos(theta) * u[X] + s2 * floatSin(theta) * v[X] + c2 * dir[X]), p2[Y] + radius * (s2 * floatCos(theta) * u[Y] + s2 * floatSin(theta) * v[Y] + c2 * dir[Y]), p2[Z] + radius * (s2 * floatCos(theta) * u[Z] + s2 * floatSin(theta) * v[Z] + c2 * dir[Z])); line(DD_EXPLICIT_CONTEXT_ONLY(ctx,) point1, point3, color, durationMillis, depthEnabled); } } } } // ======================================================== // RenderInterface stubs: // ======================================================== RenderInterface::~RenderInterface() { } void RenderInterface::beginDraw() { } void RenderInterface::endDraw() { } void RenderInterface::drawPointList(const DrawVertex *, int, bool) { } void RenderInterface::drawLineList(const DrawVertex *, int, bool) { } void RenderInterface::drawGlyphList(const DrawVertex *, int, GlyphTextureHandle) { } void RenderInterface::destroyGlyphTexture(GlyphTextureHandle) { } GlyphTextureHandle RenderInterface::createGlyphTexture(int, int, const void *) { return nullptr; } } // namespace dd #undef DD_CONTEXT #undef DD_MALLOC #undef DD_MFREE // ================ End of implementation ================= #endif // DEBUG_DRAW_IMPLEMENTATION // ================ End of implementation ================= ================================================ FILE: samples/Makefile ================================================ #------------------------------------------------ # Brief: Makefile for the Debug Draw samples. # # Remarks: # - Tested only on Mac OSX; Should work on Linux. # - GLFW must be installed on the system. # (http://www.glfw.org) #------------------------------------------------ # Select the proper OpenGL library for Mac (-framework OpenGL) # or use a default (-lGL) that should work on most Unix-like systems. # This script also assumes GLFW is installed and available in the system path. UNAME = $(shell uname -s) ifeq ($(UNAME), Darwin) OPENGL_LIB = -framework CoreFoundation -framework OpenGL else OPENGL_LIB = -lGL endif # GLFW Should be installed and visible in the system path! ifeq ($(UNAME), Darwin) CXXFLAGS += -Weffc++ GLFW_LIB = -L/usr/local/lib -lglfw LIBRARIES = -framework Cocoa -framework IOKit -framework CoreVideo endif ifeq ($(UNAME), Linux) CXXFLAGS += `pkg-config --cflags glfw3` GLFW_LIB = `pkg-config --static --libs glfw3` endif # Compile an Address Sanitizer build if this flag is set ifdef ASAN CXXFLAGS += -g -fsanitize=address -fno-omit-frame-pointer endif # Define 'VERBOSE' to get the full console output. # Otherwise we print a shorter message for each rule. ifndef VERBOSE QUIET = @ ECHO_COMPILING = @echo "-> Building Debug Draw samples ..." ECHO_CLEANING = @echo "-> Cleaning ..." endif #------------------------------------------------ # Macros / source files: #------------------------------------------------ LIBRARIES += $(OPENGL_LIB) $(GLFW_LIB) INC_DIRS = -I. -I.. -Ivectormath -Igl3w/include CXXFLAGS += $(INC_DIRS) -std=c++11 -O3 -Wall -Wextra -Winit-self -Wunused -Wshadow -Wno-strict-aliasing CFLAGS = $(CXXFLAGS) # Null renderer sample: SRC_FILES_NULL_SAMP = sample_null_renderer.cpp BIN_TARGET_NULL_SAMP = sample_null_renderer # Legacy OpenGL sample: SRC_FILES_GL_LEGACY_SAMP = sample_gl_legacy.cpp BIN_TARGET_GL_LEGACY_SAMP = sample_gl_legacy # Core OpenGL sample: SRC_FILES_GL_CORE_SAMP = gl3w/src/gl3w.cpp sample_gl_core.cpp BIN_TARGET_GL_CORE_SAMP = sample_gl_core # Multi-threaded sample with explicit context: SRC_FILES_GL_CORE_MT_SAMP_1 = gl3w/src/gl3w.cpp sample_gl_core_multithreaded_explicit.cpp BIN_TARGET_GL_CORE_MT_SAMP_1 = sample_gl_core_multithreaded_explicit # Multi-threaded sample with thread-local implicit context: SRC_FILES_GL_CORE_MT_SAMP_2 = gl3w/src/gl3w.cpp sample_gl_core_multithreaded_tls.cpp BIN_TARGET_GL_CORE_MT_SAMP_2 = sample_gl_core_multithreaded_tls #------------------------------------------------ # Build rules: #------------------------------------------------ all: $(ECHO_COMPILING) $(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_NULL_SAMP) -o $(BIN_TARGET_NULL_SAMP) $(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_GL_LEGACY_SAMP) -o $(BIN_TARGET_GL_LEGACY_SAMP) $(LIBRARIES) $(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_GL_CORE_SAMP) -o $(BIN_TARGET_GL_CORE_SAMP) $(LIBRARIES) $(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_GL_CORE_MT_SAMP_1) -o $(BIN_TARGET_GL_CORE_MT_SAMP_1) $(LIBRARIES) $(QUIET) $(CXX) $(CXXFLAGS) $(SRC_FILES_GL_CORE_MT_SAMP_2) -o $(BIN_TARGET_GL_CORE_MT_SAMP_2) $(LIBRARIES) clean: $(ECHO_CLEANING) $(QUIET) rm -f $(BIN_TARGET_NULL_SAMP) $(QUIET) rm -f $(BIN_TARGET_GL_LEGACY_SAMP) $(QUIET) rm -f $(BIN_TARGET_GL_CORE_SAMP) $(QUIET) rm -f $(BIN_TARGET_GL_CORE_MT_SAMP_1) $(QUIET) rm -f $(BIN_TARGET_GL_CORE_MT_SAMP_2) $(QUIET) rm -rf *.dSYM ================================================ FILE: samples/README.md ================================================ ### Debug Draw Samples Three sample programs showing basic usage of the Debug Draw library are currently provided: - `sample_null_renderer.cpp`: Just a tiny `main()` that calls a couple functions and exists. This sample is meant only to test if the library will compile without errors. - `sample_gl_core.cpp`: Sample using core (shader-based) OpenGL that draws a handful of debug shapes using the library. You can move around using `W,A,S,D` or the arrow keys. Click on the window and drag the mouse to rotate the camera. This sample requires OpenGL version 3.2 or newer. - `sample_gl_legacy.cpp`: Exact same as the core GL sample, but uses a legacy (AKA fixed-function) OpenGL renderer instead. - `sample_gl_core_multithreaded_tls.cpp` and `sample_gl_core_multithreaded_explicit.cpp` are similar to the Core OpenGL sample but demonstrate how to use the TLS or explicit context modes. - `sample_d3d11.cpp`: Windows sample using D3D11 as the renderer interface for Debug Draw. - `samples_common.hpp`: Contains code shared by all samples, such as input handling and camera/controls. ---- To build the samples on Linux or MacOS, run the provided Makefile. For Windows, Visual Studio projects are included for VS2015. The only external dependency required to build the samples is [GLFW](http://www.glfw.org/). Make sure to install it before attempting to build them. [GL3W](https://github.com/skaslev/gl3w) is our extension wrangler for the Core OpenGL sample. It is included here and builds with DD. Sony's Vectormath library is also a dependency, but it is included as well. Those libraries are only required for the samples and not by Debug Draw itself. The samples have only been officially tested on MacOS and Windows 7 & 10, though should build and run fine on Linux, provided that you have GLFW installed. Running them requires at least OpenGL v3.2, but due to hardware differences there's no guarantee that they will render the expected outputs, even if your machine supports GL3+. Little to no handling is done to account for GL version and hardware differences, so the samples might not run properly on your hardware. The main idea is that they serve as a rough guide on how to integrate Debug Draw into your own projects, so there's more value in the code itself than in the demo applications, which are just drawing some line shapes in the 3D world and some HUD text, nothing more. ================================================ FILE: samples/gl3w/README.rst ================================================ ======================================== gl3w: Simple OpenGL core profile loading ======================================== Introduction ------------ gl3w_ is the easiest way to get your hands on the functionality offered by the OpenGL core profile specification. Its main part is a simple gl3w_gen.py_ Python script that downloads the Khronos_ supported glcorearb.h_ header and generates gl3w.h and gl3w.c from it. Those files can then be added and linked (statically or dynamically) into your project. Requirements ------------ gl3w_gen.py_ requires Python version 2.6 or newer, with SSL support. It is also compatible with Python 3.x. Example ------- Here is a simple example of using gl3w_ with glut. Note that GL/gl3w.h must be included before any other OpenGL related headers:: #include #include #include // ... int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(width, height); glutCreateWindow("cookie"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutMouseFunc(mouse); glutMotionFunc(motion); if (gl3wInit()) { fprintf(stderr, "failed to initialize OpenGL\n"); return -1; } if (!gl3wIsSupported(3, 2)) { fprintf(stderr, "OpenGL 3.2 not supported\n"); return -1; } printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION)); // ... glutMainLoop(); return 0; } API Reference ------------- The gl3w_ API consists of just three functions: ``int gl3wInit(void)`` Initializes the library. Should be called once after an OpenGL context has been created. Returns ``0`` when gl3w_ was initialized successfully, ``-1`` if there was an error. ``int gl3wIsSupported(int major, int minor)`` Returns ``1`` when OpenGL core profile version *major.minor* is available and ``0`` otherwise. ``GL3WglProc gl3wGetProcAddress(const char *proc)`` Returns the address of an OpenGL extension function. Generally, you won't need to use it since gl3w_ loads all functions defined in the OpenGL core profile on initialization. It allows you to load OpenGL extensions outside of the core profile. License ------- gl3w_ is in the public domain. See the file UNLICENSE for more information. Credits ------- Slavomir Kaslev Initial implementation Kelvin McDowell Mac OS X support Sjors Gielen Mac OS X support Travis Gesslein Patches regarding glcorearb.h Arthur Tombs Port to Python 3 Rommel160 [github.com/Rommel160] Code contributions Copyright --------- OpenGL_ is a registered trademark of SGI_. .. _gl3w: https://github.com/skaslev/gl3w .. _gl3w_gen.py: https://github.com/skaslev/gl3w/blob/master/gl3w_gen.py .. _glcorearb.h: https://www.opengl.org/registry/api/GL/glcorearb.h .. _OpenGL: http://www.opengl.org/ .. _Khronos: http://www.khronos.org/ .. _SGI: http://www.sgi.com/ ================================================ FILE: samples/gl3w/UNLICENSE ================================================ This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: samples/gl3w/gl3w_gen.py ================================================ #!/usr/bin/env python # This file is part of gl3w, hosted at https://github.com/skaslev/gl3w # # This is free and unencumbered software released into the public domain. # # Anyone is free to copy, modify, publish, use, compile, sell, or # distribute this software, either in source code form or as a compiled # binary, for any purpose, commercial or non-commercial, and by any # means. # # In jurisdictions that recognize copyright laws, the author or authors # of this software dedicate any and all copyright interest in the # software to the public domain. We make this dedication for the benefit # of the public at large and to the detriment of our heirs and # successors. We intend this dedication to be an overt act of # relinquishment in perpetuity of all present and future rights to this # software under copyright law. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # Allow Python 2.6+ to use the print() function from __future__ import print_function import re import os # Try to import Python 3 library urllib.request # and if it fails, fall back to Python 2 urllib2 try: import urllib.request as urllib2 except ImportError: import urllib2 # UNLICENSE copyright header UNLICENSE = br'''/* This file was generated with gl3w_gen.py, part of gl3w (hosted at https://github.com/skaslev/gl3w) This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ ''' # Create directories if not os.path.exists('include/GL'): os.makedirs('include/GL') if not os.path.exists('src'): os.makedirs('src') # Download glcorearb.h if not os.path.exists('include/GL/glcorearb.h'): print('Downloading glcorearb.h to include/GL...') web = urllib2.urlopen('https://www.opengl.org/registry/api/GL/glcorearb.h') with open('include/GL/glcorearb.h', 'wb') as f: f.writelines(web.readlines()) else: print('Reusing glcorearb.h from include/GL...') # Parse function names from glcorearb.h print('Parsing glcorearb.h header...') procs = [] p = re.compile(r'GLAPI.*APIENTRY\s+(\w+)') with open('include/GL/glcorearb.h', 'r') as f: for line in f: m = p.match(line) if m: procs.append(m.group(1)) procs.sort() def proc_t(proc): return { 'p': proc, 'p_s': 'gl3w' + proc[2:], 'p_t': 'PFN' + proc.upper() + 'PROC' } # Generate gl3w.h print('Generating gl3w.h in include/GL...') with open('include/GL/gl3w.h', 'wb') as f: f.write(UNLICENSE) f.write(br'''#ifndef __gl3w_h_ #define __gl3w_h_ #include #ifndef __gl_h_ #define __gl_h_ #endif typedef void (*GL3WglProc)(void); /* gl3w API: */ int gl3wInit(void); void gl3wShutdown(void); int gl3wIsSupported(int major, int minor); GL3WglProc gl3wGetProcAddress(const char *proc); /* OpenGL functions: */ ''') for proc in procs: f.write('extern {0[p_t]: <52} {0[p_s]};\n'.format(proc_t(proc)).encode("utf-8")) f.write(b'\n') for proc in procs: f.write('#define {0[p]: <51} {0[p_s]}\n'.format(proc_t(proc)).encode("utf-8")) f.write(br''' #endif // __gl3w_h_ ''') # Generate gl3w.cpp print('Generating gl3w.cpp in src...') with open('src/gl3w.cpp', 'wb') as f: f.write(UNLICENSE) f.write(br'''#include /* --------------------------------------------------------------------------------------------- */ #ifdef _WIN32 /* ------------------------------------ * Windows * ------------------------------------ */ #define WIN32_LEAN_AND_MEAN 1 #include static HMODULE gl3w_libgl = NULL; static int gl3w_open_libgl(void) { if (!gl3w_libgl) { gl3w_libgl = LoadLibraryA("opengl32.dll"); } return gl3w_libgl != NULL; } static void gl3w_close_libgl(void) { if (gl3w_libgl) { FreeLibrary(gl3w_libgl); gl3w_libgl = NULL; } } static GL3WglProc gl3w_fn(const char *proc) { GL3WglProc res; res = (GL3WglProc) wglGetProcAddress(proc); if (!res) { res = (GL3WglProc) GetProcAddress(gl3w_libgl, proc); } return res; } #elif defined(__APPLE__) || defined(__APPLE_CC__) /* ------------------------------------ * Mac OS * ------------------------------------ */ #include static CFBundleRef gl3w_cfBundle = NULL; static CFURLRef gl3w_cfBundleURL = NULL; static int gl3w_open_libgl(void) { if (gl3w_cfBundle) { return 1; /* Already init */ } gl3w_cfBundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true); if (!gl3w_cfBundleURL) { return 0; } gl3w_cfBundle = CFBundleCreate(kCFAllocatorDefault, gl3w_cfBundleURL); if (!gl3w_cfBundle) { CFRelease(gl3w_cfBundleURL); return 0; } return 1; } static void gl3w_close_libgl(void) { if (gl3w_cfBundle) { CFRelease(gl3w_cfBundle); gl3w_cfBundle = NULL; } if (gl3w_cfBundleURL) { CFRelease(gl3w_cfBundleURL); gl3w_cfBundleURL = NULL; } } static GL3WglProc gl3w_fn(const char *proc) { GL3WglProc res; CFStringRef procName; procName = CFStringCreateWithCString(kCFAllocatorDefault, proc, kCFStringEncodingASCII); res = (GL3WglProc) CFBundleGetFunctionPointerForName(gl3w_cfBundle, procName); CFRelease(procName); return res; } #else /* ------------------------------------ * GLX * ------------------------------------ */ #include #include static void *gl3w_libgl = NULL; static int gl3w_open_libgl(void) { if (!gl3w_libgl) { gl3w_libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); } return gl3w_libgl != NULL; } static void gl3w_close_libgl(void) { if (gl3w_libgl) { dlclose(gl3w_libgl); gl3w_libgl = NULL; } } static GL3WglProc gl3w_fn(const char *proc) { GL3WglProc res; res = (GL3WglProc) glXGetProcAddress((const GLubyte *) proc); if (!res) { res = (GL3WglProc) dlsym(gl3w_libgl, proc); } return res; } #endif /* ------------------------------------ * GL3W API * ------------------------------------ */ static struct { int major, minor; } gl3w_version; static void gl3w_load_all_functions(void); static int gl3w_parse_version(void) { if (!glGetIntegerv) { return 0; } glGetIntegerv(GL_MAJOR_VERSION, &gl3w_version.major); glGetIntegerv(GL_MINOR_VERSION, &gl3w_version.minor); if (gl3w_version.major < 3) { return 0; } return 1; } int gl3wInit(void) { if (!gl3w_open_libgl()) { return 0; } gl3w_load_all_functions(); return gl3w_parse_version(); } void gl3wShutdown(void) { gl3w_close_libgl(); } int gl3wIsSupported(int major, int minor) { if (major < 3) { return 0; } if (gl3w_version.major == major) { return gl3w_version.minor >= minor; } return gl3w_version.major >= major; } GL3WglProc gl3wGetProcAddress(const char *proc) { if (!proc) { return NULL; } return gl3w_fn(proc); } /* --------------------------------------------------------------------------------------------- */ ''') for proc in procs: f.write('{0[p_t]: <52} {0[p_s]};\n'.format(proc_t(proc)).encode("utf-8")) f.write(br''' /* --------------------------------------------------------------------------------------------- */ static void gl3w_load_all_functions(void) { ''') for proc in procs: f.write('\t{0[p_s]: <47} = ( {0[p_t]: <52} ) gl3w_fn("{0[p]}");\n'.format(proc_t(proc)).encode("utf-8")) f.write(b'}\n') ================================================ FILE: samples/gl3w/include/GL/gl3w.h ================================================ /* This file was generated with gl3w_gen.py, part of gl3w (hosted at https://github.com/skaslev/gl3w) This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef __gl3w_h_ #define __gl3w_h_ #include #ifndef __gl_h_ #define __gl_h_ #endif typedef void (*GL3WglProc)(void); /* gl3w API: */ int gl3wInit(void); void gl3wShutdown(void); int gl3wIsSupported(int major, int minor); GL3WglProc gl3wGetProcAddress(const char *proc); /* OpenGL functions: */ extern PFNGLACTIVESHADERPROGRAMPROC gl3wActiveShaderProgram; extern PFNGLACTIVETEXTUREPROC gl3wActiveTexture; extern PFNGLATTACHSHADERPROC gl3wAttachShader; extern PFNGLBEGINCONDITIONALRENDERPROC gl3wBeginConditionalRender; extern PFNGLBEGINQUERYPROC gl3wBeginQuery; extern PFNGLBEGINQUERYINDEXEDPROC gl3wBeginQueryIndexed; extern PFNGLBEGINTRANSFORMFEEDBACKPROC gl3wBeginTransformFeedback; extern PFNGLBINDATTRIBLOCATIONPROC gl3wBindAttribLocation; extern PFNGLBINDBUFFERPROC gl3wBindBuffer; extern PFNGLBINDBUFFERBASEPROC gl3wBindBufferBase; extern PFNGLBINDBUFFERRANGEPROC gl3wBindBufferRange; extern PFNGLBINDBUFFERSBASEPROC gl3wBindBuffersBase; extern PFNGLBINDBUFFERSRANGEPROC gl3wBindBuffersRange; extern PFNGLBINDFRAGDATALOCATIONPROC gl3wBindFragDataLocation; extern PFNGLBINDFRAGDATALOCATIONINDEXEDPROC gl3wBindFragDataLocationIndexed; extern PFNGLBINDFRAMEBUFFERPROC gl3wBindFramebuffer; extern PFNGLBINDIMAGETEXTUREPROC gl3wBindImageTexture; extern PFNGLBINDIMAGETEXTURESPROC gl3wBindImageTextures; extern PFNGLBINDPROGRAMPIPELINEPROC gl3wBindProgramPipeline; extern PFNGLBINDRENDERBUFFERPROC gl3wBindRenderbuffer; extern PFNGLBINDSAMPLERPROC gl3wBindSampler; extern PFNGLBINDSAMPLERSPROC gl3wBindSamplers; extern PFNGLBINDTEXTUREPROC gl3wBindTexture; extern PFNGLBINDTEXTUREUNITPROC gl3wBindTextureUnit; extern PFNGLBINDTEXTURESPROC gl3wBindTextures; extern PFNGLBINDTRANSFORMFEEDBACKPROC gl3wBindTransformFeedback; extern PFNGLBINDVERTEXARRAYPROC gl3wBindVertexArray; extern PFNGLBINDVERTEXBUFFERPROC gl3wBindVertexBuffer; extern PFNGLBINDVERTEXBUFFERSPROC gl3wBindVertexBuffers; extern PFNGLBLENDCOLORPROC gl3wBlendColor; extern PFNGLBLENDEQUATIONPROC gl3wBlendEquation; extern PFNGLBLENDEQUATIONSEPARATEPROC gl3wBlendEquationSeparate; extern PFNGLBLENDEQUATIONSEPARATEIPROC gl3wBlendEquationSeparatei; extern PFNGLBLENDEQUATIONSEPARATEIARBPROC gl3wBlendEquationSeparateiARB; extern PFNGLBLENDEQUATIONIPROC gl3wBlendEquationi; extern PFNGLBLENDEQUATIONIARBPROC gl3wBlendEquationiARB; extern PFNGLBLENDFUNCPROC gl3wBlendFunc; extern PFNGLBLENDFUNCSEPARATEPROC gl3wBlendFuncSeparate; extern PFNGLBLENDFUNCSEPARATEIPROC gl3wBlendFuncSeparatei; extern PFNGLBLENDFUNCSEPARATEIARBPROC gl3wBlendFuncSeparateiARB; extern PFNGLBLENDFUNCIPROC gl3wBlendFunci; extern PFNGLBLENDFUNCIARBPROC gl3wBlendFunciARB; extern PFNGLBLITFRAMEBUFFERPROC gl3wBlitFramebuffer; extern PFNGLBLITNAMEDFRAMEBUFFERPROC gl3wBlitNamedFramebuffer; extern PFNGLBUFFERDATAPROC gl3wBufferData; extern PFNGLBUFFERPAGECOMMITMENTARBPROC gl3wBufferPageCommitmentARB; extern PFNGLBUFFERSTORAGEPROC gl3wBufferStorage; extern PFNGLBUFFERSUBDATAPROC gl3wBufferSubData; extern PFNGLCHECKFRAMEBUFFERSTATUSPROC gl3wCheckFramebufferStatus; extern PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC gl3wCheckNamedFramebufferStatus; extern PFNGLCLAMPCOLORPROC gl3wClampColor; extern PFNGLCLEARPROC gl3wClear; extern PFNGLCLEARBUFFERDATAPROC gl3wClearBufferData; extern PFNGLCLEARBUFFERSUBDATAPROC gl3wClearBufferSubData; extern PFNGLCLEARBUFFERFIPROC gl3wClearBufferfi; extern PFNGLCLEARBUFFERFVPROC gl3wClearBufferfv; extern PFNGLCLEARBUFFERIVPROC gl3wClearBufferiv; extern PFNGLCLEARBUFFERUIVPROC gl3wClearBufferuiv; extern PFNGLCLEARCOLORPROC gl3wClearColor; extern PFNGLCLEARDEPTHPROC gl3wClearDepth; extern PFNGLCLEARDEPTHFPROC gl3wClearDepthf; extern PFNGLCLEARNAMEDBUFFERDATAPROC gl3wClearNamedBufferData; extern PFNGLCLEARNAMEDBUFFERSUBDATAPROC gl3wClearNamedBufferSubData; extern PFNGLCLEARNAMEDFRAMEBUFFERFIPROC gl3wClearNamedFramebufferfi; extern PFNGLCLEARNAMEDFRAMEBUFFERFVPROC gl3wClearNamedFramebufferfv; extern PFNGLCLEARNAMEDFRAMEBUFFERIVPROC gl3wClearNamedFramebufferiv; extern PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC gl3wClearNamedFramebufferuiv; extern PFNGLCLEARSTENCILPROC gl3wClearStencil; extern PFNGLCLEARTEXIMAGEPROC gl3wClearTexImage; extern PFNGLCLEARTEXSUBIMAGEPROC gl3wClearTexSubImage; extern PFNGLCLIENTWAITSYNCPROC gl3wClientWaitSync; extern PFNGLCLIPCONTROLPROC gl3wClipControl; extern PFNGLCOLORMASKPROC gl3wColorMask; extern PFNGLCOLORMASKIPROC gl3wColorMaski; extern PFNGLCOMPILESHADERPROC gl3wCompileShader; extern PFNGLCOMPILESHADERINCLUDEARBPROC gl3wCompileShaderIncludeARB; extern PFNGLCOMPRESSEDTEXIMAGE1DPROC gl3wCompressedTexImage1D; extern PFNGLCOMPRESSEDTEXIMAGE2DPROC gl3wCompressedTexImage2D; extern PFNGLCOMPRESSEDTEXIMAGE3DPROC gl3wCompressedTexImage3D; extern PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC gl3wCompressedTexSubImage1D; extern PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC gl3wCompressedTexSubImage2D; extern PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC gl3wCompressedTexSubImage3D; extern PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC gl3wCompressedTextureSubImage1D; extern PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC gl3wCompressedTextureSubImage2D; extern PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC gl3wCompressedTextureSubImage3D; extern PFNGLCOPYBUFFERSUBDATAPROC gl3wCopyBufferSubData; extern PFNGLCOPYIMAGESUBDATAPROC gl3wCopyImageSubData; extern PFNGLCOPYNAMEDBUFFERSUBDATAPROC gl3wCopyNamedBufferSubData; extern PFNGLCOPYTEXIMAGE1DPROC gl3wCopyTexImage1D; extern PFNGLCOPYTEXIMAGE2DPROC gl3wCopyTexImage2D; extern PFNGLCOPYTEXSUBIMAGE1DPROC gl3wCopyTexSubImage1D; extern PFNGLCOPYTEXSUBIMAGE2DPROC gl3wCopyTexSubImage2D; extern PFNGLCOPYTEXSUBIMAGE3DPROC gl3wCopyTexSubImage3D; extern PFNGLCOPYTEXTURESUBIMAGE1DPROC gl3wCopyTextureSubImage1D; extern PFNGLCOPYTEXTURESUBIMAGE2DPROC gl3wCopyTextureSubImage2D; extern PFNGLCOPYTEXTURESUBIMAGE3DPROC gl3wCopyTextureSubImage3D; extern PFNGLCREATEBUFFERSPROC gl3wCreateBuffers; extern PFNGLCREATEFRAMEBUFFERSPROC gl3wCreateFramebuffers; extern PFNGLCREATEPROGRAMPROC gl3wCreateProgram; extern PFNGLCREATEPROGRAMPIPELINESPROC gl3wCreateProgramPipelines; extern PFNGLCREATEQUERIESPROC gl3wCreateQueries; extern PFNGLCREATERENDERBUFFERSPROC gl3wCreateRenderbuffers; extern PFNGLCREATESAMPLERSPROC gl3wCreateSamplers; extern PFNGLCREATESHADERPROC gl3wCreateShader; extern PFNGLCREATESHADERPROGRAMVPROC gl3wCreateShaderProgramv; extern PFNGLCREATESYNCFROMCLEVENTARBPROC gl3wCreateSyncFromCLeventARB; extern PFNGLCREATETEXTURESPROC gl3wCreateTextures; extern PFNGLCREATETRANSFORMFEEDBACKSPROC gl3wCreateTransformFeedbacks; extern PFNGLCREATEVERTEXARRAYSPROC gl3wCreateVertexArrays; extern PFNGLCULLFACEPROC gl3wCullFace; extern PFNGLDEBUGMESSAGECALLBACKPROC gl3wDebugMessageCallback; extern PFNGLDEBUGMESSAGECALLBACKARBPROC gl3wDebugMessageCallbackARB; extern PFNGLDEBUGMESSAGECONTROLPROC gl3wDebugMessageControl; extern PFNGLDEBUGMESSAGECONTROLARBPROC gl3wDebugMessageControlARB; extern PFNGLDEBUGMESSAGEINSERTPROC gl3wDebugMessageInsert; extern PFNGLDEBUGMESSAGEINSERTARBPROC gl3wDebugMessageInsertARB; extern PFNGLDELETEBUFFERSPROC gl3wDeleteBuffers; extern PFNGLDELETEFRAMEBUFFERSPROC gl3wDeleteFramebuffers; extern PFNGLDELETENAMEDSTRINGARBPROC gl3wDeleteNamedStringARB; extern PFNGLDELETEPROGRAMPROC gl3wDeleteProgram; extern PFNGLDELETEPROGRAMPIPELINESPROC gl3wDeleteProgramPipelines; extern PFNGLDELETEQUERIESPROC gl3wDeleteQueries; extern PFNGLDELETERENDERBUFFERSPROC gl3wDeleteRenderbuffers; extern PFNGLDELETESAMPLERSPROC gl3wDeleteSamplers; extern PFNGLDELETESHADERPROC gl3wDeleteShader; extern PFNGLDELETESYNCPROC gl3wDeleteSync; extern PFNGLDELETETEXTURESPROC gl3wDeleteTextures; extern PFNGLDELETETRANSFORMFEEDBACKSPROC gl3wDeleteTransformFeedbacks; extern PFNGLDELETEVERTEXARRAYSPROC gl3wDeleteVertexArrays; extern PFNGLDEPTHFUNCPROC gl3wDepthFunc; extern PFNGLDEPTHMASKPROC gl3wDepthMask; extern PFNGLDEPTHRANGEPROC gl3wDepthRange; extern PFNGLDEPTHRANGEARRAYVPROC gl3wDepthRangeArrayv; extern PFNGLDEPTHRANGEINDEXEDPROC gl3wDepthRangeIndexed; extern PFNGLDEPTHRANGEFPROC gl3wDepthRangef; extern PFNGLDETACHSHADERPROC gl3wDetachShader; extern PFNGLDISABLEPROC gl3wDisable; extern PFNGLDISABLEVERTEXARRAYATTRIBPROC gl3wDisableVertexArrayAttrib; extern PFNGLDISABLEVERTEXATTRIBARRAYPROC gl3wDisableVertexAttribArray; extern PFNGLDISABLEIPROC gl3wDisablei; extern PFNGLDISPATCHCOMPUTEPROC gl3wDispatchCompute; extern PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC gl3wDispatchComputeGroupSizeARB; extern PFNGLDISPATCHCOMPUTEINDIRECTPROC gl3wDispatchComputeIndirect; extern PFNGLDRAWARRAYSPROC gl3wDrawArrays; extern PFNGLDRAWARRAYSINDIRECTPROC gl3wDrawArraysIndirect; extern PFNGLDRAWARRAYSINSTANCEDPROC gl3wDrawArraysInstanced; extern PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC gl3wDrawArraysInstancedBaseInstance; extern PFNGLDRAWBUFFERPROC gl3wDrawBuffer; extern PFNGLDRAWBUFFERSPROC gl3wDrawBuffers; extern PFNGLDRAWELEMENTSPROC gl3wDrawElements; extern PFNGLDRAWELEMENTSBASEVERTEXPROC gl3wDrawElementsBaseVertex; extern PFNGLDRAWELEMENTSINDIRECTPROC gl3wDrawElementsIndirect; extern PFNGLDRAWELEMENTSINSTANCEDPROC gl3wDrawElementsInstanced; extern PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC gl3wDrawElementsInstancedBaseInstance; extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC gl3wDrawElementsInstancedBaseVertex; extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC gl3wDrawElementsInstancedBaseVertexBaseInstance; extern PFNGLDRAWRANGEELEMENTSPROC gl3wDrawRangeElements; extern PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC gl3wDrawRangeElementsBaseVertex; extern PFNGLDRAWTRANSFORMFEEDBACKPROC gl3wDrawTransformFeedback; extern PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC gl3wDrawTransformFeedbackInstanced; extern PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC gl3wDrawTransformFeedbackStream; extern PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC gl3wDrawTransformFeedbackStreamInstanced; extern PFNGLENABLEPROC gl3wEnable; extern PFNGLENABLEVERTEXARRAYATTRIBPROC gl3wEnableVertexArrayAttrib; extern PFNGLENABLEVERTEXATTRIBARRAYPROC gl3wEnableVertexAttribArray; extern PFNGLENABLEIPROC gl3wEnablei; extern PFNGLENDCONDITIONALRENDERPROC gl3wEndConditionalRender; extern PFNGLENDQUERYPROC gl3wEndQuery; extern PFNGLENDQUERYINDEXEDPROC gl3wEndQueryIndexed; extern PFNGLENDTRANSFORMFEEDBACKPROC gl3wEndTransformFeedback; extern PFNGLFENCESYNCPROC gl3wFenceSync; extern PFNGLFINISHPROC gl3wFinish; extern PFNGLFLUSHPROC gl3wFlush; extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC gl3wFlushMappedBufferRange; extern PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC gl3wFlushMappedNamedBufferRange; extern PFNGLFRAMEBUFFERPARAMETERIPROC gl3wFramebufferParameteri; extern PFNGLFRAMEBUFFERRENDERBUFFERPROC gl3wFramebufferRenderbuffer; extern PFNGLFRAMEBUFFERTEXTUREPROC gl3wFramebufferTexture; extern PFNGLFRAMEBUFFERTEXTURE1DPROC gl3wFramebufferTexture1D; extern PFNGLFRAMEBUFFERTEXTURE2DPROC gl3wFramebufferTexture2D; extern PFNGLFRAMEBUFFERTEXTURE3DPROC gl3wFramebufferTexture3D; extern PFNGLFRAMEBUFFERTEXTURELAYERPROC gl3wFramebufferTextureLayer; extern PFNGLFRONTFACEPROC gl3wFrontFace; extern PFNGLGENBUFFERSPROC gl3wGenBuffers; extern PFNGLGENFRAMEBUFFERSPROC gl3wGenFramebuffers; extern PFNGLGENPROGRAMPIPELINESPROC gl3wGenProgramPipelines; extern PFNGLGENQUERIESPROC gl3wGenQueries; extern PFNGLGENRENDERBUFFERSPROC gl3wGenRenderbuffers; extern PFNGLGENSAMPLERSPROC gl3wGenSamplers; extern PFNGLGENTEXTURESPROC gl3wGenTextures; extern PFNGLGENTRANSFORMFEEDBACKSPROC gl3wGenTransformFeedbacks; extern PFNGLGENVERTEXARRAYSPROC gl3wGenVertexArrays; extern PFNGLGENERATEMIPMAPPROC gl3wGenerateMipmap; extern PFNGLGENERATETEXTUREMIPMAPPROC gl3wGenerateTextureMipmap; extern PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC gl3wGetActiveAtomicCounterBufferiv; extern PFNGLGETACTIVEATTRIBPROC gl3wGetActiveAttrib; extern PFNGLGETACTIVESUBROUTINENAMEPROC gl3wGetActiveSubroutineName; extern PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC gl3wGetActiveSubroutineUniformName; extern PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC gl3wGetActiveSubroutineUniformiv; extern PFNGLGETACTIVEUNIFORMPROC gl3wGetActiveUniform; extern PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC gl3wGetActiveUniformBlockName; extern PFNGLGETACTIVEUNIFORMBLOCKIVPROC gl3wGetActiveUniformBlockiv; extern PFNGLGETACTIVEUNIFORMNAMEPROC gl3wGetActiveUniformName; extern PFNGLGETACTIVEUNIFORMSIVPROC gl3wGetActiveUniformsiv; extern PFNGLGETATTACHEDSHADERSPROC gl3wGetAttachedShaders; extern PFNGLGETATTRIBLOCATIONPROC gl3wGetAttribLocation; extern PFNGLGETBOOLEANI_VPROC gl3wGetBooleani_v; extern PFNGLGETBOOLEANVPROC gl3wGetBooleanv; extern PFNGLGETBUFFERPARAMETERI64VPROC gl3wGetBufferParameteri64v; extern PFNGLGETBUFFERPARAMETERIVPROC gl3wGetBufferParameteriv; extern PFNGLGETBUFFERPOINTERVPROC gl3wGetBufferPointerv; extern PFNGLGETBUFFERSUBDATAPROC gl3wGetBufferSubData; extern PFNGLGETCOMPRESSEDTEXIMAGEPROC gl3wGetCompressedTexImage; extern PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC gl3wGetCompressedTextureImage; extern PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC gl3wGetCompressedTextureSubImage; extern PFNGLGETDEBUGMESSAGELOGPROC gl3wGetDebugMessageLog; extern PFNGLGETDEBUGMESSAGELOGARBPROC gl3wGetDebugMessageLogARB; extern PFNGLGETDOUBLEI_VPROC gl3wGetDoublei_v; extern PFNGLGETDOUBLEVPROC gl3wGetDoublev; extern PFNGLGETERRORPROC gl3wGetError; extern PFNGLGETFLOATI_VPROC gl3wGetFloati_v; extern PFNGLGETFLOATVPROC gl3wGetFloatv; extern PFNGLGETFRAGDATAINDEXPROC gl3wGetFragDataIndex; extern PFNGLGETFRAGDATALOCATIONPROC gl3wGetFragDataLocation; extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC gl3wGetFramebufferAttachmentParameteriv; extern PFNGLGETFRAMEBUFFERPARAMETERIVPROC gl3wGetFramebufferParameteriv; extern PFNGLGETGRAPHICSRESETSTATUSPROC gl3wGetGraphicsResetStatus; extern PFNGLGETGRAPHICSRESETSTATUSARBPROC gl3wGetGraphicsResetStatusARB; extern PFNGLGETIMAGEHANDLEARBPROC gl3wGetImageHandleARB; extern PFNGLGETINTEGER64I_VPROC gl3wGetInteger64i_v; extern PFNGLGETINTEGER64VPROC gl3wGetInteger64v; extern PFNGLGETINTEGERI_VPROC gl3wGetIntegeri_v; extern PFNGLGETINTEGERVPROC gl3wGetIntegerv; extern PFNGLGETINTERNALFORMATI64VPROC gl3wGetInternalformati64v; extern PFNGLGETINTERNALFORMATIVPROC gl3wGetInternalformativ; extern PFNGLGETMULTISAMPLEFVPROC gl3wGetMultisamplefv; extern PFNGLGETNAMEDBUFFERPARAMETERI64VPROC gl3wGetNamedBufferParameteri64v; extern PFNGLGETNAMEDBUFFERPARAMETERIVPROC gl3wGetNamedBufferParameteriv; extern PFNGLGETNAMEDBUFFERPOINTERVPROC gl3wGetNamedBufferPointerv; extern PFNGLGETNAMEDBUFFERSUBDATAPROC gl3wGetNamedBufferSubData; extern PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC gl3wGetNamedFramebufferAttachmentParameteriv; extern PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC gl3wGetNamedFramebufferParameteriv; extern PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC gl3wGetNamedRenderbufferParameteriv; extern PFNGLGETNAMEDSTRINGARBPROC gl3wGetNamedStringARB; extern PFNGLGETNAMEDSTRINGIVARBPROC gl3wGetNamedStringivARB; extern PFNGLGETOBJECTLABELPROC gl3wGetObjectLabel; extern PFNGLGETOBJECTPTRLABELPROC gl3wGetObjectPtrLabel; extern PFNGLGETPOINTERVPROC gl3wGetPointerv; extern PFNGLGETPROGRAMBINARYPROC gl3wGetProgramBinary; extern PFNGLGETPROGRAMINFOLOGPROC gl3wGetProgramInfoLog; extern PFNGLGETPROGRAMINTERFACEIVPROC gl3wGetProgramInterfaceiv; extern PFNGLGETPROGRAMPIPELINEINFOLOGPROC gl3wGetProgramPipelineInfoLog; extern PFNGLGETPROGRAMPIPELINEIVPROC gl3wGetProgramPipelineiv; extern PFNGLGETPROGRAMRESOURCEINDEXPROC gl3wGetProgramResourceIndex; extern PFNGLGETPROGRAMRESOURCELOCATIONPROC gl3wGetProgramResourceLocation; extern PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC gl3wGetProgramResourceLocationIndex; extern PFNGLGETPROGRAMRESOURCENAMEPROC gl3wGetProgramResourceName; extern PFNGLGETPROGRAMRESOURCEIVPROC gl3wGetProgramResourceiv; extern PFNGLGETPROGRAMSTAGEIVPROC gl3wGetProgramStageiv; extern PFNGLGETPROGRAMIVPROC gl3wGetProgramiv; extern PFNGLGETQUERYBUFFEROBJECTI64VPROC gl3wGetQueryBufferObjecti64v; extern PFNGLGETQUERYBUFFEROBJECTIVPROC gl3wGetQueryBufferObjectiv; extern PFNGLGETQUERYBUFFEROBJECTUI64VPROC gl3wGetQueryBufferObjectui64v; extern PFNGLGETQUERYBUFFEROBJECTUIVPROC gl3wGetQueryBufferObjectuiv; extern PFNGLGETQUERYINDEXEDIVPROC gl3wGetQueryIndexediv; extern PFNGLGETQUERYOBJECTI64VPROC gl3wGetQueryObjecti64v; extern PFNGLGETQUERYOBJECTIVPROC gl3wGetQueryObjectiv; extern PFNGLGETQUERYOBJECTUI64VPROC gl3wGetQueryObjectui64v; extern PFNGLGETQUERYOBJECTUIVPROC gl3wGetQueryObjectuiv; extern PFNGLGETQUERYIVPROC gl3wGetQueryiv; extern PFNGLGETRENDERBUFFERPARAMETERIVPROC gl3wGetRenderbufferParameteriv; extern PFNGLGETSAMPLERPARAMETERIIVPROC gl3wGetSamplerParameterIiv; extern PFNGLGETSAMPLERPARAMETERIUIVPROC gl3wGetSamplerParameterIuiv; extern PFNGLGETSAMPLERPARAMETERFVPROC gl3wGetSamplerParameterfv; extern PFNGLGETSAMPLERPARAMETERIVPROC gl3wGetSamplerParameteriv; extern PFNGLGETSHADERINFOLOGPROC gl3wGetShaderInfoLog; extern PFNGLGETSHADERPRECISIONFORMATPROC gl3wGetShaderPrecisionFormat; extern PFNGLGETSHADERSOURCEPROC gl3wGetShaderSource; extern PFNGLGETSHADERIVPROC gl3wGetShaderiv; extern PFNGLGETSTRINGPROC gl3wGetString; extern PFNGLGETSTRINGIPROC gl3wGetStringi; extern PFNGLGETSUBROUTINEINDEXPROC gl3wGetSubroutineIndex; extern PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC gl3wGetSubroutineUniformLocation; extern PFNGLGETSYNCIVPROC gl3wGetSynciv; extern PFNGLGETTEXIMAGEPROC gl3wGetTexImage; extern PFNGLGETTEXLEVELPARAMETERFVPROC gl3wGetTexLevelParameterfv; extern PFNGLGETTEXLEVELPARAMETERIVPROC gl3wGetTexLevelParameteriv; extern PFNGLGETTEXPARAMETERIIVPROC gl3wGetTexParameterIiv; extern PFNGLGETTEXPARAMETERIUIVPROC gl3wGetTexParameterIuiv; extern PFNGLGETTEXPARAMETERFVPROC gl3wGetTexParameterfv; extern PFNGLGETTEXPARAMETERIVPROC gl3wGetTexParameteriv; extern PFNGLGETTEXTUREHANDLEARBPROC gl3wGetTextureHandleARB; extern PFNGLGETTEXTUREIMAGEPROC gl3wGetTextureImage; extern PFNGLGETTEXTURELEVELPARAMETERFVPROC gl3wGetTextureLevelParameterfv; extern PFNGLGETTEXTURELEVELPARAMETERIVPROC gl3wGetTextureLevelParameteriv; extern PFNGLGETTEXTUREPARAMETERIIVPROC gl3wGetTextureParameterIiv; extern PFNGLGETTEXTUREPARAMETERIUIVPROC gl3wGetTextureParameterIuiv; extern PFNGLGETTEXTUREPARAMETERFVPROC gl3wGetTextureParameterfv; extern PFNGLGETTEXTUREPARAMETERIVPROC gl3wGetTextureParameteriv; extern PFNGLGETTEXTURESAMPLERHANDLEARBPROC gl3wGetTextureSamplerHandleARB; extern PFNGLGETTEXTURESUBIMAGEPROC gl3wGetTextureSubImage; extern PFNGLGETTRANSFORMFEEDBACKVARYINGPROC gl3wGetTransformFeedbackVarying; extern PFNGLGETTRANSFORMFEEDBACKI64_VPROC gl3wGetTransformFeedbacki64_v; extern PFNGLGETTRANSFORMFEEDBACKI_VPROC gl3wGetTransformFeedbacki_v; extern PFNGLGETTRANSFORMFEEDBACKIVPROC gl3wGetTransformFeedbackiv; extern PFNGLGETUNIFORMBLOCKINDEXPROC gl3wGetUniformBlockIndex; extern PFNGLGETUNIFORMINDICESPROC gl3wGetUniformIndices; extern PFNGLGETUNIFORMLOCATIONPROC gl3wGetUniformLocation; extern PFNGLGETUNIFORMSUBROUTINEUIVPROC gl3wGetUniformSubroutineuiv; extern PFNGLGETUNIFORMDVPROC gl3wGetUniformdv; extern PFNGLGETUNIFORMFVPROC gl3wGetUniformfv; extern PFNGLGETUNIFORMIVPROC gl3wGetUniformiv; extern PFNGLGETUNIFORMUIVPROC gl3wGetUniformuiv; extern PFNGLGETVERTEXARRAYINDEXED64IVPROC gl3wGetVertexArrayIndexed64iv; extern PFNGLGETVERTEXARRAYINDEXEDIVPROC gl3wGetVertexArrayIndexediv; extern PFNGLGETVERTEXARRAYIVPROC gl3wGetVertexArrayiv; extern PFNGLGETVERTEXATTRIBIIVPROC gl3wGetVertexAttribIiv; extern PFNGLGETVERTEXATTRIBIUIVPROC gl3wGetVertexAttribIuiv; extern PFNGLGETVERTEXATTRIBLDVPROC gl3wGetVertexAttribLdv; extern PFNGLGETVERTEXATTRIBLUI64VARBPROC gl3wGetVertexAttribLui64vARB; extern PFNGLGETVERTEXATTRIBPOINTERVPROC gl3wGetVertexAttribPointerv; extern PFNGLGETVERTEXATTRIBDVPROC gl3wGetVertexAttribdv; extern PFNGLGETVERTEXATTRIBFVPROC gl3wGetVertexAttribfv; extern PFNGLGETVERTEXATTRIBIVPROC gl3wGetVertexAttribiv; extern PFNGLGETNCOMPRESSEDTEXIMAGEPROC gl3wGetnCompressedTexImage; extern PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC gl3wGetnCompressedTexImageARB; extern PFNGLGETNTEXIMAGEPROC gl3wGetnTexImage; extern PFNGLGETNTEXIMAGEARBPROC gl3wGetnTexImageARB; extern PFNGLGETNUNIFORMDVPROC gl3wGetnUniformdv; extern PFNGLGETNUNIFORMDVARBPROC gl3wGetnUniformdvARB; extern PFNGLGETNUNIFORMFVPROC gl3wGetnUniformfv; extern PFNGLGETNUNIFORMFVARBPROC gl3wGetnUniformfvARB; extern PFNGLGETNUNIFORMIVPROC gl3wGetnUniformiv; extern PFNGLGETNUNIFORMIVARBPROC gl3wGetnUniformivARB; extern PFNGLGETNUNIFORMUIVPROC gl3wGetnUniformuiv; extern PFNGLGETNUNIFORMUIVARBPROC gl3wGetnUniformuivARB; extern PFNGLHINTPROC gl3wHint; extern PFNGLINVALIDATEBUFFERDATAPROC gl3wInvalidateBufferData; extern PFNGLINVALIDATEBUFFERSUBDATAPROC gl3wInvalidateBufferSubData; extern PFNGLINVALIDATEFRAMEBUFFERPROC gl3wInvalidateFramebuffer; extern PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC gl3wInvalidateNamedFramebufferData; extern PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC gl3wInvalidateNamedFramebufferSubData; extern PFNGLINVALIDATESUBFRAMEBUFFERPROC gl3wInvalidateSubFramebuffer; extern PFNGLINVALIDATETEXIMAGEPROC gl3wInvalidateTexImage; extern PFNGLINVALIDATETEXSUBIMAGEPROC gl3wInvalidateTexSubImage; extern PFNGLISBUFFERPROC gl3wIsBuffer; extern PFNGLISENABLEDPROC gl3wIsEnabled; extern PFNGLISENABLEDIPROC gl3wIsEnabledi; extern PFNGLISFRAMEBUFFERPROC gl3wIsFramebuffer; extern PFNGLISIMAGEHANDLERESIDENTARBPROC gl3wIsImageHandleResidentARB; extern PFNGLISNAMEDSTRINGARBPROC gl3wIsNamedStringARB; extern PFNGLISPROGRAMPROC gl3wIsProgram; extern PFNGLISPROGRAMPIPELINEPROC gl3wIsProgramPipeline; extern PFNGLISQUERYPROC gl3wIsQuery; extern PFNGLISRENDERBUFFERPROC gl3wIsRenderbuffer; extern PFNGLISSAMPLERPROC gl3wIsSampler; extern PFNGLISSHADERPROC gl3wIsShader; extern PFNGLISSYNCPROC gl3wIsSync; extern PFNGLISTEXTUREPROC gl3wIsTexture; extern PFNGLISTEXTUREHANDLERESIDENTARBPROC gl3wIsTextureHandleResidentARB; extern PFNGLISTRANSFORMFEEDBACKPROC gl3wIsTransformFeedback; extern PFNGLISVERTEXARRAYPROC gl3wIsVertexArray; extern PFNGLLINEWIDTHPROC gl3wLineWidth; extern PFNGLLINKPROGRAMPROC gl3wLinkProgram; extern PFNGLLOGICOPPROC gl3wLogicOp; extern PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC gl3wMakeImageHandleNonResidentARB; extern PFNGLMAKEIMAGEHANDLERESIDENTARBPROC gl3wMakeImageHandleResidentARB; extern PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC gl3wMakeTextureHandleNonResidentARB; extern PFNGLMAKETEXTUREHANDLERESIDENTARBPROC gl3wMakeTextureHandleResidentARB; extern PFNGLMAPBUFFERPROC gl3wMapBuffer; extern PFNGLMAPBUFFERRANGEPROC gl3wMapBufferRange; extern PFNGLMAPNAMEDBUFFERPROC gl3wMapNamedBuffer; extern PFNGLMAPNAMEDBUFFERRANGEPROC gl3wMapNamedBufferRange; extern PFNGLMEMORYBARRIERPROC gl3wMemoryBarrier; extern PFNGLMEMORYBARRIERBYREGIONPROC gl3wMemoryBarrierByRegion; extern PFNGLMINSAMPLESHADINGPROC gl3wMinSampleShading; extern PFNGLMINSAMPLESHADINGARBPROC gl3wMinSampleShadingARB; extern PFNGLMULTIDRAWARRAYSPROC gl3wMultiDrawArrays; extern PFNGLMULTIDRAWARRAYSINDIRECTPROC gl3wMultiDrawArraysIndirect; extern PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC gl3wMultiDrawArraysIndirectCountARB; extern PFNGLMULTIDRAWELEMENTSPROC gl3wMultiDrawElements; extern PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC gl3wMultiDrawElementsBaseVertex; extern PFNGLMULTIDRAWELEMENTSINDIRECTPROC gl3wMultiDrawElementsIndirect; extern PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC gl3wMultiDrawElementsIndirectCountARB; extern PFNGLNAMEDBUFFERDATAPROC gl3wNamedBufferData; extern PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC gl3wNamedBufferPageCommitmentARB; extern PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC gl3wNamedBufferPageCommitmentEXT; extern PFNGLNAMEDBUFFERSTORAGEPROC gl3wNamedBufferStorage; extern PFNGLNAMEDBUFFERSUBDATAPROC gl3wNamedBufferSubData; extern PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC gl3wNamedFramebufferDrawBuffer; extern PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC gl3wNamedFramebufferDrawBuffers; extern PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC gl3wNamedFramebufferParameteri; extern PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC gl3wNamedFramebufferReadBuffer; extern PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC gl3wNamedFramebufferRenderbuffer; extern PFNGLNAMEDFRAMEBUFFERTEXTUREPROC gl3wNamedFramebufferTexture; extern PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC gl3wNamedFramebufferTextureLayer; extern PFNGLNAMEDRENDERBUFFERSTORAGEPROC gl3wNamedRenderbufferStorage; extern PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC gl3wNamedRenderbufferStorageMultisample; extern PFNGLNAMEDSTRINGARBPROC gl3wNamedStringARB; extern PFNGLOBJECTLABELPROC gl3wObjectLabel; extern PFNGLOBJECTPTRLABELPROC gl3wObjectPtrLabel; extern PFNGLPATCHPARAMETERFVPROC gl3wPatchParameterfv; extern PFNGLPATCHPARAMETERIPROC gl3wPatchParameteri; extern PFNGLPAUSETRANSFORMFEEDBACKPROC gl3wPauseTransformFeedback; extern PFNGLPIXELSTOREFPROC gl3wPixelStoref; extern PFNGLPIXELSTOREIPROC gl3wPixelStorei; extern PFNGLPOINTPARAMETERFPROC gl3wPointParameterf; extern PFNGLPOINTPARAMETERFVPROC gl3wPointParameterfv; extern PFNGLPOINTPARAMETERIPROC gl3wPointParameteri; extern PFNGLPOINTPARAMETERIVPROC gl3wPointParameteriv; extern PFNGLPOINTSIZEPROC gl3wPointSize; extern PFNGLPOLYGONMODEPROC gl3wPolygonMode; extern PFNGLPOLYGONOFFSETPROC gl3wPolygonOffset; extern PFNGLPOPDEBUGGROUPPROC gl3wPopDebugGroup; extern PFNGLPRIMITIVERESTARTINDEXPROC gl3wPrimitiveRestartIndex; extern PFNGLPROGRAMBINARYPROC gl3wProgramBinary; extern PFNGLPROGRAMPARAMETERIPROC gl3wProgramParameteri; extern PFNGLPROGRAMUNIFORM1DPROC gl3wProgramUniform1d; extern PFNGLPROGRAMUNIFORM1DVPROC gl3wProgramUniform1dv; extern PFNGLPROGRAMUNIFORM1FPROC gl3wProgramUniform1f; extern PFNGLPROGRAMUNIFORM1FVPROC gl3wProgramUniform1fv; extern PFNGLPROGRAMUNIFORM1IPROC gl3wProgramUniform1i; extern PFNGLPROGRAMUNIFORM1IVPROC gl3wProgramUniform1iv; extern PFNGLPROGRAMUNIFORM1UIPROC gl3wProgramUniform1ui; extern PFNGLPROGRAMUNIFORM1UIVPROC gl3wProgramUniform1uiv; extern PFNGLPROGRAMUNIFORM2DPROC gl3wProgramUniform2d; extern PFNGLPROGRAMUNIFORM2DVPROC gl3wProgramUniform2dv; extern PFNGLPROGRAMUNIFORM2FPROC gl3wProgramUniform2f; extern PFNGLPROGRAMUNIFORM2FVPROC gl3wProgramUniform2fv; extern PFNGLPROGRAMUNIFORM2IPROC gl3wProgramUniform2i; extern PFNGLPROGRAMUNIFORM2IVPROC gl3wProgramUniform2iv; extern PFNGLPROGRAMUNIFORM2UIPROC gl3wProgramUniform2ui; extern PFNGLPROGRAMUNIFORM2UIVPROC gl3wProgramUniform2uiv; extern PFNGLPROGRAMUNIFORM3DPROC gl3wProgramUniform3d; extern PFNGLPROGRAMUNIFORM3DVPROC gl3wProgramUniform3dv; extern PFNGLPROGRAMUNIFORM3FPROC gl3wProgramUniform3f; extern PFNGLPROGRAMUNIFORM3FVPROC gl3wProgramUniform3fv; extern PFNGLPROGRAMUNIFORM3IPROC gl3wProgramUniform3i; extern PFNGLPROGRAMUNIFORM3IVPROC gl3wProgramUniform3iv; extern PFNGLPROGRAMUNIFORM3UIPROC gl3wProgramUniform3ui; extern PFNGLPROGRAMUNIFORM3UIVPROC gl3wProgramUniform3uiv; extern PFNGLPROGRAMUNIFORM4DPROC gl3wProgramUniform4d; extern PFNGLPROGRAMUNIFORM4DVPROC gl3wProgramUniform4dv; extern PFNGLPROGRAMUNIFORM4FPROC gl3wProgramUniform4f; extern PFNGLPROGRAMUNIFORM4FVPROC gl3wProgramUniform4fv; extern PFNGLPROGRAMUNIFORM4IPROC gl3wProgramUniform4i; extern PFNGLPROGRAMUNIFORM4IVPROC gl3wProgramUniform4iv; extern PFNGLPROGRAMUNIFORM4UIPROC gl3wProgramUniform4ui; extern PFNGLPROGRAMUNIFORM4UIVPROC gl3wProgramUniform4uiv; extern PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC gl3wProgramUniformHandleui64ARB; extern PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC gl3wProgramUniformHandleui64vARB; extern PFNGLPROGRAMUNIFORMMATRIX2DVPROC gl3wProgramUniformMatrix2dv; extern PFNGLPROGRAMUNIFORMMATRIX2FVPROC gl3wProgramUniformMatrix2fv; extern PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC gl3wProgramUniformMatrix2x3dv; extern PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC gl3wProgramUniformMatrix2x3fv; extern PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC gl3wProgramUniformMatrix2x4dv; extern PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC gl3wProgramUniformMatrix2x4fv; extern PFNGLPROGRAMUNIFORMMATRIX3DVPROC gl3wProgramUniformMatrix3dv; extern PFNGLPROGRAMUNIFORMMATRIX3FVPROC gl3wProgramUniformMatrix3fv; extern PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC gl3wProgramUniformMatrix3x2dv; extern PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC gl3wProgramUniformMatrix3x2fv; extern PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC gl3wProgramUniformMatrix3x4dv; extern PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC gl3wProgramUniformMatrix3x4fv; extern PFNGLPROGRAMUNIFORMMATRIX4DVPROC gl3wProgramUniformMatrix4dv; extern PFNGLPROGRAMUNIFORMMATRIX4FVPROC gl3wProgramUniformMatrix4fv; extern PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC gl3wProgramUniformMatrix4x2dv; extern PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC gl3wProgramUniformMatrix4x2fv; extern PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC gl3wProgramUniformMatrix4x3dv; extern PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC gl3wProgramUniformMatrix4x3fv; extern PFNGLPROVOKINGVERTEXPROC gl3wProvokingVertex; extern PFNGLPUSHDEBUGGROUPPROC gl3wPushDebugGroup; extern PFNGLQUERYCOUNTERPROC gl3wQueryCounter; extern PFNGLREADBUFFERPROC gl3wReadBuffer; extern PFNGLREADPIXELSPROC gl3wReadPixels; extern PFNGLREADNPIXELSPROC gl3wReadnPixels; extern PFNGLREADNPIXELSARBPROC gl3wReadnPixelsARB; extern PFNGLRELEASESHADERCOMPILERPROC gl3wReleaseShaderCompiler; extern PFNGLRENDERBUFFERSTORAGEPROC gl3wRenderbufferStorage; extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC gl3wRenderbufferStorageMultisample; extern PFNGLRESUMETRANSFORMFEEDBACKPROC gl3wResumeTransformFeedback; extern PFNGLSAMPLECOVERAGEPROC gl3wSampleCoverage; extern PFNGLSAMPLEMASKIPROC gl3wSampleMaski; extern PFNGLSAMPLERPARAMETERIIVPROC gl3wSamplerParameterIiv; extern PFNGLSAMPLERPARAMETERIUIVPROC gl3wSamplerParameterIuiv; extern PFNGLSAMPLERPARAMETERFPROC gl3wSamplerParameterf; extern PFNGLSAMPLERPARAMETERFVPROC gl3wSamplerParameterfv; extern PFNGLSAMPLERPARAMETERIPROC gl3wSamplerParameteri; extern PFNGLSAMPLERPARAMETERIVPROC gl3wSamplerParameteriv; extern PFNGLSCISSORPROC gl3wScissor; extern PFNGLSCISSORARRAYVPROC gl3wScissorArrayv; extern PFNGLSCISSORINDEXEDPROC gl3wScissorIndexed; extern PFNGLSCISSORINDEXEDVPROC gl3wScissorIndexedv; extern PFNGLSHADERBINARYPROC gl3wShaderBinary; extern PFNGLSHADERSOURCEPROC gl3wShaderSource; extern PFNGLSHADERSTORAGEBLOCKBINDINGPROC gl3wShaderStorageBlockBinding; extern PFNGLSTENCILFUNCPROC gl3wStencilFunc; extern PFNGLSTENCILFUNCSEPARATEPROC gl3wStencilFuncSeparate; extern PFNGLSTENCILMASKPROC gl3wStencilMask; extern PFNGLSTENCILMASKSEPARATEPROC gl3wStencilMaskSeparate; extern PFNGLSTENCILOPPROC gl3wStencilOp; extern PFNGLSTENCILOPSEPARATEPROC gl3wStencilOpSeparate; extern PFNGLTEXBUFFERPROC gl3wTexBuffer; extern PFNGLTEXBUFFERRANGEPROC gl3wTexBufferRange; extern PFNGLTEXIMAGE1DPROC gl3wTexImage1D; extern PFNGLTEXIMAGE2DPROC gl3wTexImage2D; extern PFNGLTEXIMAGE2DMULTISAMPLEPROC gl3wTexImage2DMultisample; extern PFNGLTEXIMAGE3DPROC gl3wTexImage3D; extern PFNGLTEXIMAGE3DMULTISAMPLEPROC gl3wTexImage3DMultisample; extern PFNGLTEXPAGECOMMITMENTARBPROC gl3wTexPageCommitmentARB; extern PFNGLTEXPARAMETERIIVPROC gl3wTexParameterIiv; extern PFNGLTEXPARAMETERIUIVPROC gl3wTexParameterIuiv; extern PFNGLTEXPARAMETERFPROC gl3wTexParameterf; extern PFNGLTEXPARAMETERFVPROC gl3wTexParameterfv; extern PFNGLTEXPARAMETERIPROC gl3wTexParameteri; extern PFNGLTEXPARAMETERIVPROC gl3wTexParameteriv; extern PFNGLTEXSTORAGE1DPROC gl3wTexStorage1D; extern PFNGLTEXSTORAGE2DPROC gl3wTexStorage2D; extern PFNGLTEXSTORAGE2DMULTISAMPLEPROC gl3wTexStorage2DMultisample; extern PFNGLTEXSTORAGE3DPROC gl3wTexStorage3D; extern PFNGLTEXSTORAGE3DMULTISAMPLEPROC gl3wTexStorage3DMultisample; extern PFNGLTEXSUBIMAGE1DPROC gl3wTexSubImage1D; extern PFNGLTEXSUBIMAGE2DPROC gl3wTexSubImage2D; extern PFNGLTEXSUBIMAGE3DPROC gl3wTexSubImage3D; extern PFNGLTEXTUREBARRIERPROC gl3wTextureBarrier; extern PFNGLTEXTUREBUFFERPROC gl3wTextureBuffer; extern PFNGLTEXTUREBUFFERRANGEPROC gl3wTextureBufferRange; extern PFNGLTEXTUREPARAMETERIIVPROC gl3wTextureParameterIiv; extern PFNGLTEXTUREPARAMETERIUIVPROC gl3wTextureParameterIuiv; extern PFNGLTEXTUREPARAMETERFPROC gl3wTextureParameterf; extern PFNGLTEXTUREPARAMETERFVPROC gl3wTextureParameterfv; extern PFNGLTEXTUREPARAMETERIPROC gl3wTextureParameteri; extern PFNGLTEXTUREPARAMETERIVPROC gl3wTextureParameteriv; extern PFNGLTEXTURESTORAGE1DPROC gl3wTextureStorage1D; extern PFNGLTEXTURESTORAGE2DPROC gl3wTextureStorage2D; extern PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC gl3wTextureStorage2DMultisample; extern PFNGLTEXTURESTORAGE3DPROC gl3wTextureStorage3D; extern PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC gl3wTextureStorage3DMultisample; extern PFNGLTEXTURESUBIMAGE1DPROC gl3wTextureSubImage1D; extern PFNGLTEXTURESUBIMAGE2DPROC gl3wTextureSubImage2D; extern PFNGLTEXTURESUBIMAGE3DPROC gl3wTextureSubImage3D; extern PFNGLTEXTUREVIEWPROC gl3wTextureView; extern PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC gl3wTransformFeedbackBufferBase; extern PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC gl3wTransformFeedbackBufferRange; extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC gl3wTransformFeedbackVaryings; extern PFNGLUNIFORM1DPROC gl3wUniform1d; extern PFNGLUNIFORM1DVPROC gl3wUniform1dv; extern PFNGLUNIFORM1FPROC gl3wUniform1f; extern PFNGLUNIFORM1FVPROC gl3wUniform1fv; extern PFNGLUNIFORM1IPROC gl3wUniform1i; extern PFNGLUNIFORM1IVPROC gl3wUniform1iv; extern PFNGLUNIFORM1UIPROC gl3wUniform1ui; extern PFNGLUNIFORM1UIVPROC gl3wUniform1uiv; extern PFNGLUNIFORM2DPROC gl3wUniform2d; extern PFNGLUNIFORM2DVPROC gl3wUniform2dv; extern PFNGLUNIFORM2FPROC gl3wUniform2f; extern PFNGLUNIFORM2FVPROC gl3wUniform2fv; extern PFNGLUNIFORM2IPROC gl3wUniform2i; extern PFNGLUNIFORM2IVPROC gl3wUniform2iv; extern PFNGLUNIFORM2UIPROC gl3wUniform2ui; extern PFNGLUNIFORM2UIVPROC gl3wUniform2uiv; extern PFNGLUNIFORM3DPROC gl3wUniform3d; extern PFNGLUNIFORM3DVPROC gl3wUniform3dv; extern PFNGLUNIFORM3FPROC gl3wUniform3f; extern PFNGLUNIFORM3FVPROC gl3wUniform3fv; extern PFNGLUNIFORM3IPROC gl3wUniform3i; extern PFNGLUNIFORM3IVPROC gl3wUniform3iv; extern PFNGLUNIFORM3UIPROC gl3wUniform3ui; extern PFNGLUNIFORM3UIVPROC gl3wUniform3uiv; extern PFNGLUNIFORM4DPROC gl3wUniform4d; extern PFNGLUNIFORM4DVPROC gl3wUniform4dv; extern PFNGLUNIFORM4FPROC gl3wUniform4f; extern PFNGLUNIFORM4FVPROC gl3wUniform4fv; extern PFNGLUNIFORM4IPROC gl3wUniform4i; extern PFNGLUNIFORM4IVPROC gl3wUniform4iv; extern PFNGLUNIFORM4UIPROC gl3wUniform4ui; extern PFNGLUNIFORM4UIVPROC gl3wUniform4uiv; extern PFNGLUNIFORMBLOCKBINDINGPROC gl3wUniformBlockBinding; extern PFNGLUNIFORMHANDLEUI64ARBPROC gl3wUniformHandleui64ARB; extern PFNGLUNIFORMHANDLEUI64VARBPROC gl3wUniformHandleui64vARB; extern PFNGLUNIFORMMATRIX2DVPROC gl3wUniformMatrix2dv; extern PFNGLUNIFORMMATRIX2FVPROC gl3wUniformMatrix2fv; extern PFNGLUNIFORMMATRIX2X3DVPROC gl3wUniformMatrix2x3dv; extern PFNGLUNIFORMMATRIX2X3FVPROC gl3wUniformMatrix2x3fv; extern PFNGLUNIFORMMATRIX2X4DVPROC gl3wUniformMatrix2x4dv; extern PFNGLUNIFORMMATRIX2X4FVPROC gl3wUniformMatrix2x4fv; extern PFNGLUNIFORMMATRIX3DVPROC gl3wUniformMatrix3dv; extern PFNGLUNIFORMMATRIX3FVPROC gl3wUniformMatrix3fv; extern PFNGLUNIFORMMATRIX3X2DVPROC gl3wUniformMatrix3x2dv; extern PFNGLUNIFORMMATRIX3X2FVPROC gl3wUniformMatrix3x2fv; extern PFNGLUNIFORMMATRIX3X4DVPROC gl3wUniformMatrix3x4dv; extern PFNGLUNIFORMMATRIX3X4FVPROC gl3wUniformMatrix3x4fv; extern PFNGLUNIFORMMATRIX4DVPROC gl3wUniformMatrix4dv; extern PFNGLUNIFORMMATRIX4FVPROC gl3wUniformMatrix4fv; extern PFNGLUNIFORMMATRIX4X2DVPROC gl3wUniformMatrix4x2dv; extern PFNGLUNIFORMMATRIX4X2FVPROC gl3wUniformMatrix4x2fv; extern PFNGLUNIFORMMATRIX4X3DVPROC gl3wUniformMatrix4x3dv; extern PFNGLUNIFORMMATRIX4X3FVPROC gl3wUniformMatrix4x3fv; extern PFNGLUNIFORMSUBROUTINESUIVPROC gl3wUniformSubroutinesuiv; extern PFNGLUNMAPBUFFERPROC gl3wUnmapBuffer; extern PFNGLUNMAPNAMEDBUFFERPROC gl3wUnmapNamedBuffer; extern PFNGLUSEPROGRAMPROC gl3wUseProgram; extern PFNGLUSEPROGRAMSTAGESPROC gl3wUseProgramStages; extern PFNGLVALIDATEPROGRAMPROC gl3wValidateProgram; extern PFNGLVALIDATEPROGRAMPIPELINEPROC gl3wValidateProgramPipeline; extern PFNGLVERTEXARRAYATTRIBBINDINGPROC gl3wVertexArrayAttribBinding; extern PFNGLVERTEXARRAYATTRIBFORMATPROC gl3wVertexArrayAttribFormat; extern PFNGLVERTEXARRAYATTRIBIFORMATPROC gl3wVertexArrayAttribIFormat; extern PFNGLVERTEXARRAYATTRIBLFORMATPROC gl3wVertexArrayAttribLFormat; extern PFNGLVERTEXARRAYBINDINGDIVISORPROC gl3wVertexArrayBindingDivisor; extern PFNGLVERTEXARRAYELEMENTBUFFERPROC gl3wVertexArrayElementBuffer; extern PFNGLVERTEXARRAYVERTEXBUFFERPROC gl3wVertexArrayVertexBuffer; extern PFNGLVERTEXARRAYVERTEXBUFFERSPROC gl3wVertexArrayVertexBuffers; extern PFNGLVERTEXATTRIB1DPROC gl3wVertexAttrib1d; extern PFNGLVERTEXATTRIB1DVPROC gl3wVertexAttrib1dv; extern PFNGLVERTEXATTRIB1FPROC gl3wVertexAttrib1f; extern PFNGLVERTEXATTRIB1FVPROC gl3wVertexAttrib1fv; extern PFNGLVERTEXATTRIB1SPROC gl3wVertexAttrib1s; extern PFNGLVERTEXATTRIB1SVPROC gl3wVertexAttrib1sv; extern PFNGLVERTEXATTRIB2DPROC gl3wVertexAttrib2d; extern PFNGLVERTEXATTRIB2DVPROC gl3wVertexAttrib2dv; extern PFNGLVERTEXATTRIB2FPROC gl3wVertexAttrib2f; extern PFNGLVERTEXATTRIB2FVPROC gl3wVertexAttrib2fv; extern PFNGLVERTEXATTRIB2SPROC gl3wVertexAttrib2s; extern PFNGLVERTEXATTRIB2SVPROC gl3wVertexAttrib2sv; extern PFNGLVERTEXATTRIB3DPROC gl3wVertexAttrib3d; extern PFNGLVERTEXATTRIB3DVPROC gl3wVertexAttrib3dv; extern PFNGLVERTEXATTRIB3FPROC gl3wVertexAttrib3f; extern PFNGLVERTEXATTRIB3FVPROC gl3wVertexAttrib3fv; extern PFNGLVERTEXATTRIB3SPROC gl3wVertexAttrib3s; extern PFNGLVERTEXATTRIB3SVPROC gl3wVertexAttrib3sv; extern PFNGLVERTEXATTRIB4NBVPROC gl3wVertexAttrib4Nbv; extern PFNGLVERTEXATTRIB4NIVPROC gl3wVertexAttrib4Niv; extern PFNGLVERTEXATTRIB4NSVPROC gl3wVertexAttrib4Nsv; extern PFNGLVERTEXATTRIB4NUBPROC gl3wVertexAttrib4Nub; extern PFNGLVERTEXATTRIB4NUBVPROC gl3wVertexAttrib4Nubv; extern PFNGLVERTEXATTRIB4NUIVPROC gl3wVertexAttrib4Nuiv; extern PFNGLVERTEXATTRIB4NUSVPROC gl3wVertexAttrib4Nusv; extern PFNGLVERTEXATTRIB4BVPROC gl3wVertexAttrib4bv; extern PFNGLVERTEXATTRIB4DPROC gl3wVertexAttrib4d; extern PFNGLVERTEXATTRIB4DVPROC gl3wVertexAttrib4dv; extern PFNGLVERTEXATTRIB4FPROC gl3wVertexAttrib4f; extern PFNGLVERTEXATTRIB4FVPROC gl3wVertexAttrib4fv; extern PFNGLVERTEXATTRIB4IVPROC gl3wVertexAttrib4iv; extern PFNGLVERTEXATTRIB4SPROC gl3wVertexAttrib4s; extern PFNGLVERTEXATTRIB4SVPROC gl3wVertexAttrib4sv; extern PFNGLVERTEXATTRIB4UBVPROC gl3wVertexAttrib4ubv; extern PFNGLVERTEXATTRIB4UIVPROC gl3wVertexAttrib4uiv; extern PFNGLVERTEXATTRIB4USVPROC gl3wVertexAttrib4usv; extern PFNGLVERTEXATTRIBBINDINGPROC gl3wVertexAttribBinding; extern PFNGLVERTEXATTRIBDIVISORPROC gl3wVertexAttribDivisor; extern PFNGLVERTEXATTRIBFORMATPROC gl3wVertexAttribFormat; extern PFNGLVERTEXATTRIBI1IPROC gl3wVertexAttribI1i; extern PFNGLVERTEXATTRIBI1IVPROC gl3wVertexAttribI1iv; extern PFNGLVERTEXATTRIBI1UIPROC gl3wVertexAttribI1ui; extern PFNGLVERTEXATTRIBI1UIVPROC gl3wVertexAttribI1uiv; extern PFNGLVERTEXATTRIBI2IPROC gl3wVertexAttribI2i; extern PFNGLVERTEXATTRIBI2IVPROC gl3wVertexAttribI2iv; extern PFNGLVERTEXATTRIBI2UIPROC gl3wVertexAttribI2ui; extern PFNGLVERTEXATTRIBI2UIVPROC gl3wVertexAttribI2uiv; extern PFNGLVERTEXATTRIBI3IPROC gl3wVertexAttribI3i; extern PFNGLVERTEXATTRIBI3IVPROC gl3wVertexAttribI3iv; extern PFNGLVERTEXATTRIBI3UIPROC gl3wVertexAttribI3ui; extern PFNGLVERTEXATTRIBI3UIVPROC gl3wVertexAttribI3uiv; extern PFNGLVERTEXATTRIBI4BVPROC gl3wVertexAttribI4bv; extern PFNGLVERTEXATTRIBI4IPROC gl3wVertexAttribI4i; extern PFNGLVERTEXATTRIBI4IVPROC gl3wVertexAttribI4iv; extern PFNGLVERTEXATTRIBI4SVPROC gl3wVertexAttribI4sv; extern PFNGLVERTEXATTRIBI4UBVPROC gl3wVertexAttribI4ubv; extern PFNGLVERTEXATTRIBI4UIPROC gl3wVertexAttribI4ui; extern PFNGLVERTEXATTRIBI4UIVPROC gl3wVertexAttribI4uiv; extern PFNGLVERTEXATTRIBI4USVPROC gl3wVertexAttribI4usv; extern PFNGLVERTEXATTRIBIFORMATPROC gl3wVertexAttribIFormat; extern PFNGLVERTEXATTRIBIPOINTERPROC gl3wVertexAttribIPointer; extern PFNGLVERTEXATTRIBL1DPROC gl3wVertexAttribL1d; extern PFNGLVERTEXATTRIBL1DVPROC gl3wVertexAttribL1dv; extern PFNGLVERTEXATTRIBL1UI64ARBPROC gl3wVertexAttribL1ui64ARB; extern PFNGLVERTEXATTRIBL1UI64VARBPROC gl3wVertexAttribL1ui64vARB; extern PFNGLVERTEXATTRIBL2DPROC gl3wVertexAttribL2d; extern PFNGLVERTEXATTRIBL2DVPROC gl3wVertexAttribL2dv; extern PFNGLVERTEXATTRIBL3DPROC gl3wVertexAttribL3d; extern PFNGLVERTEXATTRIBL3DVPROC gl3wVertexAttribL3dv; extern PFNGLVERTEXATTRIBL4DPROC gl3wVertexAttribL4d; extern PFNGLVERTEXATTRIBL4DVPROC gl3wVertexAttribL4dv; extern PFNGLVERTEXATTRIBLFORMATPROC gl3wVertexAttribLFormat; extern PFNGLVERTEXATTRIBLPOINTERPROC gl3wVertexAttribLPointer; extern PFNGLVERTEXATTRIBP1UIPROC gl3wVertexAttribP1ui; extern PFNGLVERTEXATTRIBP1UIVPROC gl3wVertexAttribP1uiv; extern PFNGLVERTEXATTRIBP2UIPROC gl3wVertexAttribP2ui; extern PFNGLVERTEXATTRIBP2UIVPROC gl3wVertexAttribP2uiv; extern PFNGLVERTEXATTRIBP3UIPROC gl3wVertexAttribP3ui; extern PFNGLVERTEXATTRIBP3UIVPROC gl3wVertexAttribP3uiv; extern PFNGLVERTEXATTRIBP4UIPROC gl3wVertexAttribP4ui; extern PFNGLVERTEXATTRIBP4UIVPROC gl3wVertexAttribP4uiv; extern PFNGLVERTEXATTRIBPOINTERPROC gl3wVertexAttribPointer; extern PFNGLVERTEXBINDINGDIVISORPROC gl3wVertexBindingDivisor; extern PFNGLVIEWPORTPROC gl3wViewport; extern PFNGLVIEWPORTARRAYVPROC gl3wViewportArrayv; extern PFNGLVIEWPORTINDEXEDFPROC gl3wViewportIndexedf; extern PFNGLVIEWPORTINDEXEDFVPROC gl3wViewportIndexedfv; extern PFNGLWAITSYNCPROC gl3wWaitSync; #define glActiveShaderProgram gl3wActiveShaderProgram #define glActiveTexture gl3wActiveTexture #define glAttachShader gl3wAttachShader #define glBeginConditionalRender gl3wBeginConditionalRender #define glBeginQuery gl3wBeginQuery #define glBeginQueryIndexed gl3wBeginQueryIndexed #define glBeginTransformFeedback gl3wBeginTransformFeedback #define glBindAttribLocation gl3wBindAttribLocation #define glBindBuffer gl3wBindBuffer #define glBindBufferBase gl3wBindBufferBase #define glBindBufferRange gl3wBindBufferRange #define glBindBuffersBase gl3wBindBuffersBase #define glBindBuffersRange gl3wBindBuffersRange #define glBindFragDataLocation gl3wBindFragDataLocation #define glBindFragDataLocationIndexed gl3wBindFragDataLocationIndexed #define glBindFramebuffer gl3wBindFramebuffer #define glBindImageTexture gl3wBindImageTexture #define glBindImageTextures gl3wBindImageTextures #define glBindProgramPipeline gl3wBindProgramPipeline #define glBindRenderbuffer gl3wBindRenderbuffer #define glBindSampler gl3wBindSampler #define glBindSamplers gl3wBindSamplers #define glBindTexture gl3wBindTexture #define glBindTextureUnit gl3wBindTextureUnit #define glBindTextures gl3wBindTextures #define glBindTransformFeedback gl3wBindTransformFeedback #define glBindVertexArray gl3wBindVertexArray #define glBindVertexBuffer gl3wBindVertexBuffer #define glBindVertexBuffers gl3wBindVertexBuffers #define glBlendColor gl3wBlendColor #define glBlendEquation gl3wBlendEquation #define glBlendEquationSeparate gl3wBlendEquationSeparate #define glBlendEquationSeparatei gl3wBlendEquationSeparatei #define glBlendEquationSeparateiARB gl3wBlendEquationSeparateiARB #define glBlendEquationi gl3wBlendEquationi #define glBlendEquationiARB gl3wBlendEquationiARB #define glBlendFunc gl3wBlendFunc #define glBlendFuncSeparate gl3wBlendFuncSeparate #define glBlendFuncSeparatei gl3wBlendFuncSeparatei #define glBlendFuncSeparateiARB gl3wBlendFuncSeparateiARB #define glBlendFunci gl3wBlendFunci #define glBlendFunciARB gl3wBlendFunciARB #define glBlitFramebuffer gl3wBlitFramebuffer #define glBlitNamedFramebuffer gl3wBlitNamedFramebuffer #define glBufferData gl3wBufferData #define glBufferPageCommitmentARB gl3wBufferPageCommitmentARB #define glBufferStorage gl3wBufferStorage #define glBufferSubData gl3wBufferSubData #define glCheckFramebufferStatus gl3wCheckFramebufferStatus #define glCheckNamedFramebufferStatus gl3wCheckNamedFramebufferStatus #define glClampColor gl3wClampColor #define glClear gl3wClear #define glClearBufferData gl3wClearBufferData #define glClearBufferSubData gl3wClearBufferSubData #define glClearBufferfi gl3wClearBufferfi #define glClearBufferfv gl3wClearBufferfv #define glClearBufferiv gl3wClearBufferiv #define glClearBufferuiv gl3wClearBufferuiv #define glClearColor gl3wClearColor #define glClearDepth gl3wClearDepth #define glClearDepthf gl3wClearDepthf #define glClearNamedBufferData gl3wClearNamedBufferData #define glClearNamedBufferSubData gl3wClearNamedBufferSubData #define glClearNamedFramebufferfi gl3wClearNamedFramebufferfi #define glClearNamedFramebufferfv gl3wClearNamedFramebufferfv #define glClearNamedFramebufferiv gl3wClearNamedFramebufferiv #define glClearNamedFramebufferuiv gl3wClearNamedFramebufferuiv #define glClearStencil gl3wClearStencil #define glClearTexImage gl3wClearTexImage #define glClearTexSubImage gl3wClearTexSubImage #define glClientWaitSync gl3wClientWaitSync #define glClipControl gl3wClipControl #define glColorMask gl3wColorMask #define glColorMaski gl3wColorMaski #define glCompileShader gl3wCompileShader #define glCompileShaderIncludeARB gl3wCompileShaderIncludeARB #define glCompressedTexImage1D gl3wCompressedTexImage1D #define glCompressedTexImage2D gl3wCompressedTexImage2D #define glCompressedTexImage3D gl3wCompressedTexImage3D #define glCompressedTexSubImage1D gl3wCompressedTexSubImage1D #define glCompressedTexSubImage2D gl3wCompressedTexSubImage2D #define glCompressedTexSubImage3D gl3wCompressedTexSubImage3D #define glCompressedTextureSubImage1D gl3wCompressedTextureSubImage1D #define glCompressedTextureSubImage2D gl3wCompressedTextureSubImage2D #define glCompressedTextureSubImage3D gl3wCompressedTextureSubImage3D #define glCopyBufferSubData gl3wCopyBufferSubData #define glCopyImageSubData gl3wCopyImageSubData #define glCopyNamedBufferSubData gl3wCopyNamedBufferSubData #define glCopyTexImage1D gl3wCopyTexImage1D #define glCopyTexImage2D gl3wCopyTexImage2D #define glCopyTexSubImage1D gl3wCopyTexSubImage1D #define glCopyTexSubImage2D gl3wCopyTexSubImage2D #define glCopyTexSubImage3D gl3wCopyTexSubImage3D #define glCopyTextureSubImage1D gl3wCopyTextureSubImage1D #define glCopyTextureSubImage2D gl3wCopyTextureSubImage2D #define glCopyTextureSubImage3D gl3wCopyTextureSubImage3D #define glCreateBuffers gl3wCreateBuffers #define glCreateFramebuffers gl3wCreateFramebuffers #define glCreateProgram gl3wCreateProgram #define glCreateProgramPipelines gl3wCreateProgramPipelines #define glCreateQueries gl3wCreateQueries #define glCreateRenderbuffers gl3wCreateRenderbuffers #define glCreateSamplers gl3wCreateSamplers #define glCreateShader gl3wCreateShader #define glCreateShaderProgramv gl3wCreateShaderProgramv #define glCreateSyncFromCLeventARB gl3wCreateSyncFromCLeventARB #define glCreateTextures gl3wCreateTextures #define glCreateTransformFeedbacks gl3wCreateTransformFeedbacks #define glCreateVertexArrays gl3wCreateVertexArrays #define glCullFace gl3wCullFace #define glDebugMessageCallback gl3wDebugMessageCallback #define glDebugMessageCallbackARB gl3wDebugMessageCallbackARB #define glDebugMessageControl gl3wDebugMessageControl #define glDebugMessageControlARB gl3wDebugMessageControlARB #define glDebugMessageInsert gl3wDebugMessageInsert #define glDebugMessageInsertARB gl3wDebugMessageInsertARB #define glDeleteBuffers gl3wDeleteBuffers #define glDeleteFramebuffers gl3wDeleteFramebuffers #define glDeleteNamedStringARB gl3wDeleteNamedStringARB #define glDeleteProgram gl3wDeleteProgram #define glDeleteProgramPipelines gl3wDeleteProgramPipelines #define glDeleteQueries gl3wDeleteQueries #define glDeleteRenderbuffers gl3wDeleteRenderbuffers #define glDeleteSamplers gl3wDeleteSamplers #define glDeleteShader gl3wDeleteShader #define glDeleteSync gl3wDeleteSync #define glDeleteTextures gl3wDeleteTextures #define glDeleteTransformFeedbacks gl3wDeleteTransformFeedbacks #define glDeleteVertexArrays gl3wDeleteVertexArrays #define glDepthFunc gl3wDepthFunc #define glDepthMask gl3wDepthMask #define glDepthRange gl3wDepthRange #define glDepthRangeArrayv gl3wDepthRangeArrayv #define glDepthRangeIndexed gl3wDepthRangeIndexed #define glDepthRangef gl3wDepthRangef #define glDetachShader gl3wDetachShader #define glDisable gl3wDisable #define glDisableVertexArrayAttrib gl3wDisableVertexArrayAttrib #define glDisableVertexAttribArray gl3wDisableVertexAttribArray #define glDisablei gl3wDisablei #define glDispatchCompute gl3wDispatchCompute #define glDispatchComputeGroupSizeARB gl3wDispatchComputeGroupSizeARB #define glDispatchComputeIndirect gl3wDispatchComputeIndirect #define glDrawArrays gl3wDrawArrays #define glDrawArraysIndirect gl3wDrawArraysIndirect #define glDrawArraysInstanced gl3wDrawArraysInstanced #define glDrawArraysInstancedBaseInstance gl3wDrawArraysInstancedBaseInstance #define glDrawBuffer gl3wDrawBuffer #define glDrawBuffers gl3wDrawBuffers #define glDrawElements gl3wDrawElements #define glDrawElementsBaseVertex gl3wDrawElementsBaseVertex #define glDrawElementsIndirect gl3wDrawElementsIndirect #define glDrawElementsInstanced gl3wDrawElementsInstanced #define glDrawElementsInstancedBaseInstance gl3wDrawElementsInstancedBaseInstance #define glDrawElementsInstancedBaseVertex gl3wDrawElementsInstancedBaseVertex #define glDrawElementsInstancedBaseVertexBaseInstance gl3wDrawElementsInstancedBaseVertexBaseInstance #define glDrawRangeElements gl3wDrawRangeElements #define glDrawRangeElementsBaseVertex gl3wDrawRangeElementsBaseVertex #define glDrawTransformFeedback gl3wDrawTransformFeedback #define glDrawTransformFeedbackInstanced gl3wDrawTransformFeedbackInstanced #define glDrawTransformFeedbackStream gl3wDrawTransformFeedbackStream #define glDrawTransformFeedbackStreamInstanced gl3wDrawTransformFeedbackStreamInstanced #define glEnable gl3wEnable #define glEnableVertexArrayAttrib gl3wEnableVertexArrayAttrib #define glEnableVertexAttribArray gl3wEnableVertexAttribArray #define glEnablei gl3wEnablei #define glEndConditionalRender gl3wEndConditionalRender #define glEndQuery gl3wEndQuery #define glEndQueryIndexed gl3wEndQueryIndexed #define glEndTransformFeedback gl3wEndTransformFeedback #define glFenceSync gl3wFenceSync #define glFinish gl3wFinish #define glFlush gl3wFlush #define glFlushMappedBufferRange gl3wFlushMappedBufferRange #define glFlushMappedNamedBufferRange gl3wFlushMappedNamedBufferRange #define glFramebufferParameteri gl3wFramebufferParameteri #define glFramebufferRenderbuffer gl3wFramebufferRenderbuffer #define glFramebufferTexture gl3wFramebufferTexture #define glFramebufferTexture1D gl3wFramebufferTexture1D #define glFramebufferTexture2D gl3wFramebufferTexture2D #define glFramebufferTexture3D gl3wFramebufferTexture3D #define glFramebufferTextureLayer gl3wFramebufferTextureLayer #define glFrontFace gl3wFrontFace #define glGenBuffers gl3wGenBuffers #define glGenFramebuffers gl3wGenFramebuffers #define glGenProgramPipelines gl3wGenProgramPipelines #define glGenQueries gl3wGenQueries #define glGenRenderbuffers gl3wGenRenderbuffers #define glGenSamplers gl3wGenSamplers #define glGenTextures gl3wGenTextures #define glGenTransformFeedbacks gl3wGenTransformFeedbacks #define glGenVertexArrays gl3wGenVertexArrays #define glGenerateMipmap gl3wGenerateMipmap #define glGenerateTextureMipmap gl3wGenerateTextureMipmap #define glGetActiveAtomicCounterBufferiv gl3wGetActiveAtomicCounterBufferiv #define glGetActiveAttrib gl3wGetActiveAttrib #define glGetActiveSubroutineName gl3wGetActiveSubroutineName #define glGetActiveSubroutineUniformName gl3wGetActiveSubroutineUniformName #define glGetActiveSubroutineUniformiv gl3wGetActiveSubroutineUniformiv #define glGetActiveUniform gl3wGetActiveUniform #define glGetActiveUniformBlockName gl3wGetActiveUniformBlockName #define glGetActiveUniformBlockiv gl3wGetActiveUniformBlockiv #define glGetActiveUniformName gl3wGetActiveUniformName #define glGetActiveUniformsiv gl3wGetActiveUniformsiv #define glGetAttachedShaders gl3wGetAttachedShaders #define glGetAttribLocation gl3wGetAttribLocation #define glGetBooleani_v gl3wGetBooleani_v #define glGetBooleanv gl3wGetBooleanv #define glGetBufferParameteri64v gl3wGetBufferParameteri64v #define glGetBufferParameteriv gl3wGetBufferParameteriv #define glGetBufferPointerv gl3wGetBufferPointerv #define glGetBufferSubData gl3wGetBufferSubData #define glGetCompressedTexImage gl3wGetCompressedTexImage #define glGetCompressedTextureImage gl3wGetCompressedTextureImage #define glGetCompressedTextureSubImage gl3wGetCompressedTextureSubImage #define glGetDebugMessageLog gl3wGetDebugMessageLog #define glGetDebugMessageLogARB gl3wGetDebugMessageLogARB #define glGetDoublei_v gl3wGetDoublei_v #define glGetDoublev gl3wGetDoublev #define glGetError gl3wGetError #define glGetFloati_v gl3wGetFloati_v #define glGetFloatv gl3wGetFloatv #define glGetFragDataIndex gl3wGetFragDataIndex #define glGetFragDataLocation gl3wGetFragDataLocation #define glGetFramebufferAttachmentParameteriv gl3wGetFramebufferAttachmentParameteriv #define glGetFramebufferParameteriv gl3wGetFramebufferParameteriv #define glGetGraphicsResetStatus gl3wGetGraphicsResetStatus #define glGetGraphicsResetStatusARB gl3wGetGraphicsResetStatusARB #define glGetImageHandleARB gl3wGetImageHandleARB #define glGetInteger64i_v gl3wGetInteger64i_v #define glGetInteger64v gl3wGetInteger64v #define glGetIntegeri_v gl3wGetIntegeri_v #define glGetIntegerv gl3wGetIntegerv #define glGetInternalformati64v gl3wGetInternalformati64v #define glGetInternalformativ gl3wGetInternalformativ #define glGetMultisamplefv gl3wGetMultisamplefv #define glGetNamedBufferParameteri64v gl3wGetNamedBufferParameteri64v #define glGetNamedBufferParameteriv gl3wGetNamedBufferParameteriv #define glGetNamedBufferPointerv gl3wGetNamedBufferPointerv #define glGetNamedBufferSubData gl3wGetNamedBufferSubData #define glGetNamedFramebufferAttachmentParameteriv gl3wGetNamedFramebufferAttachmentParameteriv #define glGetNamedFramebufferParameteriv gl3wGetNamedFramebufferParameteriv #define glGetNamedRenderbufferParameteriv gl3wGetNamedRenderbufferParameteriv #define glGetNamedStringARB gl3wGetNamedStringARB #define glGetNamedStringivARB gl3wGetNamedStringivARB #define glGetObjectLabel gl3wGetObjectLabel #define glGetObjectPtrLabel gl3wGetObjectPtrLabel #define glGetPointerv gl3wGetPointerv #define glGetProgramBinary gl3wGetProgramBinary #define glGetProgramInfoLog gl3wGetProgramInfoLog #define glGetProgramInterfaceiv gl3wGetProgramInterfaceiv #define glGetProgramPipelineInfoLog gl3wGetProgramPipelineInfoLog #define glGetProgramPipelineiv gl3wGetProgramPipelineiv #define glGetProgramResourceIndex gl3wGetProgramResourceIndex #define glGetProgramResourceLocation gl3wGetProgramResourceLocation #define glGetProgramResourceLocationIndex gl3wGetProgramResourceLocationIndex #define glGetProgramResourceName gl3wGetProgramResourceName #define glGetProgramResourceiv gl3wGetProgramResourceiv #define glGetProgramStageiv gl3wGetProgramStageiv #define glGetProgramiv gl3wGetProgramiv #define glGetQueryBufferObjecti64v gl3wGetQueryBufferObjecti64v #define glGetQueryBufferObjectiv gl3wGetQueryBufferObjectiv #define glGetQueryBufferObjectui64v gl3wGetQueryBufferObjectui64v #define glGetQueryBufferObjectuiv gl3wGetQueryBufferObjectuiv #define glGetQueryIndexediv gl3wGetQueryIndexediv #define glGetQueryObjecti64v gl3wGetQueryObjecti64v #define glGetQueryObjectiv gl3wGetQueryObjectiv #define glGetQueryObjectui64v gl3wGetQueryObjectui64v #define glGetQueryObjectuiv gl3wGetQueryObjectuiv #define glGetQueryiv gl3wGetQueryiv #define glGetRenderbufferParameteriv gl3wGetRenderbufferParameteriv #define glGetSamplerParameterIiv gl3wGetSamplerParameterIiv #define glGetSamplerParameterIuiv gl3wGetSamplerParameterIuiv #define glGetSamplerParameterfv gl3wGetSamplerParameterfv #define glGetSamplerParameteriv gl3wGetSamplerParameteriv #define glGetShaderInfoLog gl3wGetShaderInfoLog #define glGetShaderPrecisionFormat gl3wGetShaderPrecisionFormat #define glGetShaderSource gl3wGetShaderSource #define glGetShaderiv gl3wGetShaderiv #define glGetString gl3wGetString #define glGetStringi gl3wGetStringi #define glGetSubroutineIndex gl3wGetSubroutineIndex #define glGetSubroutineUniformLocation gl3wGetSubroutineUniformLocation #define glGetSynciv gl3wGetSynciv #define glGetTexImage gl3wGetTexImage #define glGetTexLevelParameterfv gl3wGetTexLevelParameterfv #define glGetTexLevelParameteriv gl3wGetTexLevelParameteriv #define glGetTexParameterIiv gl3wGetTexParameterIiv #define glGetTexParameterIuiv gl3wGetTexParameterIuiv #define glGetTexParameterfv gl3wGetTexParameterfv #define glGetTexParameteriv gl3wGetTexParameteriv #define glGetTextureHandleARB gl3wGetTextureHandleARB #define glGetTextureImage gl3wGetTextureImage #define glGetTextureLevelParameterfv gl3wGetTextureLevelParameterfv #define glGetTextureLevelParameteriv gl3wGetTextureLevelParameteriv #define glGetTextureParameterIiv gl3wGetTextureParameterIiv #define glGetTextureParameterIuiv gl3wGetTextureParameterIuiv #define glGetTextureParameterfv gl3wGetTextureParameterfv #define glGetTextureParameteriv gl3wGetTextureParameteriv #define glGetTextureSamplerHandleARB gl3wGetTextureSamplerHandleARB #define glGetTextureSubImage gl3wGetTextureSubImage #define glGetTransformFeedbackVarying gl3wGetTransformFeedbackVarying #define glGetTransformFeedbacki64_v gl3wGetTransformFeedbacki64_v #define glGetTransformFeedbacki_v gl3wGetTransformFeedbacki_v #define glGetTransformFeedbackiv gl3wGetTransformFeedbackiv #define glGetUniformBlockIndex gl3wGetUniformBlockIndex #define glGetUniformIndices gl3wGetUniformIndices #define glGetUniformLocation gl3wGetUniformLocation #define glGetUniformSubroutineuiv gl3wGetUniformSubroutineuiv #define glGetUniformdv gl3wGetUniformdv #define glGetUniformfv gl3wGetUniformfv #define glGetUniformiv gl3wGetUniformiv #define glGetUniformuiv gl3wGetUniformuiv #define glGetVertexArrayIndexed64iv gl3wGetVertexArrayIndexed64iv #define glGetVertexArrayIndexediv gl3wGetVertexArrayIndexediv #define glGetVertexArrayiv gl3wGetVertexArrayiv #define glGetVertexAttribIiv gl3wGetVertexAttribIiv #define glGetVertexAttribIuiv gl3wGetVertexAttribIuiv #define glGetVertexAttribLdv gl3wGetVertexAttribLdv #define glGetVertexAttribLui64vARB gl3wGetVertexAttribLui64vARB #define glGetVertexAttribPointerv gl3wGetVertexAttribPointerv #define glGetVertexAttribdv gl3wGetVertexAttribdv #define glGetVertexAttribfv gl3wGetVertexAttribfv #define glGetVertexAttribiv gl3wGetVertexAttribiv #define glGetnCompressedTexImage gl3wGetnCompressedTexImage #define glGetnCompressedTexImageARB gl3wGetnCompressedTexImageARB #define glGetnTexImage gl3wGetnTexImage #define glGetnTexImageARB gl3wGetnTexImageARB #define glGetnUniformdv gl3wGetnUniformdv #define glGetnUniformdvARB gl3wGetnUniformdvARB #define glGetnUniformfv gl3wGetnUniformfv #define glGetnUniformfvARB gl3wGetnUniformfvARB #define glGetnUniformiv gl3wGetnUniformiv #define glGetnUniformivARB gl3wGetnUniformivARB #define glGetnUniformuiv gl3wGetnUniformuiv #define glGetnUniformuivARB gl3wGetnUniformuivARB #define glHint gl3wHint #define glInvalidateBufferData gl3wInvalidateBufferData #define glInvalidateBufferSubData gl3wInvalidateBufferSubData #define glInvalidateFramebuffer gl3wInvalidateFramebuffer #define glInvalidateNamedFramebufferData gl3wInvalidateNamedFramebufferData #define glInvalidateNamedFramebufferSubData gl3wInvalidateNamedFramebufferSubData #define glInvalidateSubFramebuffer gl3wInvalidateSubFramebuffer #define glInvalidateTexImage gl3wInvalidateTexImage #define glInvalidateTexSubImage gl3wInvalidateTexSubImage #define glIsBuffer gl3wIsBuffer #define glIsEnabled gl3wIsEnabled #define glIsEnabledi gl3wIsEnabledi #define glIsFramebuffer gl3wIsFramebuffer #define glIsImageHandleResidentARB gl3wIsImageHandleResidentARB #define glIsNamedStringARB gl3wIsNamedStringARB #define glIsProgram gl3wIsProgram #define glIsProgramPipeline gl3wIsProgramPipeline #define glIsQuery gl3wIsQuery #define glIsRenderbuffer gl3wIsRenderbuffer #define glIsSampler gl3wIsSampler #define glIsShader gl3wIsShader #define glIsSync gl3wIsSync #define glIsTexture gl3wIsTexture #define glIsTextureHandleResidentARB gl3wIsTextureHandleResidentARB #define glIsTransformFeedback gl3wIsTransformFeedback #define glIsVertexArray gl3wIsVertexArray #define glLineWidth gl3wLineWidth #define glLinkProgram gl3wLinkProgram #define glLogicOp gl3wLogicOp #define glMakeImageHandleNonResidentARB gl3wMakeImageHandleNonResidentARB #define glMakeImageHandleResidentARB gl3wMakeImageHandleResidentARB #define glMakeTextureHandleNonResidentARB gl3wMakeTextureHandleNonResidentARB #define glMakeTextureHandleResidentARB gl3wMakeTextureHandleResidentARB #define glMapBuffer gl3wMapBuffer #define glMapBufferRange gl3wMapBufferRange #define glMapNamedBuffer gl3wMapNamedBuffer #define glMapNamedBufferRange gl3wMapNamedBufferRange #define glMemoryBarrier gl3wMemoryBarrier #define glMemoryBarrierByRegion gl3wMemoryBarrierByRegion #define glMinSampleShading gl3wMinSampleShading #define glMinSampleShadingARB gl3wMinSampleShadingARB #define glMultiDrawArrays gl3wMultiDrawArrays #define glMultiDrawArraysIndirect gl3wMultiDrawArraysIndirect #define glMultiDrawArraysIndirectCountARB gl3wMultiDrawArraysIndirectCountARB #define glMultiDrawElements gl3wMultiDrawElements #define glMultiDrawElementsBaseVertex gl3wMultiDrawElementsBaseVertex #define glMultiDrawElementsIndirect gl3wMultiDrawElementsIndirect #define glMultiDrawElementsIndirectCountARB gl3wMultiDrawElementsIndirectCountARB #define glNamedBufferData gl3wNamedBufferData #define glNamedBufferPageCommitmentARB gl3wNamedBufferPageCommitmentARB #define glNamedBufferPageCommitmentEXT gl3wNamedBufferPageCommitmentEXT #define glNamedBufferStorage gl3wNamedBufferStorage #define glNamedBufferSubData gl3wNamedBufferSubData #define glNamedFramebufferDrawBuffer gl3wNamedFramebufferDrawBuffer #define glNamedFramebufferDrawBuffers gl3wNamedFramebufferDrawBuffers #define glNamedFramebufferParameteri gl3wNamedFramebufferParameteri #define glNamedFramebufferReadBuffer gl3wNamedFramebufferReadBuffer #define glNamedFramebufferRenderbuffer gl3wNamedFramebufferRenderbuffer #define glNamedFramebufferTexture gl3wNamedFramebufferTexture #define glNamedFramebufferTextureLayer gl3wNamedFramebufferTextureLayer #define glNamedRenderbufferStorage gl3wNamedRenderbufferStorage #define glNamedRenderbufferStorageMultisample gl3wNamedRenderbufferStorageMultisample #define glNamedStringARB gl3wNamedStringARB #define glObjectLabel gl3wObjectLabel #define glObjectPtrLabel gl3wObjectPtrLabel #define glPatchParameterfv gl3wPatchParameterfv #define glPatchParameteri gl3wPatchParameteri #define glPauseTransformFeedback gl3wPauseTransformFeedback #define glPixelStoref gl3wPixelStoref #define glPixelStorei gl3wPixelStorei #define glPointParameterf gl3wPointParameterf #define glPointParameterfv gl3wPointParameterfv #define glPointParameteri gl3wPointParameteri #define glPointParameteriv gl3wPointParameteriv #define glPointSize gl3wPointSize #define glPolygonMode gl3wPolygonMode #define glPolygonOffset gl3wPolygonOffset #define glPopDebugGroup gl3wPopDebugGroup #define glPrimitiveRestartIndex gl3wPrimitiveRestartIndex #define glProgramBinary gl3wProgramBinary #define glProgramParameteri gl3wProgramParameteri #define glProgramUniform1d gl3wProgramUniform1d #define glProgramUniform1dv gl3wProgramUniform1dv #define glProgramUniform1f gl3wProgramUniform1f #define glProgramUniform1fv gl3wProgramUniform1fv #define glProgramUniform1i gl3wProgramUniform1i #define glProgramUniform1iv gl3wProgramUniform1iv #define glProgramUniform1ui gl3wProgramUniform1ui #define glProgramUniform1uiv gl3wProgramUniform1uiv #define glProgramUniform2d gl3wProgramUniform2d #define glProgramUniform2dv gl3wProgramUniform2dv #define glProgramUniform2f gl3wProgramUniform2f #define glProgramUniform2fv gl3wProgramUniform2fv #define glProgramUniform2i gl3wProgramUniform2i #define glProgramUniform2iv gl3wProgramUniform2iv #define glProgramUniform2ui gl3wProgramUniform2ui #define glProgramUniform2uiv gl3wProgramUniform2uiv #define glProgramUniform3d gl3wProgramUniform3d #define glProgramUniform3dv gl3wProgramUniform3dv #define glProgramUniform3f gl3wProgramUniform3f #define glProgramUniform3fv gl3wProgramUniform3fv #define glProgramUniform3i gl3wProgramUniform3i #define glProgramUniform3iv gl3wProgramUniform3iv #define glProgramUniform3ui gl3wProgramUniform3ui #define glProgramUniform3uiv gl3wProgramUniform3uiv #define glProgramUniform4d gl3wProgramUniform4d #define glProgramUniform4dv gl3wProgramUniform4dv #define glProgramUniform4f gl3wProgramUniform4f #define glProgramUniform4fv gl3wProgramUniform4fv #define glProgramUniform4i gl3wProgramUniform4i #define glProgramUniform4iv gl3wProgramUniform4iv #define glProgramUniform4ui gl3wProgramUniform4ui #define glProgramUniform4uiv gl3wProgramUniform4uiv #define glProgramUniformHandleui64ARB gl3wProgramUniformHandleui64ARB #define glProgramUniformHandleui64vARB gl3wProgramUniformHandleui64vARB #define glProgramUniformMatrix2dv gl3wProgramUniformMatrix2dv #define glProgramUniformMatrix2fv gl3wProgramUniformMatrix2fv #define glProgramUniformMatrix2x3dv gl3wProgramUniformMatrix2x3dv #define glProgramUniformMatrix2x3fv gl3wProgramUniformMatrix2x3fv #define glProgramUniformMatrix2x4dv gl3wProgramUniformMatrix2x4dv #define glProgramUniformMatrix2x4fv gl3wProgramUniformMatrix2x4fv #define glProgramUniformMatrix3dv gl3wProgramUniformMatrix3dv #define glProgramUniformMatrix3fv gl3wProgramUniformMatrix3fv #define glProgramUniformMatrix3x2dv gl3wProgramUniformMatrix3x2dv #define glProgramUniformMatrix3x2fv gl3wProgramUniformMatrix3x2fv #define glProgramUniformMatrix3x4dv gl3wProgramUniformMatrix3x4dv #define glProgramUniformMatrix3x4fv gl3wProgramUniformMatrix3x4fv #define glProgramUniformMatrix4dv gl3wProgramUniformMatrix4dv #define glProgramUniformMatrix4fv gl3wProgramUniformMatrix4fv #define glProgramUniformMatrix4x2dv gl3wProgramUniformMatrix4x2dv #define glProgramUniformMatrix4x2fv gl3wProgramUniformMatrix4x2fv #define glProgramUniformMatrix4x3dv gl3wProgramUniformMatrix4x3dv #define glProgramUniformMatrix4x3fv gl3wProgramUniformMatrix4x3fv #define glProvokingVertex gl3wProvokingVertex #define glPushDebugGroup gl3wPushDebugGroup #define glQueryCounter gl3wQueryCounter #define glReadBuffer gl3wReadBuffer #define glReadPixels gl3wReadPixels #define glReadnPixels gl3wReadnPixels #define glReadnPixelsARB gl3wReadnPixelsARB #define glReleaseShaderCompiler gl3wReleaseShaderCompiler #define glRenderbufferStorage gl3wRenderbufferStorage #define glRenderbufferStorageMultisample gl3wRenderbufferStorageMultisample #define glResumeTransformFeedback gl3wResumeTransformFeedback #define glSampleCoverage gl3wSampleCoverage #define glSampleMaski gl3wSampleMaski #define glSamplerParameterIiv gl3wSamplerParameterIiv #define glSamplerParameterIuiv gl3wSamplerParameterIuiv #define glSamplerParameterf gl3wSamplerParameterf #define glSamplerParameterfv gl3wSamplerParameterfv #define glSamplerParameteri gl3wSamplerParameteri #define glSamplerParameteriv gl3wSamplerParameteriv #define glScissor gl3wScissor #define glScissorArrayv gl3wScissorArrayv #define glScissorIndexed gl3wScissorIndexed #define glScissorIndexedv gl3wScissorIndexedv #define glShaderBinary gl3wShaderBinary #define glShaderSource gl3wShaderSource #define glShaderStorageBlockBinding gl3wShaderStorageBlockBinding #define glStencilFunc gl3wStencilFunc #define glStencilFuncSeparate gl3wStencilFuncSeparate #define glStencilMask gl3wStencilMask #define glStencilMaskSeparate gl3wStencilMaskSeparate #define glStencilOp gl3wStencilOp #define glStencilOpSeparate gl3wStencilOpSeparate #define glTexBuffer gl3wTexBuffer #define glTexBufferRange gl3wTexBufferRange #define glTexImage1D gl3wTexImage1D #define glTexImage2D gl3wTexImage2D #define glTexImage2DMultisample gl3wTexImage2DMultisample #define glTexImage3D gl3wTexImage3D #define glTexImage3DMultisample gl3wTexImage3DMultisample #define glTexPageCommitmentARB gl3wTexPageCommitmentARB #define glTexParameterIiv gl3wTexParameterIiv #define glTexParameterIuiv gl3wTexParameterIuiv #define glTexParameterf gl3wTexParameterf #define glTexParameterfv gl3wTexParameterfv #define glTexParameteri gl3wTexParameteri #define glTexParameteriv gl3wTexParameteriv #define glTexStorage1D gl3wTexStorage1D #define glTexStorage2D gl3wTexStorage2D #define glTexStorage2DMultisample gl3wTexStorage2DMultisample #define glTexStorage3D gl3wTexStorage3D #define glTexStorage3DMultisample gl3wTexStorage3DMultisample #define glTexSubImage1D gl3wTexSubImage1D #define glTexSubImage2D gl3wTexSubImage2D #define glTexSubImage3D gl3wTexSubImage3D #define glTextureBarrier gl3wTextureBarrier #define glTextureBuffer gl3wTextureBuffer #define glTextureBufferRange gl3wTextureBufferRange #define glTextureParameterIiv gl3wTextureParameterIiv #define glTextureParameterIuiv gl3wTextureParameterIuiv #define glTextureParameterf gl3wTextureParameterf #define glTextureParameterfv gl3wTextureParameterfv #define glTextureParameteri gl3wTextureParameteri #define glTextureParameteriv gl3wTextureParameteriv #define glTextureStorage1D gl3wTextureStorage1D #define glTextureStorage2D gl3wTextureStorage2D #define glTextureStorage2DMultisample gl3wTextureStorage2DMultisample #define glTextureStorage3D gl3wTextureStorage3D #define glTextureStorage3DMultisample gl3wTextureStorage3DMultisample #define glTextureSubImage1D gl3wTextureSubImage1D #define glTextureSubImage2D gl3wTextureSubImage2D #define glTextureSubImage3D gl3wTextureSubImage3D #define glTextureView gl3wTextureView #define glTransformFeedbackBufferBase gl3wTransformFeedbackBufferBase #define glTransformFeedbackBufferRange gl3wTransformFeedbackBufferRange #define glTransformFeedbackVaryings gl3wTransformFeedbackVaryings #define glUniform1d gl3wUniform1d #define glUniform1dv gl3wUniform1dv #define glUniform1f gl3wUniform1f #define glUniform1fv gl3wUniform1fv #define glUniform1i gl3wUniform1i #define glUniform1iv gl3wUniform1iv #define glUniform1ui gl3wUniform1ui #define glUniform1uiv gl3wUniform1uiv #define glUniform2d gl3wUniform2d #define glUniform2dv gl3wUniform2dv #define glUniform2f gl3wUniform2f #define glUniform2fv gl3wUniform2fv #define glUniform2i gl3wUniform2i #define glUniform2iv gl3wUniform2iv #define glUniform2ui gl3wUniform2ui #define glUniform2uiv gl3wUniform2uiv #define glUniform3d gl3wUniform3d #define glUniform3dv gl3wUniform3dv #define glUniform3f gl3wUniform3f #define glUniform3fv gl3wUniform3fv #define glUniform3i gl3wUniform3i #define glUniform3iv gl3wUniform3iv #define glUniform3ui gl3wUniform3ui #define glUniform3uiv gl3wUniform3uiv #define glUniform4d gl3wUniform4d #define glUniform4dv gl3wUniform4dv #define glUniform4f gl3wUniform4f #define glUniform4fv gl3wUniform4fv #define glUniform4i gl3wUniform4i #define glUniform4iv gl3wUniform4iv #define glUniform4ui gl3wUniform4ui #define glUniform4uiv gl3wUniform4uiv #define glUniformBlockBinding gl3wUniformBlockBinding #define glUniformHandleui64ARB gl3wUniformHandleui64ARB #define glUniformHandleui64vARB gl3wUniformHandleui64vARB #define glUniformMatrix2dv gl3wUniformMatrix2dv #define glUniformMatrix2fv gl3wUniformMatrix2fv #define glUniformMatrix2x3dv gl3wUniformMatrix2x3dv #define glUniformMatrix2x3fv gl3wUniformMatrix2x3fv #define glUniformMatrix2x4dv gl3wUniformMatrix2x4dv #define glUniformMatrix2x4fv gl3wUniformMatrix2x4fv #define glUniformMatrix3dv gl3wUniformMatrix3dv #define glUniformMatrix3fv gl3wUniformMatrix3fv #define glUniformMatrix3x2dv gl3wUniformMatrix3x2dv #define glUniformMatrix3x2fv gl3wUniformMatrix3x2fv #define glUniformMatrix3x4dv gl3wUniformMatrix3x4dv #define glUniformMatrix3x4fv gl3wUniformMatrix3x4fv #define glUniformMatrix4dv gl3wUniformMatrix4dv #define glUniformMatrix4fv gl3wUniformMatrix4fv #define glUniformMatrix4x2dv gl3wUniformMatrix4x2dv #define glUniformMatrix4x2fv gl3wUniformMatrix4x2fv #define glUniformMatrix4x3dv gl3wUniformMatrix4x3dv #define glUniformMatrix4x3fv gl3wUniformMatrix4x3fv #define glUniformSubroutinesuiv gl3wUniformSubroutinesuiv #define glUnmapBuffer gl3wUnmapBuffer #define glUnmapNamedBuffer gl3wUnmapNamedBuffer #define glUseProgram gl3wUseProgram #define glUseProgramStages gl3wUseProgramStages #define glValidateProgram gl3wValidateProgram #define glValidateProgramPipeline gl3wValidateProgramPipeline #define glVertexArrayAttribBinding gl3wVertexArrayAttribBinding #define glVertexArrayAttribFormat gl3wVertexArrayAttribFormat #define glVertexArrayAttribIFormat gl3wVertexArrayAttribIFormat #define glVertexArrayAttribLFormat gl3wVertexArrayAttribLFormat #define glVertexArrayBindingDivisor gl3wVertexArrayBindingDivisor #define glVertexArrayElementBuffer gl3wVertexArrayElementBuffer #define glVertexArrayVertexBuffer gl3wVertexArrayVertexBuffer #define glVertexArrayVertexBuffers gl3wVertexArrayVertexBuffers #define glVertexAttrib1d gl3wVertexAttrib1d #define glVertexAttrib1dv gl3wVertexAttrib1dv #define glVertexAttrib1f gl3wVertexAttrib1f #define glVertexAttrib1fv gl3wVertexAttrib1fv #define glVertexAttrib1s gl3wVertexAttrib1s #define glVertexAttrib1sv gl3wVertexAttrib1sv #define glVertexAttrib2d gl3wVertexAttrib2d #define glVertexAttrib2dv gl3wVertexAttrib2dv #define glVertexAttrib2f gl3wVertexAttrib2f #define glVertexAttrib2fv gl3wVertexAttrib2fv #define glVertexAttrib2s gl3wVertexAttrib2s #define glVertexAttrib2sv gl3wVertexAttrib2sv #define glVertexAttrib3d gl3wVertexAttrib3d #define glVertexAttrib3dv gl3wVertexAttrib3dv #define glVertexAttrib3f gl3wVertexAttrib3f #define glVertexAttrib3fv gl3wVertexAttrib3fv #define glVertexAttrib3s gl3wVertexAttrib3s #define glVertexAttrib3sv gl3wVertexAttrib3sv #define glVertexAttrib4Nbv gl3wVertexAttrib4Nbv #define glVertexAttrib4Niv gl3wVertexAttrib4Niv #define glVertexAttrib4Nsv gl3wVertexAttrib4Nsv #define glVertexAttrib4Nub gl3wVertexAttrib4Nub #define glVertexAttrib4Nubv gl3wVertexAttrib4Nubv #define glVertexAttrib4Nuiv gl3wVertexAttrib4Nuiv #define glVertexAttrib4Nusv gl3wVertexAttrib4Nusv #define glVertexAttrib4bv gl3wVertexAttrib4bv #define glVertexAttrib4d gl3wVertexAttrib4d #define glVertexAttrib4dv gl3wVertexAttrib4dv #define glVertexAttrib4f gl3wVertexAttrib4f #define glVertexAttrib4fv gl3wVertexAttrib4fv #define glVertexAttrib4iv gl3wVertexAttrib4iv #define glVertexAttrib4s gl3wVertexAttrib4s #define glVertexAttrib4sv gl3wVertexAttrib4sv #define glVertexAttrib4ubv gl3wVertexAttrib4ubv #define glVertexAttrib4uiv gl3wVertexAttrib4uiv #define glVertexAttrib4usv gl3wVertexAttrib4usv #define glVertexAttribBinding gl3wVertexAttribBinding #define glVertexAttribDivisor gl3wVertexAttribDivisor #define glVertexAttribFormat gl3wVertexAttribFormat #define glVertexAttribI1i gl3wVertexAttribI1i #define glVertexAttribI1iv gl3wVertexAttribI1iv #define glVertexAttribI1ui gl3wVertexAttribI1ui #define glVertexAttribI1uiv gl3wVertexAttribI1uiv #define glVertexAttribI2i gl3wVertexAttribI2i #define glVertexAttribI2iv gl3wVertexAttribI2iv #define glVertexAttribI2ui gl3wVertexAttribI2ui #define glVertexAttribI2uiv gl3wVertexAttribI2uiv #define glVertexAttribI3i gl3wVertexAttribI3i #define glVertexAttribI3iv gl3wVertexAttribI3iv #define glVertexAttribI3ui gl3wVertexAttribI3ui #define glVertexAttribI3uiv gl3wVertexAttribI3uiv #define glVertexAttribI4bv gl3wVertexAttribI4bv #define glVertexAttribI4i gl3wVertexAttribI4i #define glVertexAttribI4iv gl3wVertexAttribI4iv #define glVertexAttribI4sv gl3wVertexAttribI4sv #define glVertexAttribI4ubv gl3wVertexAttribI4ubv #define glVertexAttribI4ui gl3wVertexAttribI4ui #define glVertexAttribI4uiv gl3wVertexAttribI4uiv #define glVertexAttribI4usv gl3wVertexAttribI4usv #define glVertexAttribIFormat gl3wVertexAttribIFormat #define glVertexAttribIPointer gl3wVertexAttribIPointer #define glVertexAttribL1d gl3wVertexAttribL1d #define glVertexAttribL1dv gl3wVertexAttribL1dv #define glVertexAttribL1ui64ARB gl3wVertexAttribL1ui64ARB #define glVertexAttribL1ui64vARB gl3wVertexAttribL1ui64vARB #define glVertexAttribL2d gl3wVertexAttribL2d #define glVertexAttribL2dv gl3wVertexAttribL2dv #define glVertexAttribL3d gl3wVertexAttribL3d #define glVertexAttribL3dv gl3wVertexAttribL3dv #define glVertexAttribL4d gl3wVertexAttribL4d #define glVertexAttribL4dv gl3wVertexAttribL4dv #define glVertexAttribLFormat gl3wVertexAttribLFormat #define glVertexAttribLPointer gl3wVertexAttribLPointer #define glVertexAttribP1ui gl3wVertexAttribP1ui #define glVertexAttribP1uiv gl3wVertexAttribP1uiv #define glVertexAttribP2ui gl3wVertexAttribP2ui #define glVertexAttribP2uiv gl3wVertexAttribP2uiv #define glVertexAttribP3ui gl3wVertexAttribP3ui #define glVertexAttribP3uiv gl3wVertexAttribP3uiv #define glVertexAttribP4ui gl3wVertexAttribP4ui #define glVertexAttribP4uiv gl3wVertexAttribP4uiv #define glVertexAttribPointer gl3wVertexAttribPointer #define glVertexBindingDivisor gl3wVertexBindingDivisor #define glViewport gl3wViewport #define glViewportArrayv gl3wViewportArrayv #define glViewportIndexedf gl3wViewportIndexedf #define glViewportIndexedfv gl3wViewportIndexedfv #define glWaitSync gl3wWaitSync #endif // __gl3w_h_ ================================================ FILE: samples/gl3w/include/GL/glcorearb.h ================================================ #ifndef __glcorearb_h_ #define __glcorearb_h_ 1 #ifdef __cplusplus extern "C" { #endif /* ** Copyright (c) 2013-2015 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the ** "Materials"), to deal in the Materials without restriction, including ** without limitation the rights to use, copy, modify, merge, publish, ** distribute, sublicense, and/or sell copies of the Materials, and to ** permit persons to whom the Materials are furnished to do so, subject to ** the following conditions: ** ** The above copyright notice and this permission notice shall be included ** in all copies or substantial portions of the Materials. ** ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ /* ** This header is generated from the Khronos OpenGL / OpenGL ES XML ** API Registry. The current version of the Registry, generator scripts ** used to make the header, and the header can be found at ** http://www.opengl.org/registry/ ** ** Khronos $Revision: 31597 $ on $Date: 2015-06-25 16:32:35 -0400 (Thu, 25 Jun 2015) $ */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif #include #endif #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif #ifndef GLAPI #define GLAPI extern #endif /* glcorearb.h is for use with OpenGL core profile implementations. ** It should should be placed in the same directory as gl.h and ** included as . ** ** glcorearb.h includes only APIs in the latest OpenGL core profile ** implementation together with APIs in newer ARB extensions which ** can be supported by the core profile. It does not, and never will ** include functionality removed from the core profile, such as ** fixed-function vertex and fragment processing. ** ** Do not #include both and either of or ** in the same source file. */ /* Generated C header for: * API: gl * Profile: core * Versions considered: .* * Versions emitted: .* * Default extensions included: glcore * Additional extensions included: _nomatch_^ * Extensions removed: _nomatch_^ */ #ifndef GL_VERSION_1_0 #define GL_VERSION_1_0 1 typedef void GLvoid; typedef unsigned int GLenum; typedef float GLfloat; typedef int GLint; typedef int GLsizei; typedef unsigned int GLbitfield; typedef double GLdouble; typedef unsigned int GLuint; typedef unsigned char GLboolean; typedef unsigned char GLubyte; typedef void (APIENTRYP PFNGLCULLFACEPROC) (GLenum mode); typedef void (APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode); typedef void (APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode); typedef void (APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width); typedef void (APIENTRYP PFNGLPOINTSIZEPROC) (GLfloat size); typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode); typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); typedef void (APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum buf); typedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask); typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); typedef void (APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s); typedef void (APIENTRYP PFNGLCLEARDEPTHPROC) (GLdouble depth); typedef void (APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask); typedef void (APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); typedef void (APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag); typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap); typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap); typedef void (APIENTRYP PFNGLFINISHPROC) (void); typedef void (APIENTRYP PFNGLFLUSHPROC) (void); typedef void (APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor); typedef void (APIENTRYP PFNGLLOGICOPPROC) (GLenum opcode); typedef void (APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); typedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass); typedef void (APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func); typedef void (APIENTRYP PFNGLPIXELSTOREFPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLREADBUFFERPROC) (GLenum src); typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); typedef void (APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data); typedef void (APIENTRYP PFNGLGETDOUBLEVPROC) (GLenum pname, GLdouble *data); typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void); typedef void (APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data); typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data); typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, void *pixels); typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params); typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); typedef void (APIENTRYP PFNGLDEPTHRANGEPROC) (GLdouble near, GLdouble far); typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glCullFace (GLenum mode); GLAPI void APIENTRY glFrontFace (GLenum mode); GLAPI void APIENTRY glHint (GLenum target, GLenum mode); GLAPI void APIENTRY glLineWidth (GLfloat width); GLAPI void APIENTRY glPointSize (GLfloat size); GLAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode); GLAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); GLAPI void APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); GLAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); GLAPI void APIENTRY glDrawBuffer (GLenum buf); GLAPI void APIENTRY glClear (GLbitfield mask); GLAPI void APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); GLAPI void APIENTRY glClearStencil (GLint s); GLAPI void APIENTRY glClearDepth (GLdouble depth); GLAPI void APIENTRY glStencilMask (GLuint mask); GLAPI void APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); GLAPI void APIENTRY glDepthMask (GLboolean flag); GLAPI void APIENTRY glDisable (GLenum cap); GLAPI void APIENTRY glEnable (GLenum cap); GLAPI void APIENTRY glFinish (void); GLAPI void APIENTRY glFlush (void); GLAPI void APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); GLAPI void APIENTRY glLogicOp (GLenum opcode); GLAPI void APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); GLAPI void APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); GLAPI void APIENTRY glDepthFunc (GLenum func); GLAPI void APIENTRY glPixelStoref (GLenum pname, GLfloat param); GLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param); GLAPI void APIENTRY glReadBuffer (GLenum src); GLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); GLAPI void APIENTRY glGetBooleanv (GLenum pname, GLboolean *data); GLAPI void APIENTRY glGetDoublev (GLenum pname, GLdouble *data); GLAPI GLenum APIENTRY glGetError (void); GLAPI void APIENTRY glGetFloatv (GLenum pname, GLfloat *data); GLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *data); GLAPI const GLubyte *APIENTRY glGetString (GLenum name); GLAPI void APIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, void *pixels); GLAPI void APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); GLAPI GLboolean APIENTRY glIsEnabled (GLenum cap); GLAPI void APIENTRY glDepthRange (GLdouble near, GLdouble far); GLAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); #endif #endif /* GL_VERSION_1_0 */ #ifndef GL_VERSION_1_1 #define GL_VERSION_1_1 1 typedef float GLclampf; typedef double GLclampd; #define GL_DEPTH_BUFFER_BIT 0x00000100 #define GL_STENCIL_BUFFER_BIT 0x00000400 #define GL_COLOR_BUFFER_BIT 0x00004000 #define GL_FALSE 0 #define GL_TRUE 1 #define GL_POINTS 0x0000 #define GL_LINES 0x0001 #define GL_LINE_LOOP 0x0002 #define GL_LINE_STRIP 0x0003 #define GL_TRIANGLES 0x0004 #define GL_TRIANGLE_STRIP 0x0005 #define GL_TRIANGLE_FAN 0x0006 #define GL_QUADS 0x0007 #define GL_NEVER 0x0200 #define GL_LESS 0x0201 #define GL_EQUAL 0x0202 #define GL_LEQUAL 0x0203 #define GL_GREATER 0x0204 #define GL_NOTEQUAL 0x0205 #define GL_GEQUAL 0x0206 #define GL_ALWAYS 0x0207 #define GL_ZERO 0 #define GL_ONE 1 #define GL_SRC_COLOR 0x0300 #define GL_ONE_MINUS_SRC_COLOR 0x0301 #define GL_SRC_ALPHA 0x0302 #define GL_ONE_MINUS_SRC_ALPHA 0x0303 #define GL_DST_ALPHA 0x0304 #define GL_ONE_MINUS_DST_ALPHA 0x0305 #define GL_DST_COLOR 0x0306 #define GL_ONE_MINUS_DST_COLOR 0x0307 #define GL_SRC_ALPHA_SATURATE 0x0308 #define GL_NONE 0 #define GL_FRONT_LEFT 0x0400 #define GL_FRONT_RIGHT 0x0401 #define GL_BACK_LEFT 0x0402 #define GL_BACK_RIGHT 0x0403 #define GL_FRONT 0x0404 #define GL_BACK 0x0405 #define GL_LEFT 0x0406 #define GL_RIGHT 0x0407 #define GL_FRONT_AND_BACK 0x0408 #define GL_NO_ERROR 0 #define GL_INVALID_ENUM 0x0500 #define GL_INVALID_VALUE 0x0501 #define GL_INVALID_OPERATION 0x0502 #define GL_OUT_OF_MEMORY 0x0505 #define GL_CW 0x0900 #define GL_CCW 0x0901 #define GL_POINT_SIZE 0x0B11 #define GL_POINT_SIZE_RANGE 0x0B12 #define GL_POINT_SIZE_GRANULARITY 0x0B13 #define GL_LINE_SMOOTH 0x0B20 #define GL_LINE_WIDTH 0x0B21 #define GL_LINE_WIDTH_RANGE 0x0B22 #define GL_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_POLYGON_MODE 0x0B40 #define GL_POLYGON_SMOOTH 0x0B41 #define GL_CULL_FACE 0x0B44 #define GL_CULL_FACE_MODE 0x0B45 #define GL_FRONT_FACE 0x0B46 #define GL_DEPTH_RANGE 0x0B70 #define GL_DEPTH_TEST 0x0B71 #define GL_DEPTH_WRITEMASK 0x0B72 #define GL_DEPTH_CLEAR_VALUE 0x0B73 #define GL_DEPTH_FUNC 0x0B74 #define GL_STENCIL_TEST 0x0B90 #define GL_STENCIL_CLEAR_VALUE 0x0B91 #define GL_STENCIL_FUNC 0x0B92 #define GL_STENCIL_VALUE_MASK 0x0B93 #define GL_STENCIL_FAIL 0x0B94 #define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 #define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 #define GL_STENCIL_REF 0x0B97 #define GL_STENCIL_WRITEMASK 0x0B98 #define GL_VIEWPORT 0x0BA2 #define GL_DITHER 0x0BD0 #define GL_BLEND_DST 0x0BE0 #define GL_BLEND_SRC 0x0BE1 #define GL_BLEND 0x0BE2 #define GL_LOGIC_OP_MODE 0x0BF0 #define GL_COLOR_LOGIC_OP 0x0BF2 #define GL_DRAW_BUFFER 0x0C01 #define GL_READ_BUFFER 0x0C02 #define GL_SCISSOR_BOX 0x0C10 #define GL_SCISSOR_TEST 0x0C11 #define GL_COLOR_CLEAR_VALUE 0x0C22 #define GL_COLOR_WRITEMASK 0x0C23 #define GL_DOUBLEBUFFER 0x0C32 #define GL_STEREO 0x0C33 #define GL_LINE_SMOOTH_HINT 0x0C52 #define GL_POLYGON_SMOOTH_HINT 0x0C53 #define GL_UNPACK_SWAP_BYTES 0x0CF0 #define GL_UNPACK_LSB_FIRST 0x0CF1 #define GL_UNPACK_ROW_LENGTH 0x0CF2 #define GL_UNPACK_SKIP_ROWS 0x0CF3 #define GL_UNPACK_SKIP_PIXELS 0x0CF4 #define GL_UNPACK_ALIGNMENT 0x0CF5 #define GL_PACK_SWAP_BYTES 0x0D00 #define GL_PACK_LSB_FIRST 0x0D01 #define GL_PACK_ROW_LENGTH 0x0D02 #define GL_PACK_SKIP_ROWS 0x0D03 #define GL_PACK_SKIP_PIXELS 0x0D04 #define GL_PACK_ALIGNMENT 0x0D05 #define GL_MAX_TEXTURE_SIZE 0x0D33 #define GL_MAX_VIEWPORT_DIMS 0x0D3A #define GL_SUBPIXEL_BITS 0x0D50 #define GL_TEXTURE_1D 0x0DE0 #define GL_TEXTURE_2D 0x0DE1 #define GL_POLYGON_OFFSET_UNITS 0x2A00 #define GL_POLYGON_OFFSET_POINT 0x2A01 #define GL_POLYGON_OFFSET_LINE 0x2A02 #define GL_POLYGON_OFFSET_FILL 0x8037 #define GL_POLYGON_OFFSET_FACTOR 0x8038 #define GL_TEXTURE_BINDING_1D 0x8068 #define GL_TEXTURE_BINDING_2D 0x8069 #define GL_TEXTURE_WIDTH 0x1000 #define GL_TEXTURE_HEIGHT 0x1001 #define GL_TEXTURE_INTERNAL_FORMAT 0x1003 #define GL_TEXTURE_BORDER_COLOR 0x1004 #define GL_TEXTURE_RED_SIZE 0x805C #define GL_TEXTURE_GREEN_SIZE 0x805D #define GL_TEXTURE_BLUE_SIZE 0x805E #define GL_TEXTURE_ALPHA_SIZE 0x805F #define GL_DONT_CARE 0x1100 #define GL_FASTEST 0x1101 #define GL_NICEST 0x1102 #define GL_BYTE 0x1400 #define GL_UNSIGNED_BYTE 0x1401 #define GL_SHORT 0x1402 #define GL_UNSIGNED_SHORT 0x1403 #define GL_INT 0x1404 #define GL_UNSIGNED_INT 0x1405 #define GL_FLOAT 0x1406 #define GL_DOUBLE 0x140A #define GL_STACK_OVERFLOW 0x0503 #define GL_STACK_UNDERFLOW 0x0504 #define GL_CLEAR 0x1500 #define GL_AND 0x1501 #define GL_AND_REVERSE 0x1502 #define GL_COPY 0x1503 #define GL_AND_INVERTED 0x1504 #define GL_NOOP 0x1505 #define GL_XOR 0x1506 #define GL_OR 0x1507 #define GL_NOR 0x1508 #define GL_EQUIV 0x1509 #define GL_INVERT 0x150A #define GL_OR_REVERSE 0x150B #define GL_COPY_INVERTED 0x150C #define GL_OR_INVERTED 0x150D #define GL_NAND 0x150E #define GL_SET 0x150F #define GL_TEXTURE 0x1702 #define GL_COLOR 0x1800 #define GL_DEPTH 0x1801 #define GL_STENCIL 0x1802 #define GL_STENCIL_INDEX 0x1901 #define GL_DEPTH_COMPONENT 0x1902 #define GL_RED 0x1903 #define GL_GREEN 0x1904 #define GL_BLUE 0x1905 #define GL_ALPHA 0x1906 #define GL_RGB 0x1907 #define GL_RGBA 0x1908 #define GL_POINT 0x1B00 #define GL_LINE 0x1B01 #define GL_FILL 0x1B02 #define GL_KEEP 0x1E00 #define GL_REPLACE 0x1E01 #define GL_INCR 0x1E02 #define GL_DECR 0x1E03 #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 #define GL_EXTENSIONS 0x1F03 #define GL_NEAREST 0x2600 #define GL_LINEAR 0x2601 #define GL_NEAREST_MIPMAP_NEAREST 0x2700 #define GL_LINEAR_MIPMAP_NEAREST 0x2701 #define GL_NEAREST_MIPMAP_LINEAR 0x2702 #define GL_LINEAR_MIPMAP_LINEAR 0x2703 #define GL_TEXTURE_MAG_FILTER 0x2800 #define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_TEXTURE_WRAP_S 0x2802 #define GL_TEXTURE_WRAP_T 0x2803 #define GL_PROXY_TEXTURE_1D 0x8063 #define GL_PROXY_TEXTURE_2D 0x8064 #define GL_REPEAT 0x2901 #define GL_R3_G3_B2 0x2A10 #define GL_RGB4 0x804F #define GL_RGB5 0x8050 #define GL_RGB8 0x8051 #define GL_RGB10 0x8052 #define GL_RGB12 0x8053 #define GL_RGB16 0x8054 #define GL_RGBA2 0x8055 #define GL_RGBA4 0x8056 #define GL_RGB5_A1 0x8057 #define GL_RGBA8 0x8058 #define GL_RGB10_A2 0x8059 #define GL_RGBA12 0x805A #define GL_RGBA16 0x805B #define GL_VERTEX_ARRAY 0x8074 typedef void (APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices); typedef void (APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params); typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units); typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); GLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); GLAPI void APIENTRY glGetPointerv (GLenum pname, void **params); GLAPI void APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); GLAPI void APIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); GLAPI void APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); GLAPI void APIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); GLAPI void APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); GLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture); GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures); GLAPI GLboolean APIENTRY glIsTexture (GLuint texture); #endif #endif /* GL_VERSION_1_1 */ #ifndef GL_VERSION_1_2 #define GL_VERSION_1_2 1 #define GL_UNSIGNED_BYTE_3_3_2 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_INT_8_8_8_8 0x8035 #define GL_UNSIGNED_INT_10_10_10_2 0x8036 #define GL_TEXTURE_BINDING_3D 0x806A #define GL_PACK_SKIP_IMAGES 0x806B #define GL_PACK_IMAGE_HEIGHT 0x806C #define GL_UNPACK_SKIP_IMAGES 0x806D #define GL_UNPACK_IMAGE_HEIGHT 0x806E #define GL_TEXTURE_3D 0x806F #define GL_PROXY_TEXTURE_3D 0x8070 #define GL_TEXTURE_DEPTH 0x8071 #define GL_TEXTURE_WRAP_R 0x8072 #define GL_MAX_3D_TEXTURE_SIZE 0x8073 #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 #define GL_MAX_ELEMENTS_VERTICES 0x80E8 #define GL_MAX_ELEMENTS_INDICES 0x80E9 #define GL_CLAMP_TO_EDGE 0x812F #define GL_TEXTURE_MIN_LOD 0x813A #define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_BASE_LEVEL 0x813C #define GL_TEXTURE_MAX_LEVEL 0x813D #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); typedef 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); typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); GLAPI 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); GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif #endif /* GL_VERSION_1_2 */ #ifndef GL_VERSION_1_3 #define GL_VERSION_1_3 1 #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 #define GL_TEXTURE2 0x84C2 #define GL_TEXTURE3 0x84C3 #define GL_TEXTURE4 0x84C4 #define GL_TEXTURE5 0x84C5 #define GL_TEXTURE6 0x84C6 #define GL_TEXTURE7 0x84C7 #define GL_TEXTURE8 0x84C8 #define GL_TEXTURE9 0x84C9 #define GL_TEXTURE10 0x84CA #define GL_TEXTURE11 0x84CB #define GL_TEXTURE12 0x84CC #define GL_TEXTURE13 0x84CD #define GL_TEXTURE14 0x84CE #define GL_TEXTURE15 0x84CF #define GL_TEXTURE16 0x84D0 #define GL_TEXTURE17 0x84D1 #define GL_TEXTURE18 0x84D2 #define GL_TEXTURE19 0x84D3 #define GL_TEXTURE20 0x84D4 #define GL_TEXTURE21 0x84D5 #define GL_TEXTURE22 0x84D6 #define GL_TEXTURE23 0x84D7 #define GL_TEXTURE24 0x84D8 #define GL_TEXTURE25 0x84D9 #define GL_TEXTURE26 0x84DA #define GL_TEXTURE27 0x84DB #define GL_TEXTURE28 0x84DC #define GL_TEXTURE29 0x84DD #define GL_TEXTURE30 0x84DE #define GL_TEXTURE31 0x84DF #define GL_ACTIVE_TEXTURE 0x84E0 #define GL_MULTISAMPLE 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #define GL_SAMPLE_ALPHA_TO_ONE 0x809F #define GL_SAMPLE_COVERAGE 0x80A0 #define GL_SAMPLE_BUFFERS 0x80A8 #define GL_SAMPLES 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE 0x80AA #define GL_SAMPLE_COVERAGE_INVERT 0x80AB #define GL_TEXTURE_CUBE_MAP 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C #define GL_COMPRESSED_RGB 0x84ED #define GL_COMPRESSED_RGBA 0x84EE #define GL_TEXTURE_COMPRESSION_HINT 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 #define GL_TEXTURE_COMPRESSED 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define GL_CLAMP_TO_BORDER 0x812D typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); typedef 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); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glActiveTexture (GLenum texture); GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); GLAPI 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); GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, void *img); #endif #endif /* GL_VERSION_1_3 */ #ifndef GL_VERSION_1_4 #define GL_VERSION_1_4 1 #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA #define GL_BLEND_SRC_ALPHA 0x80CB #define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_DEPTH_COMPONENT24 0x81A6 #define GL_DEPTH_COMPONENT32 0x81A7 #define GL_MIRRORED_REPEAT 0x8370 #define GL_MAX_TEXTURE_LOD_BIAS 0x84FD #define GL_TEXTURE_LOD_BIAS 0x8501 #define GL_INCR_WRAP 0x8507 #define GL_DECR_WRAP 0x8508 #define GL_TEXTURE_DEPTH_SIZE 0x884A #define GL_TEXTURE_COMPARE_MODE 0x884C #define GL_TEXTURE_COMPARE_FUNC 0x884D #define GL_FUNC_ADD 0x8006 #define GL_FUNC_SUBTRACT 0x800A #define GL_FUNC_REVERSE_SUBTRACT 0x800B #define GL_MIN 0x8007 #define GL_MAX 0x8008 #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); GLAPI void APIENTRY glBlendEquation (GLenum mode); #endif #endif /* GL_VERSION_1_4 */ #ifndef GL_VERSION_1_5 #define GL_VERSION_1_5 1 #include typedef ptrdiff_t GLsizeiptr; typedef ptrdiff_t GLintptr; #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_QUERY_COUNTER_BITS 0x8864 #define GL_CURRENT_QUERY 0x8865 #define GL_QUERY_RESULT 0x8866 #define GL_QUERY_RESULT_AVAILABLE 0x8867 #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F #define GL_READ_ONLY 0x88B8 #define GL_WRITE_ONLY 0x88B9 #define GL_READ_WRITE 0x88BA #define GL_BUFFER_ACCESS 0x88BB #define GL_BUFFER_MAPPED 0x88BC #define GL_BUFFER_MAP_POINTER 0x88BD #define GL_STREAM_DRAW 0x88E0 #define GL_STREAM_READ 0x88E1 #define GL_STREAM_COPY 0x88E2 #define GL_STATIC_DRAW 0x88E4 #define GL_STATIC_READ 0x88E5 #define GL_STATIC_COPY 0x88E6 #define GL_DYNAMIC_DRAW 0x88E8 #define GL_DYNAMIC_READ 0x88E9 #define GL_DYNAMIC_COPY 0x88EA #define GL_SAMPLES_PASSED 0x8914 #define GL_SRC1_ALPHA 0x8589 typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); GLAPI GLboolean APIENTRY glIsQuery (GLuint id); GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); GLAPI void APIENTRY glEndQuery (GLenum target); GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, void *data); GLAPI void *APIENTRY glMapBuffer (GLenum target, GLenum access); GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); #endif #endif /* GL_VERSION_1_5 */ #ifndef GL_VERSION_2_0 #define GL_VERSION_2_0 1 typedef char GLchar; typedef short GLshort; typedef signed char GLbyte; typedef unsigned short GLushort; #define GL_BLEND_EQUATION_RGB 0x8009 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 #define GL_CURRENT_VERTEX_ATTRIB 0x8626 #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 #define GL_STENCIL_BACK_FUNC 0x8800 #define GL_STENCIL_BACK_FAIL 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 #define GL_MAX_DRAW_BUFFERS 0x8824 #define GL_DRAW_BUFFER0 0x8825 #define GL_DRAW_BUFFER1 0x8826 #define GL_DRAW_BUFFER2 0x8827 #define GL_DRAW_BUFFER3 0x8828 #define GL_DRAW_BUFFER4 0x8829 #define GL_DRAW_BUFFER5 0x882A #define GL_DRAW_BUFFER6 0x882B #define GL_DRAW_BUFFER7 0x882C #define GL_DRAW_BUFFER8 0x882D #define GL_DRAW_BUFFER9 0x882E #define GL_DRAW_BUFFER10 0x882F #define GL_DRAW_BUFFER11 0x8830 #define GL_DRAW_BUFFER12 0x8831 #define GL_DRAW_BUFFER13 0x8832 #define GL_DRAW_BUFFER14 0x8833 #define GL_DRAW_BUFFER15 0x8834 #define GL_BLEND_EQUATION_ALPHA 0x883D #define GL_MAX_VERTEX_ATTRIBS 0x8869 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A #define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 #define GL_FRAGMENT_SHADER 0x8B30 #define GL_VERTEX_SHADER 0x8B31 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A #define GL_MAX_VARYING_FLOATS 0x8B4B #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D #define GL_SHADER_TYPE 0x8B4F #define GL_FLOAT_VEC2 0x8B50 #define GL_FLOAT_VEC3 0x8B51 #define GL_FLOAT_VEC4 0x8B52 #define GL_INT_VEC2 0x8B53 #define GL_INT_VEC3 0x8B54 #define GL_INT_VEC4 0x8B55 #define GL_BOOL 0x8B56 #define GL_BOOL_VEC2 0x8B57 #define GL_BOOL_VEC3 0x8B58 #define GL_BOOL_VEC4 0x8B59 #define GL_FLOAT_MAT2 0x8B5A #define GL_FLOAT_MAT3 0x8B5B #define GL_FLOAT_MAT4 0x8B5C #define GL_SAMPLER_1D 0x8B5D #define GL_SAMPLER_2D 0x8B5E #define GL_SAMPLER_3D 0x8B5F #define GL_SAMPLER_CUBE 0x8B60 #define GL_SAMPLER_1D_SHADOW 0x8B61 #define GL_SAMPLER_2D_SHADOW 0x8B62 #define GL_DELETE_STATUS 0x8B80 #define GL_COMPILE_STATUS 0x8B81 #define GL_LINK_STATUS 0x8B82 #define GL_VALIDATE_STATUS 0x8B83 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_ATTACHED_SHADERS 0x8B85 #define GL_ACTIVE_UNIFORMS 0x8B86 #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 #define GL_SHADER_SOURCE_LENGTH 0x8B88 #define GL_ACTIVE_ATTRIBUTES 0x8B89 #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B #define GL_SHADING_LANGUAGE_VERSION 0x8B8C #define GL_CURRENT_PROGRAM 0x8B8D #define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 #define GL_LOWER_LEFT 0x8CA1 #define GL_UPPER_LEFT 0x8CA2 #define GL_STENCIL_BACK_REF 0x8CA3 #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); GLAPI void APIENTRY glCompileShader (GLuint shader); GLAPI GLuint APIENTRY glCreateProgram (void); GLAPI GLuint APIENTRY glCreateShader (GLenum type); GLAPI void APIENTRY glDeleteProgram (GLuint program); GLAPI void APIENTRY glDeleteShader (GLuint shader); GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); GLAPI GLboolean APIENTRY glIsProgram (GLuint program); GLAPI GLboolean APIENTRY glIsShader (GLuint shader); GLAPI void APIENTRY glLinkProgram (GLuint program); GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); GLAPI void APIENTRY glUseProgram (GLuint program); GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glValidateProgram (GLuint program); GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); #endif #endif /* GL_VERSION_2_0 */ #ifndef GL_VERSION_2_1 #define GL_VERSION_2_1 1 #define GL_PIXEL_PACK_BUFFER 0x88EB #define GL_PIXEL_UNPACK_BUFFER 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF #define GL_FLOAT_MAT2x3 0x8B65 #define GL_FLOAT_MAT2x4 0x8B66 #define GL_FLOAT_MAT3x2 0x8B67 #define GL_FLOAT_MAT3x4 0x8B68 #define GL_FLOAT_MAT4x2 0x8B69 #define GL_FLOAT_MAT4x3 0x8B6A #define GL_SRGB 0x8C40 #define GL_SRGB8 0x8C41 #define GL_SRGB_ALPHA 0x8C42 #define GL_SRGB8_ALPHA8 0x8C43 #define GL_COMPRESSED_SRGB 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); #endif #endif /* GL_VERSION_2_1 */ #ifndef GL_VERSION_3_0 #define GL_VERSION_3_0 1 typedef unsigned short GLhalf; #define GL_COMPARE_REF_TO_TEXTURE 0x884E #define GL_CLIP_DISTANCE0 0x3000 #define GL_CLIP_DISTANCE1 0x3001 #define GL_CLIP_DISTANCE2 0x3002 #define GL_CLIP_DISTANCE3 0x3003 #define GL_CLIP_DISTANCE4 0x3004 #define GL_CLIP_DISTANCE5 0x3005 #define GL_CLIP_DISTANCE6 0x3006 #define GL_CLIP_DISTANCE7 0x3007 #define GL_MAX_CLIP_DISTANCES 0x0D32 #define GL_MAJOR_VERSION 0x821B #define GL_MINOR_VERSION 0x821C #define GL_NUM_EXTENSIONS 0x821D #define GL_CONTEXT_FLAGS 0x821E #define GL_COMPRESSED_RED 0x8225 #define GL_COMPRESSED_RG 0x8226 #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 #define GL_RGBA32F 0x8814 #define GL_RGB32F 0x8815 #define GL_RGBA16F 0x881A #define GL_RGB16F 0x881B #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD #define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF #define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 #define GL_CLAMP_READ_COLOR 0x891C #define GL_FIXED_ONLY 0x891D #define GL_MAX_VARYING_COMPONENTS 0x8B4B #define GL_TEXTURE_1D_ARRAY 0x8C18 #define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 #define GL_TEXTURE_2D_ARRAY 0x8C1A #define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B #define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C #define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D #define GL_R11F_G11F_B10F 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B #define GL_RGB9_E5 0x8C3D #define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E #define GL_TEXTURE_SHARED_SIZE 0x8C3F #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 #define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 #define GL_PRIMITIVES_GENERATED 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 #define GL_RASTERIZER_DISCARD 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B #define GL_INTERLEAVED_ATTRIBS 0x8C8C #define GL_SEPARATE_ATTRIBS 0x8C8D #define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F #define GL_RGBA32UI 0x8D70 #define GL_RGB32UI 0x8D71 #define GL_RGBA16UI 0x8D76 #define GL_RGB16UI 0x8D77 #define GL_RGBA8UI 0x8D7C #define GL_RGB8UI 0x8D7D #define GL_RGBA32I 0x8D82 #define GL_RGB32I 0x8D83 #define GL_RGBA16I 0x8D88 #define GL_RGB16I 0x8D89 #define GL_RGBA8I 0x8D8E #define GL_RGB8I 0x8D8F #define GL_RED_INTEGER 0x8D94 #define GL_GREEN_INTEGER 0x8D95 #define GL_BLUE_INTEGER 0x8D96 #define GL_RGB_INTEGER 0x8D98 #define GL_RGBA_INTEGER 0x8D99 #define GL_BGR_INTEGER 0x8D9A #define GL_BGRA_INTEGER 0x8D9B #define GL_SAMPLER_1D_ARRAY 0x8DC0 #define GL_SAMPLER_2D_ARRAY 0x8DC1 #define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 #define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 #define GL_SAMPLER_CUBE_SHADOW 0x8DC5 #define GL_UNSIGNED_INT_VEC2 0x8DC6 #define GL_UNSIGNED_INT_VEC3 0x8DC7 #define GL_UNSIGNED_INT_VEC4 0x8DC8 #define GL_INT_SAMPLER_1D 0x8DC9 #define GL_INT_SAMPLER_2D 0x8DCA #define GL_INT_SAMPLER_3D 0x8DCB #define GL_INT_SAMPLER_CUBE 0x8DCC #define GL_INT_SAMPLER_1D_ARRAY 0x8DCE #define GL_INT_SAMPLER_2D_ARRAY 0x8DCF #define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 #define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 #define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 #define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 #define GL_QUERY_WAIT 0x8E13 #define GL_QUERY_NO_WAIT 0x8E14 #define GL_QUERY_BY_REGION_WAIT 0x8E15 #define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 #define GL_BUFFER_ACCESS_FLAGS 0x911F #define GL_BUFFER_MAP_LENGTH 0x9120 #define GL_BUFFER_MAP_OFFSET 0x9121 #define GL_DEPTH_COMPONENT32F 0x8CAC #define GL_DEPTH32F_STENCIL8 0x8CAD #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 #define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 #define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 #define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 #define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 #define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 #define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 #define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 #define GL_FRAMEBUFFER_DEFAULT 0x8218 #define GL_FRAMEBUFFER_UNDEFINED 0x8219 #define GL_DEPTH_STENCIL_ATTACHMENT 0x821A #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 #define GL_DEPTH_STENCIL 0x84F9 #define GL_UNSIGNED_INT_24_8 0x84FA #define GL_DEPTH24_STENCIL8 0x88F0 #define GL_TEXTURE_STENCIL_SIZE 0x88F1 #define GL_TEXTURE_RED_TYPE 0x8C10 #define GL_TEXTURE_GREEN_TYPE 0x8C11 #define GL_TEXTURE_BLUE_TYPE 0x8C12 #define GL_TEXTURE_ALPHA_TYPE 0x8C13 #define GL_TEXTURE_DEPTH_TYPE 0x8C16 #define GL_UNSIGNED_NORMALIZED 0x8C17 #define GL_FRAMEBUFFER_BINDING 0x8CA6 #define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 #define GL_RENDERBUFFER_BINDING 0x8CA7 #define GL_READ_FRAMEBUFFER 0x8CA8 #define GL_DRAW_FRAMEBUFFER 0x8CA9 #define GL_READ_FRAMEBUFFER_BINDING 0x8CAA #define GL_RENDERBUFFER_SAMPLES 0x8CAB #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD #define GL_MAX_COLOR_ATTACHMENTS 0x8CDF #define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_COLOR_ATTACHMENT1 0x8CE1 #define GL_COLOR_ATTACHMENT2 0x8CE2 #define GL_COLOR_ATTACHMENT3 0x8CE3 #define GL_COLOR_ATTACHMENT4 0x8CE4 #define GL_COLOR_ATTACHMENT5 0x8CE5 #define GL_COLOR_ATTACHMENT6 0x8CE6 #define GL_COLOR_ATTACHMENT7 0x8CE7 #define GL_COLOR_ATTACHMENT8 0x8CE8 #define GL_COLOR_ATTACHMENT9 0x8CE9 #define GL_COLOR_ATTACHMENT10 0x8CEA #define GL_COLOR_ATTACHMENT11 0x8CEB #define GL_COLOR_ATTACHMENT12 0x8CEC #define GL_COLOR_ATTACHMENT13 0x8CED #define GL_COLOR_ATTACHMENT14 0x8CEE #define GL_COLOR_ATTACHMENT15 0x8CEF #define GL_COLOR_ATTACHMENT16 0x8CF0 #define GL_COLOR_ATTACHMENT17 0x8CF1 #define GL_COLOR_ATTACHMENT18 0x8CF2 #define GL_COLOR_ATTACHMENT19 0x8CF3 #define GL_COLOR_ATTACHMENT20 0x8CF4 #define GL_COLOR_ATTACHMENT21 0x8CF5 #define GL_COLOR_ATTACHMENT22 0x8CF6 #define GL_COLOR_ATTACHMENT23 0x8CF7 #define GL_COLOR_ATTACHMENT24 0x8CF8 #define GL_COLOR_ATTACHMENT25 0x8CF9 #define GL_COLOR_ATTACHMENT26 0x8CFA #define GL_COLOR_ATTACHMENT27 0x8CFB #define GL_COLOR_ATTACHMENT28 0x8CFC #define GL_COLOR_ATTACHMENT29 0x8CFD #define GL_COLOR_ATTACHMENT30 0x8CFE #define GL_COLOR_ATTACHMENT31 0x8CFF #define GL_DEPTH_ATTACHMENT 0x8D00 #define GL_STENCIL_ATTACHMENT 0x8D20 #define GL_FRAMEBUFFER 0x8D40 #define GL_RENDERBUFFER 0x8D41 #define GL_RENDERBUFFER_WIDTH 0x8D42 #define GL_RENDERBUFFER_HEIGHT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 #define GL_STENCIL_INDEX1 0x8D46 #define GL_STENCIL_INDEX4 0x8D47 #define GL_STENCIL_INDEX8 0x8D48 #define GL_STENCIL_INDEX16 0x8D49 #define GL_RENDERBUFFER_RED_SIZE 0x8D50 #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 #define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 #define GL_MAX_SAMPLES 0x8D57 #define GL_FRAMEBUFFER_SRGB 0x8DB9 #define GL_HALF_FLOAT 0x140B #define GL_MAP_READ_BIT 0x0001 #define GL_MAP_WRITE_BIT 0x0002 #define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 #define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 #define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 #define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 #define GL_COMPRESSED_RED_RGTC1 0x8DBB #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC #define GL_COMPRESSED_RG_RGTC2 0x8DBD #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE #define GL_RG 0x8227 #define GL_RG_INTEGER 0x8228 #define GL_R8 0x8229 #define GL_R16 0x822A #define GL_RG8 0x822B #define GL_RG16 0x822C #define GL_R16F 0x822D #define GL_R32F 0x822E #define GL_RG16F 0x822F #define GL_RG32F 0x8230 #define GL_R8I 0x8231 #define GL_R8UI 0x8232 #define GL_R16I 0x8233 #define GL_R16UI 0x8234 #define GL_R32I 0x8235 #define GL_R32UI 0x8236 #define GL_RG8I 0x8237 #define GL_RG8UI 0x8238 #define GL_RG16I 0x8239 #define GL_RG16UI 0x823A #define GL_RG32I 0x823B #define GL_RG32UI 0x823C #define GL_VERTEX_ARRAY_BINDING 0x85B5 typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void *(APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); GLAPI void APIENTRY glEndTransformFeedback (void); GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); GLAPI void APIENTRY glEndConditionalRender (void); GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index); GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); GLAPI void APIENTRY glGenerateMipmap (GLenum target); GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); GLAPI void *APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); GLAPI void APIENTRY glBindVertexArray (GLuint array); GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); #endif #endif /* GL_VERSION_3_0 */ #ifndef GL_VERSION_3_1 #define GL_VERSION_3_1 1 #define GL_SAMPLER_2D_RECT 0x8B63 #define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 #define GL_SAMPLER_BUFFER 0x8DC2 #define GL_INT_SAMPLER_2D_RECT 0x8DCD #define GL_INT_SAMPLER_BUFFER 0x8DD0 #define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 #define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 #define GL_TEXTURE_BUFFER 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B #define GL_TEXTURE_BINDING_BUFFER 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D #define GL_TEXTURE_RECTANGLE 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 #define GL_R8_SNORM 0x8F94 #define GL_RG8_SNORM 0x8F95 #define GL_RGB8_SNORM 0x8F96 #define GL_RGBA8_SNORM 0x8F97 #define GL_R16_SNORM 0x8F98 #define GL_RG16_SNORM 0x8F99 #define GL_RGB16_SNORM 0x8F9A #define GL_RGBA16_SNORM 0x8F9B #define GL_SIGNED_NORMALIZED 0x8F9C #define GL_PRIMITIVE_RESTART 0x8F9D #define GL_PRIMITIVE_RESTART_INDEX 0x8F9E #define GL_COPY_READ_BUFFER 0x8F36 #define GL_COPY_WRITE_BUFFER 0x8F37 #define GL_UNIFORM_BUFFER 0x8A11 #define GL_UNIFORM_BUFFER_BINDING 0x8A28 #define GL_UNIFORM_BUFFER_START 0x8A29 #define GL_UNIFORM_BUFFER_SIZE 0x8A2A #define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B #define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C #define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D #define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E #define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F #define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 #define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 #define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 #define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 #define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 #define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 #define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 #define GL_UNIFORM_TYPE 0x8A37 #define GL_UNIFORM_SIZE 0x8A38 #define GL_UNIFORM_NAME_LENGTH 0x8A39 #define GL_UNIFORM_BLOCK_INDEX 0x8A3A #define GL_UNIFORM_OFFSET 0x8A3B #define GL_UNIFORM_ARRAY_STRIDE 0x8A3C #define GL_UNIFORM_MATRIX_STRIDE 0x8A3D #define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E #define GL_UNIFORM_BLOCK_BINDING 0x8A3F #define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 #define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 #define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 #define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 #define GL_INVALID_INDEX 0xFFFFFFFFu typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); #endif #endif /* GL_VERSION_3_1 */ #ifndef GL_VERSION_3_2 #define GL_VERSION_3_2 1 typedef struct __GLsync *GLsync; #ifndef GLEXT_64_TYPES_DEFINED /* This code block is duplicated in glxext.h, so must be protected */ #define GLEXT_64_TYPES_DEFINED /* Define int32_t, int64_t, and uint64_t types for UST/MSC */ /* (as used in the GL_EXT_timer_query extension). */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #include #elif defined(__sun__) || defined(__digital__) #include #if defined(__STDC__) #if defined(__arch64__) || defined(_LP64) typedef long int int64_t; typedef unsigned long int uint64_t; #else typedef long long int int64_t; typedef unsigned long long int uint64_t; #endif /* __arch64__ */ #endif /* __STDC__ */ #elif defined( __VMS ) || defined(__sgi) #include #elif defined(__SCO__) || defined(__USLC__) #include #elif defined(__UNIXOS2__) || defined(__SOL64__) typedef long int int32_t; typedef long long int int64_t; typedef unsigned long long int uint64_t; #elif defined(_WIN32) && defined(__GNUC__) #include #elif defined(_WIN32) typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #else /* Fallback if nothing above works */ #include #endif #endif typedef uint64_t GLuint64; typedef int64_t GLint64; #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 #define GL_LINES_ADJACENCY 0x000A #define GL_LINE_STRIP_ADJACENCY 0x000B #define GL_TRIANGLES_ADJACENCY 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY 0x000D #define GL_PROGRAM_POINT_SIZE 0x8642 #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 #define GL_GEOMETRY_SHADER 0x8DD9 #define GL_GEOMETRY_VERTICES_OUT 0x8916 #define GL_GEOMETRY_INPUT_TYPE 0x8917 #define GL_GEOMETRY_OUTPUT_TYPE 0x8918 #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 #define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 #define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 #define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 #define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 #define GL_CONTEXT_PROFILE_MASK 0x9126 #define GL_DEPTH_CLAMP 0x864F #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C #define GL_FIRST_VERTEX_CONVENTION 0x8E4D #define GL_LAST_VERTEX_CONVENTION 0x8E4E #define GL_PROVOKING_VERTEX 0x8E4F #define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F #define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 #define GL_OBJECT_TYPE 0x9112 #define GL_SYNC_CONDITION 0x9113 #define GL_SYNC_STATUS 0x9114 #define GL_SYNC_FLAGS 0x9115 #define GL_SYNC_FENCE 0x9116 #define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 #define GL_UNSIGNALED 0x9118 #define GL_SIGNALED 0x9119 #define GL_ALREADY_SIGNALED 0x911A #define GL_TIMEOUT_EXPIRED 0x911B #define GL_CONDITION_SATISFIED 0x911C #define GL_WAIT_FAILED 0x911D #define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull #define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 #define GL_SAMPLE_POSITION 0x8E50 #define GL_SAMPLE_MASK 0x8E51 #define GL_SAMPLE_MASK_VALUE 0x8E52 #define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 #define GL_TEXTURE_2D_MULTISAMPLE 0x9100 #define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 #define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 #define GL_TEXTURE_SAMPLES 0x9106 #define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 #define GL_SAMPLER_2D_MULTISAMPLE 0x9108 #define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A #define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B #define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D #define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E #define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F #define GL_MAX_INTEGER_SAMPLES 0x9110 typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); GLAPI void APIENTRY glProvokingVertex (GLenum mode); GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); GLAPI GLboolean APIENTRY glIsSync (GLsync sync); GLAPI void APIENTRY glDeleteSync (GLsync sync); GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); GLAPI void APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); #endif #endif /* GL_VERSION_3_2 */ #ifndef GL_VERSION_3_3 #define GL_VERSION_3_3 1 #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE #define GL_SRC1_COLOR 0x88F9 #define GL_ONE_MINUS_SRC1_COLOR 0x88FA #define GL_ONE_MINUS_SRC1_ALPHA 0x88FB #define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC #define GL_ANY_SAMPLES_PASSED 0x8C2F #define GL_SAMPLER_BINDING 0x8919 #define GL_RGB10_A2UI 0x906F #define GL_TEXTURE_SWIZZLE_R 0x8E42 #define GL_TEXTURE_SWIZZLE_G 0x8E43 #define GL_TEXTURE_SWIZZLE_B 0x8E44 #define GL_TEXTURE_SWIZZLE_A 0x8E45 #define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 #define GL_TIME_ELAPSED 0x88BF #define GL_TIMESTAMP 0x8E28 #define GL_INT_2_10_10_10_REV 0x8D9F typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); #endif #endif /* GL_VERSION_3_3 */ #ifndef GL_VERSION_4_0 #define GL_VERSION_4_0 1 #define GL_SAMPLE_SHADING 0x8C36 #define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F #define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A #define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B #define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D #define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F #define GL_DRAW_INDIRECT_BUFFER 0x8F3F #define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 #define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F #define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A #define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B #define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C #define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D #define GL_MAX_VERTEX_STREAMS 0x8E71 #define GL_DOUBLE_VEC2 0x8FFC #define GL_DOUBLE_VEC3 0x8FFD #define GL_DOUBLE_VEC4 0x8FFE #define GL_DOUBLE_MAT2 0x8F46 #define GL_DOUBLE_MAT3 0x8F47 #define GL_DOUBLE_MAT4 0x8F48 #define GL_DOUBLE_MAT2x3 0x8F49 #define GL_DOUBLE_MAT2x4 0x8F4A #define GL_DOUBLE_MAT3x2 0x8F4B #define GL_DOUBLE_MAT3x4 0x8F4C #define GL_DOUBLE_MAT4x2 0x8F4D #define GL_DOUBLE_MAT4x3 0x8F4E #define GL_ACTIVE_SUBROUTINES 0x8DE5 #define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 #define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 #define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 #define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 #define GL_MAX_SUBROUTINES 0x8DE7 #define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 #define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A #define GL_COMPATIBLE_SUBROUTINES 0x8E4B #define GL_PATCHES 0x000E #define GL_PATCH_VERTICES 0x8E72 #define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 #define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 #define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 #define GL_TESS_GEN_MODE 0x8E76 #define GL_TESS_GEN_SPACING 0x8E77 #define GL_TESS_GEN_VERTEX_ORDER 0x8E78 #define GL_TESS_GEN_POINT_MODE 0x8E79 #define GL_ISOLINES 0x8E7A #define GL_FRACTIONAL_ODD 0x8E7B #define GL_FRACTIONAL_EVEN 0x8E7C #define GL_MAX_PATCH_VERTICES 0x8E7D #define GL_MAX_TESS_GEN_LEVEL 0x8E7E #define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F #define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 #define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 #define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 #define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 #define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 #define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 #define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 #define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 #define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A #define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C #define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D #define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E #define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F #define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 #define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 #define GL_TESS_EVALUATION_SHADER 0x8E87 #define GL_TESS_CONTROL_SHADER 0x8E88 #define GL_TRANSFORM_FEEDBACK 0x8E22 #define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 #define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 #define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 #define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMinSampleShading (GLfloat value); GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); GLAPI void APIENTRY glPauseTransformFeedback (void); GLAPI void APIENTRY glResumeTransformFeedback (void); GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); #endif #endif /* GL_VERSION_4_0 */ #ifndef GL_VERSION_4_1 #define GL_VERSION_4_1 1 #define GL_FIXED 0x140C #define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A #define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B #define GL_LOW_FLOAT 0x8DF0 #define GL_MEDIUM_FLOAT 0x8DF1 #define GL_HIGH_FLOAT 0x8DF2 #define GL_LOW_INT 0x8DF3 #define GL_MEDIUM_INT 0x8DF4 #define GL_HIGH_INT 0x8DF5 #define GL_SHADER_COMPILER 0x8DFA #define GL_SHADER_BINARY_FORMATS 0x8DF8 #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 #define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB #define GL_MAX_VARYING_VECTORS 0x8DFC #define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD #define GL_RGB565 0x8D62 #define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 #define GL_PROGRAM_BINARY_LENGTH 0x8741 #define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE #define GL_PROGRAM_BINARY_FORMATS 0x87FF #define GL_VERTEX_SHADER_BIT 0x00000001 #define GL_FRAGMENT_SHADER_BIT 0x00000002 #define GL_GEOMETRY_SHADER_BIT 0x00000004 #define GL_TESS_CONTROL_SHADER_BIT 0x00000008 #define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 #define GL_ALL_SHADER_BITS 0xFFFFFFFF #define GL_PROGRAM_SEPARABLE 0x8258 #define GL_ACTIVE_PROGRAM 0x8259 #define GL_PROGRAM_PIPELINE_BINDING 0x825A #define GL_MAX_VIEWPORTS 0x825B #define GL_VIEWPORT_SUBPIXEL_BITS 0x825C #define GL_VIEWPORT_BOUNDS_RANGE 0x825D #define GL_LAYER_PROVOKING_VERTEX 0x825E #define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F #define GL_UNDEFINED_VERTEX 0x8260 typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReleaseShaderCompiler (void); GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); GLAPI void APIENTRY glClearDepthf (GLfloat d); GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v); GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f); GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); #endif #endif /* GL_VERSION_4_1 */ #ifndef GL_VERSION_4_2 #define GL_VERSION_4_2 1 #define GL_COPY_READ_BUFFER_BINDING 0x8F36 #define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 #define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 #define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 #define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 #define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 #define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 #define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A #define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B #define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C #define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D #define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E #define GL_NUM_SAMPLE_COUNTS 0x9380 #define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC #define GL_ATOMIC_COUNTER_BUFFER 0x92C0 #define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 #define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 #define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 #define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 #define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 #define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB #define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC #define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD #define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE #define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF #define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 #define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 #define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 #define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 #define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 #define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 #define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 #define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 #define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 #define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC #define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 #define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA #define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB #define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 #define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 #define GL_UNIFORM_BARRIER_BIT 0x00000004 #define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 #define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 #define GL_COMMAND_BARRIER_BIT 0x00000040 #define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 #define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 #define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 #define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 #define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 #define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 #define GL_ALL_BARRIER_BITS 0xFFFFFFFF #define GL_MAX_IMAGE_UNITS 0x8F38 #define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 #define GL_IMAGE_BINDING_NAME 0x8F3A #define GL_IMAGE_BINDING_LEVEL 0x8F3B #define GL_IMAGE_BINDING_LAYERED 0x8F3C #define GL_IMAGE_BINDING_LAYER 0x8F3D #define GL_IMAGE_BINDING_ACCESS 0x8F3E #define GL_IMAGE_1D 0x904C #define GL_IMAGE_2D 0x904D #define GL_IMAGE_3D 0x904E #define GL_IMAGE_2D_RECT 0x904F #define GL_IMAGE_CUBE 0x9050 #define GL_IMAGE_BUFFER 0x9051 #define GL_IMAGE_1D_ARRAY 0x9052 #define GL_IMAGE_2D_ARRAY 0x9053 #define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 #define GL_IMAGE_2D_MULTISAMPLE 0x9055 #define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 #define GL_INT_IMAGE_1D 0x9057 #define GL_INT_IMAGE_2D 0x9058 #define GL_INT_IMAGE_3D 0x9059 #define GL_INT_IMAGE_2D_RECT 0x905A #define GL_INT_IMAGE_CUBE 0x905B #define GL_INT_IMAGE_BUFFER 0x905C #define GL_INT_IMAGE_1D_ARRAY 0x905D #define GL_INT_IMAGE_2D_ARRAY 0x905E #define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F #define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 #define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 #define GL_UNSIGNED_INT_IMAGE_1D 0x9062 #define GL_UNSIGNED_INT_IMAGE_2D 0x9063 #define GL_UNSIGNED_INT_IMAGE_3D 0x9064 #define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 #define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 #define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 #define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 #define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 #define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A #define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B #define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C #define GL_MAX_IMAGE_SAMPLES 0x906D #define GL_IMAGE_BINDING_FORMAT 0x906E #define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 #define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 #define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 #define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA #define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB #define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC #define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD #define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE #define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF #define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F #define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount); GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); #endif #endif /* GL_VERSION_4_2 */ #ifndef GL_VERSION_4_3 #define GL_VERSION_4_3 1 typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); #define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 #define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E #define GL_COMPRESSED_RGB8_ETC2 0x9274 #define GL_COMPRESSED_SRGB8_ETC2 0x9275 #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 #define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 #define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 #define GL_COMPRESSED_R11_EAC 0x9270 #define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 #define GL_COMPRESSED_RG11_EAC 0x9272 #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 #define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 #define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A #define GL_MAX_ELEMENT_INDEX 0x8D6B #define GL_COMPUTE_SHADER 0x91B9 #define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB #define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC #define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD #define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 #define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 #define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 #define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 #define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 #define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB #define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE #define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF #define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 #define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED #define GL_DISPATCH_INDIRECT_BUFFER 0x90EE #define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF #define GL_COMPUTE_SHADER_BIT 0x00000020 #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 #define GL_DEBUG_CALLBACK_FUNCTION 0x8244 #define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 #define GL_DEBUG_SOURCE_API 0x8246 #define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 #define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 #define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 #define GL_DEBUG_SOURCE_APPLICATION 0x824A #define GL_DEBUG_SOURCE_OTHER 0x824B #define GL_DEBUG_TYPE_ERROR 0x824C #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E #define GL_DEBUG_TYPE_PORTABILITY 0x824F #define GL_DEBUG_TYPE_PERFORMANCE 0x8250 #define GL_DEBUG_TYPE_OTHER 0x8251 #define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 #define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 #define GL_DEBUG_LOGGED_MESSAGES 0x9145 #define GL_DEBUG_SEVERITY_HIGH 0x9146 #define GL_DEBUG_SEVERITY_MEDIUM 0x9147 #define GL_DEBUG_SEVERITY_LOW 0x9148 #define GL_DEBUG_TYPE_MARKER 0x8268 #define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 #define GL_DEBUG_TYPE_POP_GROUP 0x826A #define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B #define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C #define GL_DEBUG_GROUP_STACK_DEPTH 0x826D #define GL_BUFFER 0x82E0 #define GL_SHADER 0x82E1 #define GL_PROGRAM 0x82E2 #define GL_QUERY 0x82E3 #define GL_PROGRAM_PIPELINE 0x82E4 #define GL_SAMPLER 0x82E6 #define GL_MAX_LABEL_LENGTH 0x82E8 #define GL_DEBUG_OUTPUT 0x92E0 #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 #define GL_MAX_UNIFORM_LOCATIONS 0x826E #define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 #define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 #define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 #define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 #define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 #define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 #define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 #define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 #define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 #define GL_INTERNALFORMAT_SUPPORTED 0x826F #define GL_INTERNALFORMAT_PREFERRED 0x8270 #define GL_INTERNALFORMAT_RED_SIZE 0x8271 #define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 #define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 #define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 #define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 #define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 #define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 #define GL_INTERNALFORMAT_RED_TYPE 0x8278 #define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 #define GL_INTERNALFORMAT_BLUE_TYPE 0x827A #define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B #define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C #define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D #define GL_MAX_WIDTH 0x827E #define GL_MAX_HEIGHT 0x827F #define GL_MAX_DEPTH 0x8280 #define GL_MAX_LAYERS 0x8281 #define GL_MAX_COMBINED_DIMENSIONS 0x8282 #define GL_COLOR_COMPONENTS 0x8283 #define GL_DEPTH_COMPONENTS 0x8284 #define GL_STENCIL_COMPONENTS 0x8285 #define GL_COLOR_RENDERABLE 0x8286 #define GL_DEPTH_RENDERABLE 0x8287 #define GL_STENCIL_RENDERABLE 0x8288 #define GL_FRAMEBUFFER_RENDERABLE 0x8289 #define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A #define GL_FRAMEBUFFER_BLEND 0x828B #define GL_READ_PIXELS 0x828C #define GL_READ_PIXELS_FORMAT 0x828D #define GL_READ_PIXELS_TYPE 0x828E #define GL_TEXTURE_IMAGE_FORMAT 0x828F #define GL_TEXTURE_IMAGE_TYPE 0x8290 #define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 #define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 #define GL_MIPMAP 0x8293 #define GL_MANUAL_GENERATE_MIPMAP 0x8294 #define GL_AUTO_GENERATE_MIPMAP 0x8295 #define GL_COLOR_ENCODING 0x8296 #define GL_SRGB_READ 0x8297 #define GL_SRGB_WRITE 0x8298 #define GL_FILTER 0x829A #define GL_VERTEX_TEXTURE 0x829B #define GL_TESS_CONTROL_TEXTURE 0x829C #define GL_TESS_EVALUATION_TEXTURE 0x829D #define GL_GEOMETRY_TEXTURE 0x829E #define GL_FRAGMENT_TEXTURE 0x829F #define GL_COMPUTE_TEXTURE 0x82A0 #define GL_TEXTURE_SHADOW 0x82A1 #define GL_TEXTURE_GATHER 0x82A2 #define GL_TEXTURE_GATHER_SHADOW 0x82A3 #define GL_SHADER_IMAGE_LOAD 0x82A4 #define GL_SHADER_IMAGE_STORE 0x82A5 #define GL_SHADER_IMAGE_ATOMIC 0x82A6 #define GL_IMAGE_TEXEL_SIZE 0x82A7 #define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 #define GL_IMAGE_PIXEL_FORMAT 0x82A9 #define GL_IMAGE_PIXEL_TYPE 0x82AA #define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC #define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD #define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE #define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF #define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 #define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 #define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 #define GL_CLEAR_BUFFER 0x82B4 #define GL_TEXTURE_VIEW 0x82B5 #define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 #define GL_FULL_SUPPORT 0x82B7 #define GL_CAVEAT_SUPPORT 0x82B8 #define GL_IMAGE_CLASS_4_X_32 0x82B9 #define GL_IMAGE_CLASS_2_X_32 0x82BA #define GL_IMAGE_CLASS_1_X_32 0x82BB #define GL_IMAGE_CLASS_4_X_16 0x82BC #define GL_IMAGE_CLASS_2_X_16 0x82BD #define GL_IMAGE_CLASS_1_X_16 0x82BE #define GL_IMAGE_CLASS_4_X_8 0x82BF #define GL_IMAGE_CLASS_2_X_8 0x82C0 #define GL_IMAGE_CLASS_1_X_8 0x82C1 #define GL_IMAGE_CLASS_11_11_10 0x82C2 #define GL_IMAGE_CLASS_10_10_10_2 0x82C3 #define GL_VIEW_CLASS_128_BITS 0x82C4 #define GL_VIEW_CLASS_96_BITS 0x82C5 #define GL_VIEW_CLASS_64_BITS 0x82C6 #define GL_VIEW_CLASS_48_BITS 0x82C7 #define GL_VIEW_CLASS_32_BITS 0x82C8 #define GL_VIEW_CLASS_24_BITS 0x82C9 #define GL_VIEW_CLASS_16_BITS 0x82CA #define GL_VIEW_CLASS_8_BITS 0x82CB #define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC #define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD #define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE #define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF #define GL_VIEW_CLASS_RGTC1_RED 0x82D0 #define GL_VIEW_CLASS_RGTC2_RG 0x82D1 #define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 #define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 #define GL_UNIFORM 0x92E1 #define GL_UNIFORM_BLOCK 0x92E2 #define GL_PROGRAM_INPUT 0x92E3 #define GL_PROGRAM_OUTPUT 0x92E4 #define GL_BUFFER_VARIABLE 0x92E5 #define GL_SHADER_STORAGE_BLOCK 0x92E6 #define GL_VERTEX_SUBROUTINE 0x92E8 #define GL_TESS_CONTROL_SUBROUTINE 0x92E9 #define GL_TESS_EVALUATION_SUBROUTINE 0x92EA #define GL_GEOMETRY_SUBROUTINE 0x92EB #define GL_FRAGMENT_SUBROUTINE 0x92EC #define GL_COMPUTE_SUBROUTINE 0x92ED #define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE #define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF #define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 #define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 #define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 #define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 #define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 #define GL_ACTIVE_RESOURCES 0x92F5 #define GL_MAX_NAME_LENGTH 0x92F6 #define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 #define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 #define GL_NAME_LENGTH 0x92F9 #define GL_TYPE 0x92FA #define GL_ARRAY_SIZE 0x92FB #define GL_OFFSET 0x92FC #define GL_BLOCK_INDEX 0x92FD #define GL_ARRAY_STRIDE 0x92FE #define GL_MATRIX_STRIDE 0x92FF #define GL_IS_ROW_MAJOR 0x9300 #define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 #define GL_BUFFER_BINDING 0x9302 #define GL_BUFFER_DATA_SIZE 0x9303 #define GL_NUM_ACTIVE_VARIABLES 0x9304 #define GL_ACTIVE_VARIABLES 0x9305 #define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 #define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 #define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 #define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 #define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A #define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B #define GL_TOP_LEVEL_ARRAY_SIZE 0x930C #define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D #define GL_LOCATION 0x930E #define GL_LOCATION_INDEX 0x930F #define GL_IS_PER_PATCH 0x92E7 #define GL_SHADER_STORAGE_BUFFER 0x90D2 #define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 #define GL_SHADER_STORAGE_BUFFER_START 0x90D4 #define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 #define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 #define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 #define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 #define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 #define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA #define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB #define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC #define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD #define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE #define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF #define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 #define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 #define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA #define GL_TEXTURE_BUFFER_OFFSET 0x919D #define GL_TEXTURE_BUFFER_SIZE 0x919E #define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F #define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB #define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC #define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD #define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE #define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF #define GL_VERTEX_ATTRIB_BINDING 0x82D4 #define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 #define GL_VERTEX_BINDING_DIVISOR 0x82D6 #define GL_VERTEX_BINDING_OFFSET 0x82D7 #define GL_VERTEX_BINDING_STRIDE 0x82D8 #define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 #define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA #define GL_VERTEX_BINDING_BUFFER 0x8F4F typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); typedef 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); typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); GLAPI 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); GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer); GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); GLAPI void APIENTRY glPopDebugGroup (void); GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); #endif #endif /* GL_VERSION_4_3 */ #ifndef GL_VERSION_4_4 #define GL_VERSION_4_4 1 #define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 #define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 #define GL_TEXTURE_BUFFER_BINDING 0x8C2A #define GL_MAP_PERSISTENT_BIT 0x0040 #define GL_MAP_COHERENT_BIT 0x0080 #define GL_DYNAMIC_STORAGE_BIT 0x0100 #define GL_CLIENT_STORAGE_BIT 0x0200 #define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 #define GL_BUFFER_IMMUTABLE_STORAGE 0x821F #define GL_BUFFER_STORAGE_FLAGS 0x8220 #define GL_CLEAR_TEXTURE 0x9365 #define GL_LOCATION_COMPONENT 0x934A #define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B #define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C #define GL_QUERY_BUFFER 0x9192 #define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 #define GL_QUERY_BUFFER_BINDING 0x9193 #define GL_QUERY_RESULT_NO_WAIT 0x9194 #define GL_MIRROR_CLAMP_TO_EDGE 0x8743 typedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); typedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); typedef 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); typedef void (APIENTRYP PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); typedef void (APIENTRYP PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); typedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); typedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers); typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBufferStorage (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); GLAPI void APIENTRY glClearTexImage (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); GLAPI 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); GLAPI void APIENTRY glBindBuffersBase (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); GLAPI void APIENTRY glBindBuffersRange (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); GLAPI void APIENTRY glBindTextures (GLuint first, GLsizei count, const GLuint *textures); GLAPI void APIENTRY glBindSamplers (GLuint first, GLsizei count, const GLuint *samplers); GLAPI void APIENTRY glBindImageTextures (GLuint first, GLsizei count, const GLuint *textures); GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); #endif #endif /* GL_VERSION_4_4 */ #ifndef GL_VERSION_4_5 #define GL_VERSION_4_5 1 #define GL_CONTEXT_LOST 0x0507 #define GL_NEGATIVE_ONE_TO_ONE 0x935E #define GL_ZERO_TO_ONE 0x935F #define GL_CLIP_ORIGIN 0x935C #define GL_CLIP_DEPTH_MODE 0x935D #define GL_QUERY_WAIT_INVERTED 0x8E17 #define GL_QUERY_NO_WAIT_INVERTED 0x8E18 #define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 #define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A #define GL_MAX_CULL_DISTANCES 0x82F9 #define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA #define GL_TEXTURE_TARGET 0x1006 #define GL_QUERY_TARGET 0x82EA #define GL_GUILTY_CONTEXT_RESET 0x8253 #define GL_INNOCENT_CONTEXT_RESET 0x8254 #define GL_UNKNOWN_CONTEXT_RESET 0x8255 #define GL_RESET_NOTIFICATION_STRATEGY 0x8256 #define GL_LOSE_CONTEXT_ON_RESET 0x8252 #define GL_NO_RESET_NOTIFICATION 0x8261 #define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 #define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB #define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC typedef void (APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); typedef void (APIENTRYP PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint *param); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param); typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); typedef void (APIENTRYP PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint *buffers); typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); typedef void (APIENTRYP PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void **params); typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); typedef void (APIENTRYP PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum buf); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum src); typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); typedef 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); typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param); typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint *textures); typedef void (APIENTRYP PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); typedef 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); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); typedef 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); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat *param); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint *params); typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint *param); typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); typedef void (APIENTRYP PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); typedef void (APIENTRYP PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); typedef void (APIENTRYP PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); typedef void (APIENTRYP PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint *param); typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); typedef void (APIENTRYP PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint *samplers); typedef void (APIENTRYP PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); typedef void (APIENTRYP PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); typedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); typedef 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); typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void); typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, void *pixels); typedef void (APIENTRYP PFNGLGETNTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); typedef void (APIENTRYP PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); typedef void (APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); typedef void (APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); typedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); typedef void (APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); typedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glClipControl (GLenum origin, GLenum depth); GLAPI void APIENTRY glCreateTransformFeedbacks (GLsizei n, GLuint *ids); GLAPI void APIENTRY glTransformFeedbackBufferBase (GLuint xfb, GLuint index, GLuint buffer); GLAPI void APIENTRY glTransformFeedbackBufferRange (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glGetTransformFeedbackiv (GLuint xfb, GLenum pname, GLint *param); GLAPI void APIENTRY glGetTransformFeedbacki_v (GLuint xfb, GLenum pname, GLuint index, GLint *param); GLAPI void APIENTRY glGetTransformFeedbacki64_v (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); GLAPI void APIENTRY glCreateBuffers (GLsizei n, GLuint *buffers); GLAPI void APIENTRY glNamedBufferStorage (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); GLAPI void APIENTRY glNamedBufferData (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); GLAPI void APIENTRY glNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); GLAPI void APIENTRY glCopyNamedBufferSubData (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); GLAPI void APIENTRY glClearNamedBufferData (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); GLAPI void APIENTRY glClearNamedBufferSubData (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); GLAPI void *APIENTRY glMapNamedBuffer (GLuint buffer, GLenum access); GLAPI void *APIENTRY glMapNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); GLAPI GLboolean APIENTRY glUnmapNamedBuffer (GLuint buffer); GLAPI void APIENTRY glFlushMappedNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length); GLAPI void APIENTRY glGetNamedBufferParameteriv (GLuint buffer, GLenum pname, GLint *params); GLAPI void APIENTRY glGetNamedBufferParameteri64v (GLuint buffer, GLenum pname, GLint64 *params); GLAPI void APIENTRY glGetNamedBufferPointerv (GLuint buffer, GLenum pname, void **params); GLAPI void APIENTRY glGetNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); GLAPI void APIENTRY glCreateFramebuffers (GLsizei n, GLuint *framebuffers); GLAPI void APIENTRY glNamedFramebufferRenderbuffer (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); GLAPI void APIENTRY glNamedFramebufferParameteri (GLuint framebuffer, GLenum pname, GLint param); GLAPI void APIENTRY glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); GLAPI void APIENTRY glNamedFramebufferTextureLayer (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); GLAPI void APIENTRY glNamedFramebufferDrawBuffer (GLuint framebuffer, GLenum buf); GLAPI void APIENTRY glNamedFramebufferDrawBuffers (GLuint framebuffer, GLsizei n, const GLenum *bufs); GLAPI void APIENTRY glNamedFramebufferReadBuffer (GLuint framebuffer, GLenum src); GLAPI void APIENTRY glInvalidateNamedFramebufferData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); GLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); GLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); GLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); GLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); GLAPI 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); GLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target); GLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param); GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameteriv (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); GLAPI void APIENTRY glCreateRenderbuffers (GLsizei n, GLuint *renderbuffers); GLAPI void APIENTRY glNamedRenderbufferStorage (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glNamedRenderbufferStorageMultisample (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glGetNamedRenderbufferParameteriv (GLuint renderbuffer, GLenum pname, GLint *params); GLAPI void APIENTRY glCreateTextures (GLenum target, GLsizei n, GLuint *textures); GLAPI void APIENTRY glTextureBuffer (GLuint texture, GLenum internalformat, GLuint buffer); GLAPI void APIENTRY glTextureBufferRange (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glTextureStorage1D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); GLAPI void APIENTRY glTextureStorage2D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); GLAPI void APIENTRY glTextureStorage3D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); GLAPI void APIENTRY glTextureStorage2DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTextureStorage3DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); GLAPI void APIENTRY glTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); GLAPI void APIENTRY glTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); GLAPI 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); GLAPI void APIENTRY glCompressedTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); GLAPI void APIENTRY glCompressedTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); GLAPI 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); GLAPI void APIENTRY glCopyTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); GLAPI void APIENTRY glCopyTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glCopyTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glTextureParameterf (GLuint texture, GLenum pname, GLfloat param); GLAPI void APIENTRY glTextureParameterfv (GLuint texture, GLenum pname, const GLfloat *param); GLAPI void APIENTRY glTextureParameteri (GLuint texture, GLenum pname, GLint param); GLAPI void APIENTRY glTextureParameterIiv (GLuint texture, GLenum pname, const GLint *params); GLAPI void APIENTRY glTextureParameterIuiv (GLuint texture, GLenum pname, const GLuint *params); GLAPI void APIENTRY glTextureParameteriv (GLuint texture, GLenum pname, const GLint *param); GLAPI void APIENTRY glGenerateTextureMipmap (GLuint texture); GLAPI void APIENTRY glBindTextureUnit (GLuint unit, GLuint texture); GLAPI void APIENTRY glGetTextureImage (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); GLAPI void APIENTRY glGetCompressedTextureImage (GLuint texture, GLint level, GLsizei bufSize, void *pixels); GLAPI void APIENTRY glGetTextureLevelParameterfv (GLuint texture, GLint level, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetTextureLevelParameteriv (GLuint texture, GLint level, GLenum pname, GLint *params); GLAPI void APIENTRY glGetTextureParameterfv (GLuint texture, GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetTextureParameterIiv (GLuint texture, GLenum pname, GLint *params); GLAPI void APIENTRY glGetTextureParameterIuiv (GLuint texture, GLenum pname, GLuint *params); GLAPI void APIENTRY glGetTextureParameteriv (GLuint texture, GLenum pname, GLint *params); GLAPI void APIENTRY glCreateVertexArrays (GLsizei n, GLuint *arrays); GLAPI void APIENTRY glDisableVertexArrayAttrib (GLuint vaobj, GLuint index); GLAPI void APIENTRY glEnableVertexArrayAttrib (GLuint vaobj, GLuint index); GLAPI void APIENTRY glVertexArrayElementBuffer (GLuint vaobj, GLuint buffer); GLAPI void APIENTRY glVertexArrayVertexBuffer (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); GLAPI void APIENTRY glVertexArrayVertexBuffers (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); GLAPI void APIENTRY glVertexArrayAttribBinding (GLuint vaobj, GLuint attribindex, GLuint bindingindex); GLAPI void APIENTRY glVertexArrayAttribFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); GLAPI void APIENTRY glVertexArrayAttribIFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); GLAPI void APIENTRY glVertexArrayAttribLFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); GLAPI void APIENTRY glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor); GLAPI void APIENTRY glGetVertexArrayiv (GLuint vaobj, GLenum pname, GLint *param); GLAPI void APIENTRY glGetVertexArrayIndexediv (GLuint vaobj, GLuint index, GLenum pname, GLint *param); GLAPI void APIENTRY glGetVertexArrayIndexed64iv (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); GLAPI void APIENTRY glCreateSamplers (GLsizei n, GLuint *samplers); GLAPI void APIENTRY glCreateProgramPipelines (GLsizei n, GLuint *pipelines); GLAPI void APIENTRY glCreateQueries (GLenum target, GLsizei n, GLuint *ids); GLAPI void APIENTRY glGetQueryBufferObjecti64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); GLAPI void APIENTRY glGetQueryBufferObjectiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); GLAPI void APIENTRY glGetQueryBufferObjectui64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); GLAPI void APIENTRY glGetQueryBufferObjectuiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); GLAPI void APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); GLAPI 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); GLAPI void APIENTRY glGetCompressedTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); GLAPI GLenum APIENTRY glGetGraphicsResetStatus (void); GLAPI void APIENTRY glGetnCompressedTexImage (GLenum target, GLint lod, GLsizei bufSize, void *pixels); GLAPI void APIENTRY glGetnTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); GLAPI void APIENTRY glGetnUniformdv (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); GLAPI void APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); GLAPI void APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params); GLAPI void APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params); GLAPI void APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); GLAPI void APIENTRY glTextureBarrier (void); #endif #endif /* GL_VERSION_4_5 */ #ifndef GL_ARB_ES2_compatibility #define GL_ARB_ES2_compatibility 1 #endif /* GL_ARB_ES2_compatibility */ #ifndef GL_ARB_ES3_1_compatibility #define GL_ARB_ES3_1_compatibility 1 #endif /* GL_ARB_ES3_1_compatibility */ #ifndef GL_ARB_ES3_compatibility #define GL_ARB_ES3_compatibility 1 #endif /* GL_ARB_ES3_compatibility */ #ifndef GL_ARB_arrays_of_arrays #define GL_ARB_arrays_of_arrays 1 #endif /* GL_ARB_arrays_of_arrays */ #ifndef GL_ARB_base_instance #define GL_ARB_base_instance 1 #endif /* GL_ARB_base_instance */ #ifndef GL_ARB_bindless_texture #define GL_ARB_bindless_texture 1 typedef uint64_t GLuint64EXT; #define GL_UNSIGNED_INT64_ARB 0x140F typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params); #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint64 APIENTRY glGetTextureHandleARB (GLuint texture); GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleARB (GLuint texture, GLuint sampler); GLAPI void APIENTRY glMakeTextureHandleResidentARB (GLuint64 handle); GLAPI void APIENTRY glMakeTextureHandleNonResidentARB (GLuint64 handle); GLAPI GLuint64 APIENTRY glGetImageHandleARB (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); GLAPI void APIENTRY glMakeImageHandleResidentARB (GLuint64 handle, GLenum access); GLAPI void APIENTRY glMakeImageHandleNonResidentARB (GLuint64 handle); GLAPI void APIENTRY glUniformHandleui64ARB (GLint location, GLuint64 value); GLAPI void APIENTRY glUniformHandleui64vARB (GLint location, GLsizei count, const GLuint64 *value); GLAPI void APIENTRY glProgramUniformHandleui64ARB (GLuint program, GLint location, GLuint64 value); GLAPI void APIENTRY glProgramUniformHandleui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *values); GLAPI GLboolean APIENTRY glIsTextureHandleResidentARB (GLuint64 handle); GLAPI GLboolean APIENTRY glIsImageHandleResidentARB (GLuint64 handle); GLAPI void APIENTRY glVertexAttribL1ui64ARB (GLuint index, GLuint64EXT x); GLAPI void APIENTRY glVertexAttribL1ui64vARB (GLuint index, const GLuint64EXT *v); GLAPI void APIENTRY glGetVertexAttribLui64vARB (GLuint index, GLenum pname, GLuint64EXT *params); #endif #endif /* GL_ARB_bindless_texture */ #ifndef GL_ARB_blend_func_extended #define GL_ARB_blend_func_extended 1 #endif /* GL_ARB_blend_func_extended */ #ifndef GL_ARB_buffer_storage #define GL_ARB_buffer_storage 1 #endif /* GL_ARB_buffer_storage */ #ifndef GL_ARB_cl_event #define GL_ARB_cl_event 1 struct _cl_context; struct _cl_event; #define GL_SYNC_CL_EVENT_ARB 0x8240 #define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); #ifdef GL_GLEXT_PROTOTYPES GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); #endif #endif /* GL_ARB_cl_event */ #ifndef GL_ARB_clear_buffer_object #define GL_ARB_clear_buffer_object 1 #endif /* GL_ARB_clear_buffer_object */ #ifndef GL_ARB_clear_texture #define GL_ARB_clear_texture 1 #endif /* GL_ARB_clear_texture */ #ifndef GL_ARB_clip_control #define GL_ARB_clip_control 1 #endif /* GL_ARB_clip_control */ #ifndef GL_ARB_compressed_texture_pixel_storage #define GL_ARB_compressed_texture_pixel_storage 1 #endif /* GL_ARB_compressed_texture_pixel_storage */ #ifndef GL_ARB_compute_shader #define GL_ARB_compute_shader 1 #endif /* GL_ARB_compute_shader */ #ifndef GL_ARB_compute_variable_group_size #define GL_ARB_compute_variable_group_size 1 #define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 #define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB #define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 #define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF typedef 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); #ifdef GL_GLEXT_PROTOTYPES GLAPI 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); #endif #endif /* GL_ARB_compute_variable_group_size */ #ifndef GL_ARB_conditional_render_inverted #define GL_ARB_conditional_render_inverted 1 #endif /* GL_ARB_conditional_render_inverted */ #ifndef GL_ARB_conservative_depth #define GL_ARB_conservative_depth 1 #endif /* GL_ARB_conservative_depth */ #ifndef GL_ARB_copy_buffer #define GL_ARB_copy_buffer 1 #endif /* GL_ARB_copy_buffer */ #ifndef GL_ARB_copy_image #define GL_ARB_copy_image 1 #endif /* GL_ARB_copy_image */ #ifndef GL_ARB_cull_distance #define GL_ARB_cull_distance 1 #endif /* GL_ARB_cull_distance */ #ifndef GL_ARB_debug_output #define GL_ARB_debug_output 1 typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); #define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 #define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 #define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 #define GL_DEBUG_SOURCE_API_ARB 0x8246 #define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 #define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 #define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 #define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A #define GL_DEBUG_SOURCE_OTHER_ARB 0x824B #define GL_DEBUG_TYPE_ERROR_ARB 0x824C #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E #define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F #define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 #define GL_DEBUG_TYPE_OTHER_ARB 0x8251 #define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 #define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 #define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 #define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 #define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 #define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const void *userParam); GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); #endif #endif /* GL_ARB_debug_output */ #ifndef GL_ARB_depth_buffer_float #define GL_ARB_depth_buffer_float 1 #endif /* GL_ARB_depth_buffer_float */ #ifndef GL_ARB_depth_clamp #define GL_ARB_depth_clamp 1 #endif /* GL_ARB_depth_clamp */ #ifndef GL_ARB_derivative_control #define GL_ARB_derivative_control 1 #endif /* GL_ARB_derivative_control */ #ifndef GL_ARB_direct_state_access #define GL_ARB_direct_state_access 1 #endif /* GL_ARB_direct_state_access */ #ifndef GL_ARB_draw_buffers_blend #define GL_ARB_draw_buffers_blend 1 typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); #endif #endif /* GL_ARB_draw_buffers_blend */ #ifndef GL_ARB_draw_elements_base_vertex #define GL_ARB_draw_elements_base_vertex 1 #endif /* GL_ARB_draw_elements_base_vertex */ #ifndef GL_ARB_draw_indirect #define GL_ARB_draw_indirect 1 #endif /* GL_ARB_draw_indirect */ #ifndef GL_ARB_enhanced_layouts #define GL_ARB_enhanced_layouts 1 #endif /* GL_ARB_enhanced_layouts */ #ifndef GL_ARB_explicit_attrib_location #define GL_ARB_explicit_attrib_location 1 #endif /* GL_ARB_explicit_attrib_location */ #ifndef GL_ARB_explicit_uniform_location #define GL_ARB_explicit_uniform_location 1 #endif /* GL_ARB_explicit_uniform_location */ #ifndef GL_ARB_fragment_coord_conventions #define GL_ARB_fragment_coord_conventions 1 #endif /* GL_ARB_fragment_coord_conventions */ #ifndef GL_ARB_fragment_layer_viewport #define GL_ARB_fragment_layer_viewport 1 #endif /* GL_ARB_fragment_layer_viewport */ #ifndef GL_ARB_framebuffer_no_attachments #define GL_ARB_framebuffer_no_attachments 1 #endif /* GL_ARB_framebuffer_no_attachments */ #ifndef GL_ARB_framebuffer_object #define GL_ARB_framebuffer_object 1 #endif /* GL_ARB_framebuffer_object */ #ifndef GL_ARB_framebuffer_sRGB #define GL_ARB_framebuffer_sRGB 1 #endif /* GL_ARB_framebuffer_sRGB */ #ifndef GL_ARB_get_program_binary #define GL_ARB_get_program_binary 1 #endif /* GL_ARB_get_program_binary */ #ifndef GL_ARB_get_texture_sub_image #define GL_ARB_get_texture_sub_image 1 #endif /* GL_ARB_get_texture_sub_image */ #ifndef GL_ARB_gpu_shader5 #define GL_ARB_gpu_shader5 1 #endif /* GL_ARB_gpu_shader5 */ #ifndef GL_ARB_gpu_shader_fp64 #define GL_ARB_gpu_shader_fp64 1 #endif /* GL_ARB_gpu_shader_fp64 */ #ifndef GL_ARB_half_float_vertex #define GL_ARB_half_float_vertex 1 #endif /* GL_ARB_half_float_vertex */ #ifndef GL_ARB_imaging #define GL_ARB_imaging 1 #define GL_BLEND_COLOR 0x8005 #define GL_BLEND_EQUATION 0x8009 #endif /* GL_ARB_imaging */ #ifndef GL_ARB_indirect_parameters #define GL_ARB_indirect_parameters 1 #define GL_PARAMETER_BUFFER_ARB 0x80EE #define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); #endif #endif /* GL_ARB_indirect_parameters */ #ifndef GL_ARB_internalformat_query #define GL_ARB_internalformat_query 1 #endif /* GL_ARB_internalformat_query */ #ifndef GL_ARB_internalformat_query2 #define GL_ARB_internalformat_query2 1 #define GL_SRGB_DECODE_ARB 0x8299 #endif /* GL_ARB_internalformat_query2 */ #ifndef GL_ARB_invalidate_subdata #define GL_ARB_invalidate_subdata 1 #endif /* GL_ARB_invalidate_subdata */ #ifndef GL_ARB_map_buffer_alignment #define GL_ARB_map_buffer_alignment 1 #endif /* GL_ARB_map_buffer_alignment */ #ifndef GL_ARB_map_buffer_range #define GL_ARB_map_buffer_range 1 #endif /* GL_ARB_map_buffer_range */ #ifndef GL_ARB_multi_bind #define GL_ARB_multi_bind 1 #endif /* GL_ARB_multi_bind */ #ifndef GL_ARB_multi_draw_indirect #define GL_ARB_multi_draw_indirect 1 #endif /* GL_ARB_multi_draw_indirect */ #ifndef GL_ARB_occlusion_query2 #define GL_ARB_occlusion_query2 1 #endif /* GL_ARB_occlusion_query2 */ #ifndef GL_ARB_pipeline_statistics_query #define GL_ARB_pipeline_statistics_query 1 #define GL_VERTICES_SUBMITTED_ARB 0x82EE #define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF #define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 #define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 #define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 #define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 #define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 #define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 #define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 #define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 #endif /* GL_ARB_pipeline_statistics_query */ #ifndef GL_ARB_program_interface_query #define GL_ARB_program_interface_query 1 #endif /* GL_ARB_program_interface_query */ #ifndef GL_ARB_provoking_vertex #define GL_ARB_provoking_vertex 1 #endif /* GL_ARB_provoking_vertex */ #ifndef GL_ARB_query_buffer_object #define GL_ARB_query_buffer_object 1 #endif /* GL_ARB_query_buffer_object */ #ifndef GL_ARB_robust_buffer_access_behavior #define GL_ARB_robust_buffer_access_behavior 1 #endif /* GL_ARB_robust_buffer_access_behavior */ #ifndef GL_ARB_robustness #define GL_ARB_robustness 1 #define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 #define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 #define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 #define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 #define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 #define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 #define GL_NO_RESET_NOTIFICATION_ARB 0x8261 typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img); typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); #ifdef GL_GLEXT_PROTOTYPES GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, void *img); GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); #endif #endif /* GL_ARB_robustness */ #ifndef GL_ARB_robustness_isolation #define GL_ARB_robustness_isolation 1 #endif /* GL_ARB_robustness_isolation */ #ifndef GL_ARB_sample_shading #define GL_ARB_sample_shading 1 #define GL_SAMPLE_SHADING_ARB 0x8C36 #define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); #endif #endif /* GL_ARB_sample_shading */ #ifndef GL_ARB_sampler_objects #define GL_ARB_sampler_objects 1 #endif /* GL_ARB_sampler_objects */ #ifndef GL_ARB_seamless_cube_map #define GL_ARB_seamless_cube_map 1 #endif /* GL_ARB_seamless_cube_map */ #ifndef GL_ARB_seamless_cubemap_per_texture #define GL_ARB_seamless_cubemap_per_texture 1 #endif /* GL_ARB_seamless_cubemap_per_texture */ #ifndef GL_ARB_separate_shader_objects #define GL_ARB_separate_shader_objects 1 #endif /* GL_ARB_separate_shader_objects */ #ifndef GL_ARB_shader_atomic_counters #define GL_ARB_shader_atomic_counters 1 #endif /* GL_ARB_shader_atomic_counters */ #ifndef GL_ARB_shader_bit_encoding #define GL_ARB_shader_bit_encoding 1 #endif /* GL_ARB_shader_bit_encoding */ #ifndef GL_ARB_shader_draw_parameters #define GL_ARB_shader_draw_parameters 1 #endif /* GL_ARB_shader_draw_parameters */ #ifndef GL_ARB_shader_group_vote #define GL_ARB_shader_group_vote 1 #endif /* GL_ARB_shader_group_vote */ #ifndef GL_ARB_shader_image_load_store #define GL_ARB_shader_image_load_store 1 #endif /* GL_ARB_shader_image_load_store */ #ifndef GL_ARB_shader_image_size #define GL_ARB_shader_image_size 1 #endif /* GL_ARB_shader_image_size */ #ifndef GL_ARB_shader_precision #define GL_ARB_shader_precision 1 #endif /* GL_ARB_shader_precision */ #ifndef GL_ARB_shader_stencil_export #define GL_ARB_shader_stencil_export 1 #endif /* GL_ARB_shader_stencil_export */ #ifndef GL_ARB_shader_storage_buffer_object #define GL_ARB_shader_storage_buffer_object 1 #endif /* GL_ARB_shader_storage_buffer_object */ #ifndef GL_ARB_shader_subroutine #define GL_ARB_shader_subroutine 1 #endif /* GL_ARB_shader_subroutine */ #ifndef GL_ARB_shader_texture_image_samples #define GL_ARB_shader_texture_image_samples 1 #endif /* GL_ARB_shader_texture_image_samples */ #ifndef GL_ARB_shading_language_420pack #define GL_ARB_shading_language_420pack 1 #endif /* GL_ARB_shading_language_420pack */ #ifndef GL_ARB_shading_language_include #define GL_ARB_shading_language_include 1 #define GL_SHADER_INCLUDE_ARB 0x8DAE #define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 #define GL_NAMED_STRING_TYPE_ARB 0x8DEA typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); #endif #endif /* GL_ARB_shading_language_include */ #ifndef GL_ARB_shading_language_packing #define GL_ARB_shading_language_packing 1 #endif /* GL_ARB_shading_language_packing */ #ifndef GL_ARB_sparse_buffer #define GL_ARB_sparse_buffer 1 #define GL_SPARSE_STORAGE_BIT_ARB 0x0400 #define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 typedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBufferPageCommitmentARB (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); GLAPI void APIENTRY glNamedBufferPageCommitmentEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); GLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); #endif #endif /* GL_ARB_sparse_buffer */ #ifndef GL_ARB_sparse_texture #define GL_ARB_sparse_texture 1 #define GL_TEXTURE_SPARSE_ARB 0x91A6 #define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 #define GL_NUM_SPARSE_LEVELS_ARB 0x91AA #define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 #define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 #define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 #define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 #define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 #define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 #define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A #define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); #endif #endif /* GL_ARB_sparse_texture */ #ifndef GL_ARB_stencil_texturing #define GL_ARB_stencil_texturing 1 #endif /* GL_ARB_stencil_texturing */ #ifndef GL_ARB_sync #define GL_ARB_sync 1 #endif /* GL_ARB_sync */ #ifndef GL_ARB_tessellation_shader #define GL_ARB_tessellation_shader 1 #endif /* GL_ARB_tessellation_shader */ #ifndef GL_ARB_texture_barrier #define GL_ARB_texture_barrier 1 #endif /* GL_ARB_texture_barrier */ #ifndef GL_ARB_texture_buffer_object_rgb32 #define GL_ARB_texture_buffer_object_rgb32 1 #endif /* GL_ARB_texture_buffer_object_rgb32 */ #ifndef GL_ARB_texture_buffer_range #define GL_ARB_texture_buffer_range 1 #endif /* GL_ARB_texture_buffer_range */ #ifndef GL_ARB_texture_compression_bptc #define GL_ARB_texture_compression_bptc 1 #define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F #endif /* GL_ARB_texture_compression_bptc */ #ifndef GL_ARB_texture_compression_rgtc #define GL_ARB_texture_compression_rgtc 1 #endif /* GL_ARB_texture_compression_rgtc */ #ifndef GL_ARB_texture_cube_map_array #define GL_ARB_texture_cube_map_array 1 #define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A #define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B #define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D #define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F #endif /* GL_ARB_texture_cube_map_array */ #ifndef GL_ARB_texture_gather #define GL_ARB_texture_gather 1 #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F #define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F #endif /* GL_ARB_texture_gather */ #ifndef GL_ARB_texture_mirror_clamp_to_edge #define GL_ARB_texture_mirror_clamp_to_edge 1 #endif /* GL_ARB_texture_mirror_clamp_to_edge */ #ifndef GL_ARB_texture_multisample #define GL_ARB_texture_multisample 1 #endif /* GL_ARB_texture_multisample */ #ifndef GL_ARB_texture_query_levels #define GL_ARB_texture_query_levels 1 #endif /* GL_ARB_texture_query_levels */ #ifndef GL_ARB_texture_query_lod #define GL_ARB_texture_query_lod 1 #endif /* GL_ARB_texture_query_lod */ #ifndef GL_ARB_texture_rg #define GL_ARB_texture_rg 1 #endif /* GL_ARB_texture_rg */ #ifndef GL_ARB_texture_rgb10_a2ui #define GL_ARB_texture_rgb10_a2ui 1 #endif /* GL_ARB_texture_rgb10_a2ui */ #ifndef GL_ARB_texture_stencil8 #define GL_ARB_texture_stencil8 1 #endif /* GL_ARB_texture_stencil8 */ #ifndef GL_ARB_texture_storage #define GL_ARB_texture_storage 1 #endif /* GL_ARB_texture_storage */ #ifndef GL_ARB_texture_storage_multisample #define GL_ARB_texture_storage_multisample 1 #endif /* GL_ARB_texture_storage_multisample */ #ifndef GL_ARB_texture_swizzle #define GL_ARB_texture_swizzle 1 #endif /* GL_ARB_texture_swizzle */ #ifndef GL_ARB_texture_view #define GL_ARB_texture_view 1 #endif /* GL_ARB_texture_view */ #ifndef GL_ARB_timer_query #define GL_ARB_timer_query 1 #endif /* GL_ARB_timer_query */ #ifndef GL_ARB_transform_feedback2 #define GL_ARB_transform_feedback2 1 #endif /* GL_ARB_transform_feedback2 */ #ifndef GL_ARB_transform_feedback3 #define GL_ARB_transform_feedback3 1 #endif /* GL_ARB_transform_feedback3 */ #ifndef GL_ARB_transform_feedback_instanced #define GL_ARB_transform_feedback_instanced 1 #endif /* GL_ARB_transform_feedback_instanced */ #ifndef GL_ARB_transform_feedback_overflow_query #define GL_ARB_transform_feedback_overflow_query 1 #define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC #define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED #endif /* GL_ARB_transform_feedback_overflow_query */ #ifndef GL_ARB_uniform_buffer_object #define GL_ARB_uniform_buffer_object 1 #endif /* GL_ARB_uniform_buffer_object */ #ifndef GL_ARB_vertex_array_bgra #define GL_ARB_vertex_array_bgra 1 #endif /* GL_ARB_vertex_array_bgra */ #ifndef GL_ARB_vertex_array_object #define GL_ARB_vertex_array_object 1 #endif /* GL_ARB_vertex_array_object */ #ifndef GL_ARB_vertex_attrib_64bit #define GL_ARB_vertex_attrib_64bit 1 #endif /* GL_ARB_vertex_attrib_64bit */ #ifndef GL_ARB_vertex_attrib_binding #define GL_ARB_vertex_attrib_binding 1 #endif /* GL_ARB_vertex_attrib_binding */ #ifndef GL_ARB_vertex_type_10f_11f_11f_rev #define GL_ARB_vertex_type_10f_11f_11f_rev 1 #endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ #ifndef GL_ARB_vertex_type_2_10_10_10_rev #define GL_ARB_vertex_type_2_10_10_10_rev 1 #endif /* GL_ARB_vertex_type_2_10_10_10_rev */ #ifndef GL_ARB_viewport_array #define GL_ARB_viewport_array 1 #endif /* GL_ARB_viewport_array */ #ifndef GL_KHR_context_flush_control #define GL_KHR_context_flush_control 1 #endif /* GL_KHR_context_flush_control */ #ifndef GL_KHR_debug #define GL_KHR_debug 1 #endif /* GL_KHR_debug */ #ifndef GL_KHR_no_error #define GL_KHR_no_error 1 #define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 #endif /* GL_KHR_no_error */ #ifndef GL_KHR_robust_buffer_access_behavior #define GL_KHR_robust_buffer_access_behavior 1 #endif /* GL_KHR_robust_buffer_access_behavior */ #ifndef GL_KHR_robustness #define GL_KHR_robustness 1 #define GL_CONTEXT_ROBUST_ACCESS 0x90F3 #endif /* GL_KHR_robustness */ #ifndef GL_KHR_texture_compression_astc_hdr #define GL_KHR_texture_compression_astc_hdr 1 #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 #define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 #define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 #define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 #define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 #define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 #define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 #define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 #define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 #define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 #define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA #define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB #define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC #define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD #endif /* GL_KHR_texture_compression_astc_hdr */ #ifndef GL_KHR_texture_compression_astc_ldr #define GL_KHR_texture_compression_astc_ldr 1 #endif /* GL_KHR_texture_compression_astc_ldr */ #ifdef __cplusplus } #endif #endif ================================================ FILE: samples/gl3w/src/gl3w.cpp ================================================ /* This file was generated with gl3w_gen.py, part of gl3w (hosted at https://github.com/skaslev/gl3w) This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include /* --------------------------------------------------------------------------------------------- */ #ifdef _WIN32 /* ------------------------------------ * Windows * ------------------------------------ */ #define WIN32_LEAN_AND_MEAN 1 #include static HMODULE gl3w_libgl = NULL; static int gl3w_open_libgl(void) { if (!gl3w_libgl) { gl3w_libgl = LoadLibraryA("opengl32.dll"); } return gl3w_libgl != NULL; } static void gl3w_close_libgl(void) { if (gl3w_libgl) { FreeLibrary(gl3w_libgl); gl3w_libgl = NULL; } } static GL3WglProc gl3w_fn(const char *proc) { GL3WglProc res; res = (GL3WglProc) wglGetProcAddress(proc); if (!res) { res = (GL3WglProc) GetProcAddress(gl3w_libgl, proc); } return res; } #elif defined(__APPLE__) || defined(__APPLE_CC__) /* ------------------------------------ * Mac OS * ------------------------------------ */ #include static CFBundleRef gl3w_cfBundle = NULL; static CFURLRef gl3w_cfBundleURL = NULL; static int gl3w_open_libgl(void) { if (gl3w_cfBundle) { return 1; /* Already init */ } gl3w_cfBundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true); if (!gl3w_cfBundleURL) { return 0; } gl3w_cfBundle = CFBundleCreate(kCFAllocatorDefault, gl3w_cfBundleURL); if (!gl3w_cfBundle) { CFRelease(gl3w_cfBundleURL); return 0; } return 1; } static void gl3w_close_libgl(void) { if (gl3w_cfBundle) { CFRelease(gl3w_cfBundle); gl3w_cfBundle = NULL; } if (gl3w_cfBundleURL) { CFRelease(gl3w_cfBundleURL); gl3w_cfBundleURL = NULL; } } static GL3WglProc gl3w_fn(const char *proc) { GL3WglProc res; CFStringRef procName; procName = CFStringCreateWithCString(kCFAllocatorDefault, proc, kCFStringEncodingASCII); res = (GL3WglProc) CFBundleGetFunctionPointerForName(gl3w_cfBundle, procName); CFRelease(procName); return res; } #else /* ------------------------------------ * GLX * ------------------------------------ */ #include #include static void *gl3w_libgl = NULL; static int gl3w_open_libgl(void) { if (!gl3w_libgl) { gl3w_libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); } return gl3w_libgl != NULL; } static void gl3w_close_libgl(void) { if (gl3w_libgl) { dlclose(gl3w_libgl); gl3w_libgl = NULL; } } static GL3WglProc gl3w_fn(const char *proc) { GL3WglProc res; res = (GL3WglProc) glXGetProcAddress((const GLubyte *) proc); if (!res) { res = (GL3WglProc) dlsym(gl3w_libgl, proc); } return res; } #endif /* ------------------------------------ * GL3W API * ------------------------------------ */ static struct { int major, minor; } gl3w_version; static void gl3w_load_all_functions(void); static int gl3w_parse_version(void) { if (!glGetIntegerv) { return 0; } glGetIntegerv(GL_MAJOR_VERSION, &gl3w_version.major); glGetIntegerv(GL_MINOR_VERSION, &gl3w_version.minor); if (gl3w_version.major < 3) { return 0; } return 1; } int gl3wInit(void) { if (!gl3w_open_libgl()) { return 0; } gl3w_load_all_functions(); return gl3w_parse_version(); } void gl3wShutdown(void) { gl3w_close_libgl(); } int gl3wIsSupported(int major, int minor) { if (major < 3) { return 0; } if (gl3w_version.major == major) { return gl3w_version.minor >= minor; } return gl3w_version.major >= major; } GL3WglProc gl3wGetProcAddress(const char *proc) { if (!proc) { return NULL; } return gl3w_fn(proc); } /* --------------------------------------------------------------------------------------------- */ PFNGLACTIVESHADERPROGRAMPROC gl3wActiveShaderProgram; PFNGLACTIVETEXTUREPROC gl3wActiveTexture; PFNGLATTACHSHADERPROC gl3wAttachShader; PFNGLBEGINCONDITIONALRENDERPROC gl3wBeginConditionalRender; PFNGLBEGINQUERYPROC gl3wBeginQuery; PFNGLBEGINQUERYINDEXEDPROC gl3wBeginQueryIndexed; PFNGLBEGINTRANSFORMFEEDBACKPROC gl3wBeginTransformFeedback; PFNGLBINDATTRIBLOCATIONPROC gl3wBindAttribLocation; PFNGLBINDBUFFERPROC gl3wBindBuffer; PFNGLBINDBUFFERBASEPROC gl3wBindBufferBase; PFNGLBINDBUFFERRANGEPROC gl3wBindBufferRange; PFNGLBINDBUFFERSBASEPROC gl3wBindBuffersBase; PFNGLBINDBUFFERSRANGEPROC gl3wBindBuffersRange; PFNGLBINDFRAGDATALOCATIONPROC gl3wBindFragDataLocation; PFNGLBINDFRAGDATALOCATIONINDEXEDPROC gl3wBindFragDataLocationIndexed; PFNGLBINDFRAMEBUFFERPROC gl3wBindFramebuffer; PFNGLBINDIMAGETEXTUREPROC gl3wBindImageTexture; PFNGLBINDIMAGETEXTURESPROC gl3wBindImageTextures; PFNGLBINDPROGRAMPIPELINEPROC gl3wBindProgramPipeline; PFNGLBINDRENDERBUFFERPROC gl3wBindRenderbuffer; PFNGLBINDSAMPLERPROC gl3wBindSampler; PFNGLBINDSAMPLERSPROC gl3wBindSamplers; PFNGLBINDTEXTUREPROC gl3wBindTexture; PFNGLBINDTEXTUREUNITPROC gl3wBindTextureUnit; PFNGLBINDTEXTURESPROC gl3wBindTextures; PFNGLBINDTRANSFORMFEEDBACKPROC gl3wBindTransformFeedback; PFNGLBINDVERTEXARRAYPROC gl3wBindVertexArray; PFNGLBINDVERTEXBUFFERPROC gl3wBindVertexBuffer; PFNGLBINDVERTEXBUFFERSPROC gl3wBindVertexBuffers; PFNGLBLENDCOLORPROC gl3wBlendColor; PFNGLBLENDEQUATIONPROC gl3wBlendEquation; PFNGLBLENDEQUATIONSEPARATEPROC gl3wBlendEquationSeparate; PFNGLBLENDEQUATIONSEPARATEIPROC gl3wBlendEquationSeparatei; PFNGLBLENDEQUATIONSEPARATEIARBPROC gl3wBlendEquationSeparateiARB; PFNGLBLENDEQUATIONIPROC gl3wBlendEquationi; PFNGLBLENDEQUATIONIARBPROC gl3wBlendEquationiARB; PFNGLBLENDFUNCPROC gl3wBlendFunc; PFNGLBLENDFUNCSEPARATEPROC gl3wBlendFuncSeparate; PFNGLBLENDFUNCSEPARATEIPROC gl3wBlendFuncSeparatei; PFNGLBLENDFUNCSEPARATEIARBPROC gl3wBlendFuncSeparateiARB; PFNGLBLENDFUNCIPROC gl3wBlendFunci; PFNGLBLENDFUNCIARBPROC gl3wBlendFunciARB; PFNGLBLITFRAMEBUFFERPROC gl3wBlitFramebuffer; PFNGLBLITNAMEDFRAMEBUFFERPROC gl3wBlitNamedFramebuffer; PFNGLBUFFERDATAPROC gl3wBufferData; PFNGLBUFFERPAGECOMMITMENTARBPROC gl3wBufferPageCommitmentARB; PFNGLBUFFERSTORAGEPROC gl3wBufferStorage; PFNGLBUFFERSUBDATAPROC gl3wBufferSubData; PFNGLCHECKFRAMEBUFFERSTATUSPROC gl3wCheckFramebufferStatus; PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC gl3wCheckNamedFramebufferStatus; PFNGLCLAMPCOLORPROC gl3wClampColor; PFNGLCLEARPROC gl3wClear; PFNGLCLEARBUFFERDATAPROC gl3wClearBufferData; PFNGLCLEARBUFFERSUBDATAPROC gl3wClearBufferSubData; PFNGLCLEARBUFFERFIPROC gl3wClearBufferfi; PFNGLCLEARBUFFERFVPROC gl3wClearBufferfv; PFNGLCLEARBUFFERIVPROC gl3wClearBufferiv; PFNGLCLEARBUFFERUIVPROC gl3wClearBufferuiv; PFNGLCLEARCOLORPROC gl3wClearColor; PFNGLCLEARDEPTHPROC gl3wClearDepth; PFNGLCLEARDEPTHFPROC gl3wClearDepthf; PFNGLCLEARNAMEDBUFFERDATAPROC gl3wClearNamedBufferData; PFNGLCLEARNAMEDBUFFERSUBDATAPROC gl3wClearNamedBufferSubData; PFNGLCLEARNAMEDFRAMEBUFFERFIPROC gl3wClearNamedFramebufferfi; PFNGLCLEARNAMEDFRAMEBUFFERFVPROC gl3wClearNamedFramebufferfv; PFNGLCLEARNAMEDFRAMEBUFFERIVPROC gl3wClearNamedFramebufferiv; PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC gl3wClearNamedFramebufferuiv; PFNGLCLEARSTENCILPROC gl3wClearStencil; PFNGLCLEARTEXIMAGEPROC gl3wClearTexImage; PFNGLCLEARTEXSUBIMAGEPROC gl3wClearTexSubImage; PFNGLCLIENTWAITSYNCPROC gl3wClientWaitSync; PFNGLCLIPCONTROLPROC gl3wClipControl; PFNGLCOLORMASKPROC gl3wColorMask; PFNGLCOLORMASKIPROC gl3wColorMaski; PFNGLCOMPILESHADERPROC gl3wCompileShader; PFNGLCOMPILESHADERINCLUDEARBPROC gl3wCompileShaderIncludeARB; PFNGLCOMPRESSEDTEXIMAGE1DPROC gl3wCompressedTexImage1D; PFNGLCOMPRESSEDTEXIMAGE2DPROC gl3wCompressedTexImage2D; PFNGLCOMPRESSEDTEXIMAGE3DPROC gl3wCompressedTexImage3D; PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC gl3wCompressedTexSubImage1D; PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC gl3wCompressedTexSubImage2D; PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC gl3wCompressedTexSubImage3D; PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC gl3wCompressedTextureSubImage1D; PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC gl3wCompressedTextureSubImage2D; PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC gl3wCompressedTextureSubImage3D; PFNGLCOPYBUFFERSUBDATAPROC gl3wCopyBufferSubData; PFNGLCOPYIMAGESUBDATAPROC gl3wCopyImageSubData; PFNGLCOPYNAMEDBUFFERSUBDATAPROC gl3wCopyNamedBufferSubData; PFNGLCOPYTEXIMAGE1DPROC gl3wCopyTexImage1D; PFNGLCOPYTEXIMAGE2DPROC gl3wCopyTexImage2D; PFNGLCOPYTEXSUBIMAGE1DPROC gl3wCopyTexSubImage1D; PFNGLCOPYTEXSUBIMAGE2DPROC gl3wCopyTexSubImage2D; PFNGLCOPYTEXSUBIMAGE3DPROC gl3wCopyTexSubImage3D; PFNGLCOPYTEXTURESUBIMAGE1DPROC gl3wCopyTextureSubImage1D; PFNGLCOPYTEXTURESUBIMAGE2DPROC gl3wCopyTextureSubImage2D; PFNGLCOPYTEXTURESUBIMAGE3DPROC gl3wCopyTextureSubImage3D; PFNGLCREATEBUFFERSPROC gl3wCreateBuffers; PFNGLCREATEFRAMEBUFFERSPROC gl3wCreateFramebuffers; PFNGLCREATEPROGRAMPROC gl3wCreateProgram; PFNGLCREATEPROGRAMPIPELINESPROC gl3wCreateProgramPipelines; PFNGLCREATEQUERIESPROC gl3wCreateQueries; PFNGLCREATERENDERBUFFERSPROC gl3wCreateRenderbuffers; PFNGLCREATESAMPLERSPROC gl3wCreateSamplers; PFNGLCREATESHADERPROC gl3wCreateShader; PFNGLCREATESHADERPROGRAMVPROC gl3wCreateShaderProgramv; PFNGLCREATESYNCFROMCLEVENTARBPROC gl3wCreateSyncFromCLeventARB; PFNGLCREATETEXTURESPROC gl3wCreateTextures; PFNGLCREATETRANSFORMFEEDBACKSPROC gl3wCreateTransformFeedbacks; PFNGLCREATEVERTEXARRAYSPROC gl3wCreateVertexArrays; PFNGLCULLFACEPROC gl3wCullFace; PFNGLDEBUGMESSAGECALLBACKPROC gl3wDebugMessageCallback; PFNGLDEBUGMESSAGECALLBACKARBPROC gl3wDebugMessageCallbackARB; PFNGLDEBUGMESSAGECONTROLPROC gl3wDebugMessageControl; PFNGLDEBUGMESSAGECONTROLARBPROC gl3wDebugMessageControlARB; PFNGLDEBUGMESSAGEINSERTPROC gl3wDebugMessageInsert; PFNGLDEBUGMESSAGEINSERTARBPROC gl3wDebugMessageInsertARB; PFNGLDELETEBUFFERSPROC gl3wDeleteBuffers; PFNGLDELETEFRAMEBUFFERSPROC gl3wDeleteFramebuffers; PFNGLDELETENAMEDSTRINGARBPROC gl3wDeleteNamedStringARB; PFNGLDELETEPROGRAMPROC gl3wDeleteProgram; PFNGLDELETEPROGRAMPIPELINESPROC gl3wDeleteProgramPipelines; PFNGLDELETEQUERIESPROC gl3wDeleteQueries; PFNGLDELETERENDERBUFFERSPROC gl3wDeleteRenderbuffers; PFNGLDELETESAMPLERSPROC gl3wDeleteSamplers; PFNGLDELETESHADERPROC gl3wDeleteShader; PFNGLDELETESYNCPROC gl3wDeleteSync; PFNGLDELETETEXTURESPROC gl3wDeleteTextures; PFNGLDELETETRANSFORMFEEDBACKSPROC gl3wDeleteTransformFeedbacks; PFNGLDELETEVERTEXARRAYSPROC gl3wDeleteVertexArrays; PFNGLDEPTHFUNCPROC gl3wDepthFunc; PFNGLDEPTHMASKPROC gl3wDepthMask; PFNGLDEPTHRANGEPROC gl3wDepthRange; PFNGLDEPTHRANGEARRAYVPROC gl3wDepthRangeArrayv; PFNGLDEPTHRANGEINDEXEDPROC gl3wDepthRangeIndexed; PFNGLDEPTHRANGEFPROC gl3wDepthRangef; PFNGLDETACHSHADERPROC gl3wDetachShader; PFNGLDISABLEPROC gl3wDisable; PFNGLDISABLEVERTEXARRAYATTRIBPROC gl3wDisableVertexArrayAttrib; PFNGLDISABLEVERTEXATTRIBARRAYPROC gl3wDisableVertexAttribArray; PFNGLDISABLEIPROC gl3wDisablei; PFNGLDISPATCHCOMPUTEPROC gl3wDispatchCompute; PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC gl3wDispatchComputeGroupSizeARB; PFNGLDISPATCHCOMPUTEINDIRECTPROC gl3wDispatchComputeIndirect; PFNGLDRAWARRAYSPROC gl3wDrawArrays; PFNGLDRAWARRAYSINDIRECTPROC gl3wDrawArraysIndirect; PFNGLDRAWARRAYSINSTANCEDPROC gl3wDrawArraysInstanced; PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC gl3wDrawArraysInstancedBaseInstance; PFNGLDRAWBUFFERPROC gl3wDrawBuffer; PFNGLDRAWBUFFERSPROC gl3wDrawBuffers; PFNGLDRAWELEMENTSPROC gl3wDrawElements; PFNGLDRAWELEMENTSBASEVERTEXPROC gl3wDrawElementsBaseVertex; PFNGLDRAWELEMENTSINDIRECTPROC gl3wDrawElementsIndirect; PFNGLDRAWELEMENTSINSTANCEDPROC gl3wDrawElementsInstanced; PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC gl3wDrawElementsInstancedBaseInstance; PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC gl3wDrawElementsInstancedBaseVertex; PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC gl3wDrawElementsInstancedBaseVertexBaseInstance; PFNGLDRAWRANGEELEMENTSPROC gl3wDrawRangeElements; PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC gl3wDrawRangeElementsBaseVertex; PFNGLDRAWTRANSFORMFEEDBACKPROC gl3wDrawTransformFeedback; PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC gl3wDrawTransformFeedbackInstanced; PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC gl3wDrawTransformFeedbackStream; PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC gl3wDrawTransformFeedbackStreamInstanced; PFNGLENABLEPROC gl3wEnable; PFNGLENABLEVERTEXARRAYATTRIBPROC gl3wEnableVertexArrayAttrib; PFNGLENABLEVERTEXATTRIBARRAYPROC gl3wEnableVertexAttribArray; PFNGLENABLEIPROC gl3wEnablei; PFNGLENDCONDITIONALRENDERPROC gl3wEndConditionalRender; PFNGLENDQUERYPROC gl3wEndQuery; PFNGLENDQUERYINDEXEDPROC gl3wEndQueryIndexed; PFNGLENDTRANSFORMFEEDBACKPROC gl3wEndTransformFeedback; PFNGLFENCESYNCPROC gl3wFenceSync; PFNGLFINISHPROC gl3wFinish; PFNGLFLUSHPROC gl3wFlush; PFNGLFLUSHMAPPEDBUFFERRANGEPROC gl3wFlushMappedBufferRange; PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC gl3wFlushMappedNamedBufferRange; PFNGLFRAMEBUFFERPARAMETERIPROC gl3wFramebufferParameteri; PFNGLFRAMEBUFFERRENDERBUFFERPROC gl3wFramebufferRenderbuffer; PFNGLFRAMEBUFFERTEXTUREPROC gl3wFramebufferTexture; PFNGLFRAMEBUFFERTEXTURE1DPROC gl3wFramebufferTexture1D; PFNGLFRAMEBUFFERTEXTURE2DPROC gl3wFramebufferTexture2D; PFNGLFRAMEBUFFERTEXTURE3DPROC gl3wFramebufferTexture3D; PFNGLFRAMEBUFFERTEXTURELAYERPROC gl3wFramebufferTextureLayer; PFNGLFRONTFACEPROC gl3wFrontFace; PFNGLGENBUFFERSPROC gl3wGenBuffers; PFNGLGENFRAMEBUFFERSPROC gl3wGenFramebuffers; PFNGLGENPROGRAMPIPELINESPROC gl3wGenProgramPipelines; PFNGLGENQUERIESPROC gl3wGenQueries; PFNGLGENRENDERBUFFERSPROC gl3wGenRenderbuffers; PFNGLGENSAMPLERSPROC gl3wGenSamplers; PFNGLGENTEXTURESPROC gl3wGenTextures; PFNGLGENTRANSFORMFEEDBACKSPROC gl3wGenTransformFeedbacks; PFNGLGENVERTEXARRAYSPROC gl3wGenVertexArrays; PFNGLGENERATEMIPMAPPROC gl3wGenerateMipmap; PFNGLGENERATETEXTUREMIPMAPPROC gl3wGenerateTextureMipmap; PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC gl3wGetActiveAtomicCounterBufferiv; PFNGLGETACTIVEATTRIBPROC gl3wGetActiveAttrib; PFNGLGETACTIVESUBROUTINENAMEPROC gl3wGetActiveSubroutineName; PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC gl3wGetActiveSubroutineUniformName; PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC gl3wGetActiveSubroutineUniformiv; PFNGLGETACTIVEUNIFORMPROC gl3wGetActiveUniform; PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC gl3wGetActiveUniformBlockName; PFNGLGETACTIVEUNIFORMBLOCKIVPROC gl3wGetActiveUniformBlockiv; PFNGLGETACTIVEUNIFORMNAMEPROC gl3wGetActiveUniformName; PFNGLGETACTIVEUNIFORMSIVPROC gl3wGetActiveUniformsiv; PFNGLGETATTACHEDSHADERSPROC gl3wGetAttachedShaders; PFNGLGETATTRIBLOCATIONPROC gl3wGetAttribLocation; PFNGLGETBOOLEANI_VPROC gl3wGetBooleani_v; PFNGLGETBOOLEANVPROC gl3wGetBooleanv; PFNGLGETBUFFERPARAMETERI64VPROC gl3wGetBufferParameteri64v; PFNGLGETBUFFERPARAMETERIVPROC gl3wGetBufferParameteriv; PFNGLGETBUFFERPOINTERVPROC gl3wGetBufferPointerv; PFNGLGETBUFFERSUBDATAPROC gl3wGetBufferSubData; PFNGLGETCOMPRESSEDTEXIMAGEPROC gl3wGetCompressedTexImage; PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC gl3wGetCompressedTextureImage; PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC gl3wGetCompressedTextureSubImage; PFNGLGETDEBUGMESSAGELOGPROC gl3wGetDebugMessageLog; PFNGLGETDEBUGMESSAGELOGARBPROC gl3wGetDebugMessageLogARB; PFNGLGETDOUBLEI_VPROC gl3wGetDoublei_v; PFNGLGETDOUBLEVPROC gl3wGetDoublev; PFNGLGETERRORPROC gl3wGetError; PFNGLGETFLOATI_VPROC gl3wGetFloati_v; PFNGLGETFLOATVPROC gl3wGetFloatv; PFNGLGETFRAGDATAINDEXPROC gl3wGetFragDataIndex; PFNGLGETFRAGDATALOCATIONPROC gl3wGetFragDataLocation; PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC gl3wGetFramebufferAttachmentParameteriv; PFNGLGETFRAMEBUFFERPARAMETERIVPROC gl3wGetFramebufferParameteriv; PFNGLGETGRAPHICSRESETSTATUSPROC gl3wGetGraphicsResetStatus; PFNGLGETGRAPHICSRESETSTATUSARBPROC gl3wGetGraphicsResetStatusARB; PFNGLGETIMAGEHANDLEARBPROC gl3wGetImageHandleARB; PFNGLGETINTEGER64I_VPROC gl3wGetInteger64i_v; PFNGLGETINTEGER64VPROC gl3wGetInteger64v; PFNGLGETINTEGERI_VPROC gl3wGetIntegeri_v; PFNGLGETINTEGERVPROC gl3wGetIntegerv; PFNGLGETINTERNALFORMATI64VPROC gl3wGetInternalformati64v; PFNGLGETINTERNALFORMATIVPROC gl3wGetInternalformativ; PFNGLGETMULTISAMPLEFVPROC gl3wGetMultisamplefv; PFNGLGETNAMEDBUFFERPARAMETERI64VPROC gl3wGetNamedBufferParameteri64v; PFNGLGETNAMEDBUFFERPARAMETERIVPROC gl3wGetNamedBufferParameteriv; PFNGLGETNAMEDBUFFERPOINTERVPROC gl3wGetNamedBufferPointerv; PFNGLGETNAMEDBUFFERSUBDATAPROC gl3wGetNamedBufferSubData; PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC gl3wGetNamedFramebufferAttachmentParameteriv; PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC gl3wGetNamedFramebufferParameteriv; PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC gl3wGetNamedRenderbufferParameteriv; PFNGLGETNAMEDSTRINGARBPROC gl3wGetNamedStringARB; PFNGLGETNAMEDSTRINGIVARBPROC gl3wGetNamedStringivARB; PFNGLGETOBJECTLABELPROC gl3wGetObjectLabel; PFNGLGETOBJECTPTRLABELPROC gl3wGetObjectPtrLabel; PFNGLGETPOINTERVPROC gl3wGetPointerv; PFNGLGETPROGRAMBINARYPROC gl3wGetProgramBinary; PFNGLGETPROGRAMINFOLOGPROC gl3wGetProgramInfoLog; PFNGLGETPROGRAMINTERFACEIVPROC gl3wGetProgramInterfaceiv; PFNGLGETPROGRAMPIPELINEINFOLOGPROC gl3wGetProgramPipelineInfoLog; PFNGLGETPROGRAMPIPELINEIVPROC gl3wGetProgramPipelineiv; PFNGLGETPROGRAMRESOURCEINDEXPROC gl3wGetProgramResourceIndex; PFNGLGETPROGRAMRESOURCELOCATIONPROC gl3wGetProgramResourceLocation; PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC gl3wGetProgramResourceLocationIndex; PFNGLGETPROGRAMRESOURCENAMEPROC gl3wGetProgramResourceName; PFNGLGETPROGRAMRESOURCEIVPROC gl3wGetProgramResourceiv; PFNGLGETPROGRAMSTAGEIVPROC gl3wGetProgramStageiv; PFNGLGETPROGRAMIVPROC gl3wGetProgramiv; PFNGLGETQUERYBUFFEROBJECTI64VPROC gl3wGetQueryBufferObjecti64v; PFNGLGETQUERYBUFFEROBJECTIVPROC gl3wGetQueryBufferObjectiv; PFNGLGETQUERYBUFFEROBJECTUI64VPROC gl3wGetQueryBufferObjectui64v; PFNGLGETQUERYBUFFEROBJECTUIVPROC gl3wGetQueryBufferObjectuiv; PFNGLGETQUERYINDEXEDIVPROC gl3wGetQueryIndexediv; PFNGLGETQUERYOBJECTI64VPROC gl3wGetQueryObjecti64v; PFNGLGETQUERYOBJECTIVPROC gl3wGetQueryObjectiv; PFNGLGETQUERYOBJECTUI64VPROC gl3wGetQueryObjectui64v; PFNGLGETQUERYOBJECTUIVPROC gl3wGetQueryObjectuiv; PFNGLGETQUERYIVPROC gl3wGetQueryiv; PFNGLGETRENDERBUFFERPARAMETERIVPROC gl3wGetRenderbufferParameteriv; PFNGLGETSAMPLERPARAMETERIIVPROC gl3wGetSamplerParameterIiv; PFNGLGETSAMPLERPARAMETERIUIVPROC gl3wGetSamplerParameterIuiv; PFNGLGETSAMPLERPARAMETERFVPROC gl3wGetSamplerParameterfv; PFNGLGETSAMPLERPARAMETERIVPROC gl3wGetSamplerParameteriv; PFNGLGETSHADERINFOLOGPROC gl3wGetShaderInfoLog; PFNGLGETSHADERPRECISIONFORMATPROC gl3wGetShaderPrecisionFormat; PFNGLGETSHADERSOURCEPROC gl3wGetShaderSource; PFNGLGETSHADERIVPROC gl3wGetShaderiv; PFNGLGETSTRINGPROC gl3wGetString; PFNGLGETSTRINGIPROC gl3wGetStringi; PFNGLGETSUBROUTINEINDEXPROC gl3wGetSubroutineIndex; PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC gl3wGetSubroutineUniformLocation; PFNGLGETSYNCIVPROC gl3wGetSynciv; PFNGLGETTEXIMAGEPROC gl3wGetTexImage; PFNGLGETTEXLEVELPARAMETERFVPROC gl3wGetTexLevelParameterfv; PFNGLGETTEXLEVELPARAMETERIVPROC gl3wGetTexLevelParameteriv; PFNGLGETTEXPARAMETERIIVPROC gl3wGetTexParameterIiv; PFNGLGETTEXPARAMETERIUIVPROC gl3wGetTexParameterIuiv; PFNGLGETTEXPARAMETERFVPROC gl3wGetTexParameterfv; PFNGLGETTEXPARAMETERIVPROC gl3wGetTexParameteriv; PFNGLGETTEXTUREHANDLEARBPROC gl3wGetTextureHandleARB; PFNGLGETTEXTUREIMAGEPROC gl3wGetTextureImage; PFNGLGETTEXTURELEVELPARAMETERFVPROC gl3wGetTextureLevelParameterfv; PFNGLGETTEXTURELEVELPARAMETERIVPROC gl3wGetTextureLevelParameteriv; PFNGLGETTEXTUREPARAMETERIIVPROC gl3wGetTextureParameterIiv; PFNGLGETTEXTUREPARAMETERIUIVPROC gl3wGetTextureParameterIuiv; PFNGLGETTEXTUREPARAMETERFVPROC gl3wGetTextureParameterfv; PFNGLGETTEXTUREPARAMETERIVPROC gl3wGetTextureParameteriv; PFNGLGETTEXTURESAMPLERHANDLEARBPROC gl3wGetTextureSamplerHandleARB; PFNGLGETTEXTURESUBIMAGEPROC gl3wGetTextureSubImage; PFNGLGETTRANSFORMFEEDBACKVARYINGPROC gl3wGetTransformFeedbackVarying; PFNGLGETTRANSFORMFEEDBACKI64_VPROC gl3wGetTransformFeedbacki64_v; PFNGLGETTRANSFORMFEEDBACKI_VPROC gl3wGetTransformFeedbacki_v; PFNGLGETTRANSFORMFEEDBACKIVPROC gl3wGetTransformFeedbackiv; PFNGLGETUNIFORMBLOCKINDEXPROC gl3wGetUniformBlockIndex; PFNGLGETUNIFORMINDICESPROC gl3wGetUniformIndices; PFNGLGETUNIFORMLOCATIONPROC gl3wGetUniformLocation; PFNGLGETUNIFORMSUBROUTINEUIVPROC gl3wGetUniformSubroutineuiv; PFNGLGETUNIFORMDVPROC gl3wGetUniformdv; PFNGLGETUNIFORMFVPROC gl3wGetUniformfv; PFNGLGETUNIFORMIVPROC gl3wGetUniformiv; PFNGLGETUNIFORMUIVPROC gl3wGetUniformuiv; PFNGLGETVERTEXARRAYINDEXED64IVPROC gl3wGetVertexArrayIndexed64iv; PFNGLGETVERTEXARRAYINDEXEDIVPROC gl3wGetVertexArrayIndexediv; PFNGLGETVERTEXARRAYIVPROC gl3wGetVertexArrayiv; PFNGLGETVERTEXATTRIBIIVPROC gl3wGetVertexAttribIiv; PFNGLGETVERTEXATTRIBIUIVPROC gl3wGetVertexAttribIuiv; PFNGLGETVERTEXATTRIBLDVPROC gl3wGetVertexAttribLdv; PFNGLGETVERTEXATTRIBLUI64VARBPROC gl3wGetVertexAttribLui64vARB; PFNGLGETVERTEXATTRIBPOINTERVPROC gl3wGetVertexAttribPointerv; PFNGLGETVERTEXATTRIBDVPROC gl3wGetVertexAttribdv; PFNGLGETVERTEXATTRIBFVPROC gl3wGetVertexAttribfv; PFNGLGETVERTEXATTRIBIVPROC gl3wGetVertexAttribiv; PFNGLGETNCOMPRESSEDTEXIMAGEPROC gl3wGetnCompressedTexImage; PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC gl3wGetnCompressedTexImageARB; PFNGLGETNTEXIMAGEPROC gl3wGetnTexImage; PFNGLGETNTEXIMAGEARBPROC gl3wGetnTexImageARB; PFNGLGETNUNIFORMDVPROC gl3wGetnUniformdv; PFNGLGETNUNIFORMDVARBPROC gl3wGetnUniformdvARB; PFNGLGETNUNIFORMFVPROC gl3wGetnUniformfv; PFNGLGETNUNIFORMFVARBPROC gl3wGetnUniformfvARB; PFNGLGETNUNIFORMIVPROC gl3wGetnUniformiv; PFNGLGETNUNIFORMIVARBPROC gl3wGetnUniformivARB; PFNGLGETNUNIFORMUIVPROC gl3wGetnUniformuiv; PFNGLGETNUNIFORMUIVARBPROC gl3wGetnUniformuivARB; PFNGLHINTPROC gl3wHint; PFNGLINVALIDATEBUFFERDATAPROC gl3wInvalidateBufferData; PFNGLINVALIDATEBUFFERSUBDATAPROC gl3wInvalidateBufferSubData; PFNGLINVALIDATEFRAMEBUFFERPROC gl3wInvalidateFramebuffer; PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC gl3wInvalidateNamedFramebufferData; PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC gl3wInvalidateNamedFramebufferSubData; PFNGLINVALIDATESUBFRAMEBUFFERPROC gl3wInvalidateSubFramebuffer; PFNGLINVALIDATETEXIMAGEPROC gl3wInvalidateTexImage; PFNGLINVALIDATETEXSUBIMAGEPROC gl3wInvalidateTexSubImage; PFNGLISBUFFERPROC gl3wIsBuffer; PFNGLISENABLEDPROC gl3wIsEnabled; PFNGLISENABLEDIPROC gl3wIsEnabledi; PFNGLISFRAMEBUFFERPROC gl3wIsFramebuffer; PFNGLISIMAGEHANDLERESIDENTARBPROC gl3wIsImageHandleResidentARB; PFNGLISNAMEDSTRINGARBPROC gl3wIsNamedStringARB; PFNGLISPROGRAMPROC gl3wIsProgram; PFNGLISPROGRAMPIPELINEPROC gl3wIsProgramPipeline; PFNGLISQUERYPROC gl3wIsQuery; PFNGLISRENDERBUFFERPROC gl3wIsRenderbuffer; PFNGLISSAMPLERPROC gl3wIsSampler; PFNGLISSHADERPROC gl3wIsShader; PFNGLISSYNCPROC gl3wIsSync; PFNGLISTEXTUREPROC gl3wIsTexture; PFNGLISTEXTUREHANDLERESIDENTARBPROC gl3wIsTextureHandleResidentARB; PFNGLISTRANSFORMFEEDBACKPROC gl3wIsTransformFeedback; PFNGLISVERTEXARRAYPROC gl3wIsVertexArray; PFNGLLINEWIDTHPROC gl3wLineWidth; PFNGLLINKPROGRAMPROC gl3wLinkProgram; PFNGLLOGICOPPROC gl3wLogicOp; PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC gl3wMakeImageHandleNonResidentARB; PFNGLMAKEIMAGEHANDLERESIDENTARBPROC gl3wMakeImageHandleResidentARB; PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC gl3wMakeTextureHandleNonResidentARB; PFNGLMAKETEXTUREHANDLERESIDENTARBPROC gl3wMakeTextureHandleResidentARB; PFNGLMAPBUFFERPROC gl3wMapBuffer; PFNGLMAPBUFFERRANGEPROC gl3wMapBufferRange; PFNGLMAPNAMEDBUFFERPROC gl3wMapNamedBuffer; PFNGLMAPNAMEDBUFFERRANGEPROC gl3wMapNamedBufferRange; PFNGLMEMORYBARRIERPROC gl3wMemoryBarrier; PFNGLMEMORYBARRIERBYREGIONPROC gl3wMemoryBarrierByRegion; PFNGLMINSAMPLESHADINGPROC gl3wMinSampleShading; PFNGLMINSAMPLESHADINGARBPROC gl3wMinSampleShadingARB; PFNGLMULTIDRAWARRAYSPROC gl3wMultiDrawArrays; PFNGLMULTIDRAWARRAYSINDIRECTPROC gl3wMultiDrawArraysIndirect; PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC gl3wMultiDrawArraysIndirectCountARB; PFNGLMULTIDRAWELEMENTSPROC gl3wMultiDrawElements; PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC gl3wMultiDrawElementsBaseVertex; PFNGLMULTIDRAWELEMENTSINDIRECTPROC gl3wMultiDrawElementsIndirect; PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC gl3wMultiDrawElementsIndirectCountARB; PFNGLNAMEDBUFFERDATAPROC gl3wNamedBufferData; PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC gl3wNamedBufferPageCommitmentARB; PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC gl3wNamedBufferPageCommitmentEXT; PFNGLNAMEDBUFFERSTORAGEPROC gl3wNamedBufferStorage; PFNGLNAMEDBUFFERSUBDATAPROC gl3wNamedBufferSubData; PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC gl3wNamedFramebufferDrawBuffer; PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC gl3wNamedFramebufferDrawBuffers; PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC gl3wNamedFramebufferParameteri; PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC gl3wNamedFramebufferReadBuffer; PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC gl3wNamedFramebufferRenderbuffer; PFNGLNAMEDFRAMEBUFFERTEXTUREPROC gl3wNamedFramebufferTexture; PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC gl3wNamedFramebufferTextureLayer; PFNGLNAMEDRENDERBUFFERSTORAGEPROC gl3wNamedRenderbufferStorage; PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC gl3wNamedRenderbufferStorageMultisample; PFNGLNAMEDSTRINGARBPROC gl3wNamedStringARB; PFNGLOBJECTLABELPROC gl3wObjectLabel; PFNGLOBJECTPTRLABELPROC gl3wObjectPtrLabel; PFNGLPATCHPARAMETERFVPROC gl3wPatchParameterfv; PFNGLPATCHPARAMETERIPROC gl3wPatchParameteri; PFNGLPAUSETRANSFORMFEEDBACKPROC gl3wPauseTransformFeedback; PFNGLPIXELSTOREFPROC gl3wPixelStoref; PFNGLPIXELSTOREIPROC gl3wPixelStorei; PFNGLPOINTPARAMETERFPROC gl3wPointParameterf; PFNGLPOINTPARAMETERFVPROC gl3wPointParameterfv; PFNGLPOINTPARAMETERIPROC gl3wPointParameteri; PFNGLPOINTPARAMETERIVPROC gl3wPointParameteriv; PFNGLPOINTSIZEPROC gl3wPointSize; PFNGLPOLYGONMODEPROC gl3wPolygonMode; PFNGLPOLYGONOFFSETPROC gl3wPolygonOffset; PFNGLPOPDEBUGGROUPPROC gl3wPopDebugGroup; PFNGLPRIMITIVERESTARTINDEXPROC gl3wPrimitiveRestartIndex; PFNGLPROGRAMBINARYPROC gl3wProgramBinary; PFNGLPROGRAMPARAMETERIPROC gl3wProgramParameteri; PFNGLPROGRAMUNIFORM1DPROC gl3wProgramUniform1d; PFNGLPROGRAMUNIFORM1DVPROC gl3wProgramUniform1dv; PFNGLPROGRAMUNIFORM1FPROC gl3wProgramUniform1f; PFNGLPROGRAMUNIFORM1FVPROC gl3wProgramUniform1fv; PFNGLPROGRAMUNIFORM1IPROC gl3wProgramUniform1i; PFNGLPROGRAMUNIFORM1IVPROC gl3wProgramUniform1iv; PFNGLPROGRAMUNIFORM1UIPROC gl3wProgramUniform1ui; PFNGLPROGRAMUNIFORM1UIVPROC gl3wProgramUniform1uiv; PFNGLPROGRAMUNIFORM2DPROC gl3wProgramUniform2d; PFNGLPROGRAMUNIFORM2DVPROC gl3wProgramUniform2dv; PFNGLPROGRAMUNIFORM2FPROC gl3wProgramUniform2f; PFNGLPROGRAMUNIFORM2FVPROC gl3wProgramUniform2fv; PFNGLPROGRAMUNIFORM2IPROC gl3wProgramUniform2i; PFNGLPROGRAMUNIFORM2IVPROC gl3wProgramUniform2iv; PFNGLPROGRAMUNIFORM2UIPROC gl3wProgramUniform2ui; PFNGLPROGRAMUNIFORM2UIVPROC gl3wProgramUniform2uiv; PFNGLPROGRAMUNIFORM3DPROC gl3wProgramUniform3d; PFNGLPROGRAMUNIFORM3DVPROC gl3wProgramUniform3dv; PFNGLPROGRAMUNIFORM3FPROC gl3wProgramUniform3f; PFNGLPROGRAMUNIFORM3FVPROC gl3wProgramUniform3fv; PFNGLPROGRAMUNIFORM3IPROC gl3wProgramUniform3i; PFNGLPROGRAMUNIFORM3IVPROC gl3wProgramUniform3iv; PFNGLPROGRAMUNIFORM3UIPROC gl3wProgramUniform3ui; PFNGLPROGRAMUNIFORM3UIVPROC gl3wProgramUniform3uiv; PFNGLPROGRAMUNIFORM4DPROC gl3wProgramUniform4d; PFNGLPROGRAMUNIFORM4DVPROC gl3wProgramUniform4dv; PFNGLPROGRAMUNIFORM4FPROC gl3wProgramUniform4f; PFNGLPROGRAMUNIFORM4FVPROC gl3wProgramUniform4fv; PFNGLPROGRAMUNIFORM4IPROC gl3wProgramUniform4i; PFNGLPROGRAMUNIFORM4IVPROC gl3wProgramUniform4iv; PFNGLPROGRAMUNIFORM4UIPROC gl3wProgramUniform4ui; PFNGLPROGRAMUNIFORM4UIVPROC gl3wProgramUniform4uiv; PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC gl3wProgramUniformHandleui64ARB; PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC gl3wProgramUniformHandleui64vARB; PFNGLPROGRAMUNIFORMMATRIX2DVPROC gl3wProgramUniformMatrix2dv; PFNGLPROGRAMUNIFORMMATRIX2FVPROC gl3wProgramUniformMatrix2fv; PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC gl3wProgramUniformMatrix2x3dv; PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC gl3wProgramUniformMatrix2x3fv; PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC gl3wProgramUniformMatrix2x4dv; PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC gl3wProgramUniformMatrix2x4fv; PFNGLPROGRAMUNIFORMMATRIX3DVPROC gl3wProgramUniformMatrix3dv; PFNGLPROGRAMUNIFORMMATRIX3FVPROC gl3wProgramUniformMatrix3fv; PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC gl3wProgramUniformMatrix3x2dv; PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC gl3wProgramUniformMatrix3x2fv; PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC gl3wProgramUniformMatrix3x4dv; PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC gl3wProgramUniformMatrix3x4fv; PFNGLPROGRAMUNIFORMMATRIX4DVPROC gl3wProgramUniformMatrix4dv; PFNGLPROGRAMUNIFORMMATRIX4FVPROC gl3wProgramUniformMatrix4fv; PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC gl3wProgramUniformMatrix4x2dv; PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC gl3wProgramUniformMatrix4x2fv; PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC gl3wProgramUniformMatrix4x3dv; PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC gl3wProgramUniformMatrix4x3fv; PFNGLPROVOKINGVERTEXPROC gl3wProvokingVertex; PFNGLPUSHDEBUGGROUPPROC gl3wPushDebugGroup; PFNGLQUERYCOUNTERPROC gl3wQueryCounter; PFNGLREADBUFFERPROC gl3wReadBuffer; PFNGLREADPIXELSPROC gl3wReadPixels; PFNGLREADNPIXELSPROC gl3wReadnPixels; PFNGLREADNPIXELSARBPROC gl3wReadnPixelsARB; PFNGLRELEASESHADERCOMPILERPROC gl3wReleaseShaderCompiler; PFNGLRENDERBUFFERSTORAGEPROC gl3wRenderbufferStorage; PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC gl3wRenderbufferStorageMultisample; PFNGLRESUMETRANSFORMFEEDBACKPROC gl3wResumeTransformFeedback; PFNGLSAMPLECOVERAGEPROC gl3wSampleCoverage; PFNGLSAMPLEMASKIPROC gl3wSampleMaski; PFNGLSAMPLERPARAMETERIIVPROC gl3wSamplerParameterIiv; PFNGLSAMPLERPARAMETERIUIVPROC gl3wSamplerParameterIuiv; PFNGLSAMPLERPARAMETERFPROC gl3wSamplerParameterf; PFNGLSAMPLERPARAMETERFVPROC gl3wSamplerParameterfv; PFNGLSAMPLERPARAMETERIPROC gl3wSamplerParameteri; PFNGLSAMPLERPARAMETERIVPROC gl3wSamplerParameteriv; PFNGLSCISSORPROC gl3wScissor; PFNGLSCISSORARRAYVPROC gl3wScissorArrayv; PFNGLSCISSORINDEXEDPROC gl3wScissorIndexed; PFNGLSCISSORINDEXEDVPROC gl3wScissorIndexedv; PFNGLSHADERBINARYPROC gl3wShaderBinary; PFNGLSHADERSOURCEPROC gl3wShaderSource; PFNGLSHADERSTORAGEBLOCKBINDINGPROC gl3wShaderStorageBlockBinding; PFNGLSTENCILFUNCPROC gl3wStencilFunc; PFNGLSTENCILFUNCSEPARATEPROC gl3wStencilFuncSeparate; PFNGLSTENCILMASKPROC gl3wStencilMask; PFNGLSTENCILMASKSEPARATEPROC gl3wStencilMaskSeparate; PFNGLSTENCILOPPROC gl3wStencilOp; PFNGLSTENCILOPSEPARATEPROC gl3wStencilOpSeparate; PFNGLTEXBUFFERPROC gl3wTexBuffer; PFNGLTEXBUFFERRANGEPROC gl3wTexBufferRange; PFNGLTEXIMAGE1DPROC gl3wTexImage1D; PFNGLTEXIMAGE2DPROC gl3wTexImage2D; PFNGLTEXIMAGE2DMULTISAMPLEPROC gl3wTexImage2DMultisample; PFNGLTEXIMAGE3DPROC gl3wTexImage3D; PFNGLTEXIMAGE3DMULTISAMPLEPROC gl3wTexImage3DMultisample; PFNGLTEXPAGECOMMITMENTARBPROC gl3wTexPageCommitmentARB; PFNGLTEXPARAMETERIIVPROC gl3wTexParameterIiv; PFNGLTEXPARAMETERIUIVPROC gl3wTexParameterIuiv; PFNGLTEXPARAMETERFPROC gl3wTexParameterf; PFNGLTEXPARAMETERFVPROC gl3wTexParameterfv; PFNGLTEXPARAMETERIPROC gl3wTexParameteri; PFNGLTEXPARAMETERIVPROC gl3wTexParameteriv; PFNGLTEXSTORAGE1DPROC gl3wTexStorage1D; PFNGLTEXSTORAGE2DPROC gl3wTexStorage2D; PFNGLTEXSTORAGE2DMULTISAMPLEPROC gl3wTexStorage2DMultisample; PFNGLTEXSTORAGE3DPROC gl3wTexStorage3D; PFNGLTEXSTORAGE3DMULTISAMPLEPROC gl3wTexStorage3DMultisample; PFNGLTEXSUBIMAGE1DPROC gl3wTexSubImage1D; PFNGLTEXSUBIMAGE2DPROC gl3wTexSubImage2D; PFNGLTEXSUBIMAGE3DPROC gl3wTexSubImage3D; PFNGLTEXTUREBARRIERPROC gl3wTextureBarrier; PFNGLTEXTUREBUFFERPROC gl3wTextureBuffer; PFNGLTEXTUREBUFFERRANGEPROC gl3wTextureBufferRange; PFNGLTEXTUREPARAMETERIIVPROC gl3wTextureParameterIiv; PFNGLTEXTUREPARAMETERIUIVPROC gl3wTextureParameterIuiv; PFNGLTEXTUREPARAMETERFPROC gl3wTextureParameterf; PFNGLTEXTUREPARAMETERFVPROC gl3wTextureParameterfv; PFNGLTEXTUREPARAMETERIPROC gl3wTextureParameteri; PFNGLTEXTUREPARAMETERIVPROC gl3wTextureParameteriv; PFNGLTEXTURESTORAGE1DPROC gl3wTextureStorage1D; PFNGLTEXTURESTORAGE2DPROC gl3wTextureStorage2D; PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC gl3wTextureStorage2DMultisample; PFNGLTEXTURESTORAGE3DPROC gl3wTextureStorage3D; PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC gl3wTextureStorage3DMultisample; PFNGLTEXTURESUBIMAGE1DPROC gl3wTextureSubImage1D; PFNGLTEXTURESUBIMAGE2DPROC gl3wTextureSubImage2D; PFNGLTEXTURESUBIMAGE3DPROC gl3wTextureSubImage3D; PFNGLTEXTUREVIEWPROC gl3wTextureView; PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC gl3wTransformFeedbackBufferBase; PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC gl3wTransformFeedbackBufferRange; PFNGLTRANSFORMFEEDBACKVARYINGSPROC gl3wTransformFeedbackVaryings; PFNGLUNIFORM1DPROC gl3wUniform1d; PFNGLUNIFORM1DVPROC gl3wUniform1dv; PFNGLUNIFORM1FPROC gl3wUniform1f; PFNGLUNIFORM1FVPROC gl3wUniform1fv; PFNGLUNIFORM1IPROC gl3wUniform1i; PFNGLUNIFORM1IVPROC gl3wUniform1iv; PFNGLUNIFORM1UIPROC gl3wUniform1ui; PFNGLUNIFORM1UIVPROC gl3wUniform1uiv; PFNGLUNIFORM2DPROC gl3wUniform2d; PFNGLUNIFORM2DVPROC gl3wUniform2dv; PFNGLUNIFORM2FPROC gl3wUniform2f; PFNGLUNIFORM2FVPROC gl3wUniform2fv; PFNGLUNIFORM2IPROC gl3wUniform2i; PFNGLUNIFORM2IVPROC gl3wUniform2iv; PFNGLUNIFORM2UIPROC gl3wUniform2ui; PFNGLUNIFORM2UIVPROC gl3wUniform2uiv; PFNGLUNIFORM3DPROC gl3wUniform3d; PFNGLUNIFORM3DVPROC gl3wUniform3dv; PFNGLUNIFORM3FPROC gl3wUniform3f; PFNGLUNIFORM3FVPROC gl3wUniform3fv; PFNGLUNIFORM3IPROC gl3wUniform3i; PFNGLUNIFORM3IVPROC gl3wUniform3iv; PFNGLUNIFORM3UIPROC gl3wUniform3ui; PFNGLUNIFORM3UIVPROC gl3wUniform3uiv; PFNGLUNIFORM4DPROC gl3wUniform4d; PFNGLUNIFORM4DVPROC gl3wUniform4dv; PFNGLUNIFORM4FPROC gl3wUniform4f; PFNGLUNIFORM4FVPROC gl3wUniform4fv; PFNGLUNIFORM4IPROC gl3wUniform4i; PFNGLUNIFORM4IVPROC gl3wUniform4iv; PFNGLUNIFORM4UIPROC gl3wUniform4ui; PFNGLUNIFORM4UIVPROC gl3wUniform4uiv; PFNGLUNIFORMBLOCKBINDINGPROC gl3wUniformBlockBinding; PFNGLUNIFORMHANDLEUI64ARBPROC gl3wUniformHandleui64ARB; PFNGLUNIFORMHANDLEUI64VARBPROC gl3wUniformHandleui64vARB; PFNGLUNIFORMMATRIX2DVPROC gl3wUniformMatrix2dv; PFNGLUNIFORMMATRIX2FVPROC gl3wUniformMatrix2fv; PFNGLUNIFORMMATRIX2X3DVPROC gl3wUniformMatrix2x3dv; PFNGLUNIFORMMATRIX2X3FVPROC gl3wUniformMatrix2x3fv; PFNGLUNIFORMMATRIX2X4DVPROC gl3wUniformMatrix2x4dv; PFNGLUNIFORMMATRIX2X4FVPROC gl3wUniformMatrix2x4fv; PFNGLUNIFORMMATRIX3DVPROC gl3wUniformMatrix3dv; PFNGLUNIFORMMATRIX3FVPROC gl3wUniformMatrix3fv; PFNGLUNIFORMMATRIX3X2DVPROC gl3wUniformMatrix3x2dv; PFNGLUNIFORMMATRIX3X2FVPROC gl3wUniformMatrix3x2fv; PFNGLUNIFORMMATRIX3X4DVPROC gl3wUniformMatrix3x4dv; PFNGLUNIFORMMATRIX3X4FVPROC gl3wUniformMatrix3x4fv; PFNGLUNIFORMMATRIX4DVPROC gl3wUniformMatrix4dv; PFNGLUNIFORMMATRIX4FVPROC gl3wUniformMatrix4fv; PFNGLUNIFORMMATRIX4X2DVPROC gl3wUniformMatrix4x2dv; PFNGLUNIFORMMATRIX4X2FVPROC gl3wUniformMatrix4x2fv; PFNGLUNIFORMMATRIX4X3DVPROC gl3wUniformMatrix4x3dv; PFNGLUNIFORMMATRIX4X3FVPROC gl3wUniformMatrix4x3fv; PFNGLUNIFORMSUBROUTINESUIVPROC gl3wUniformSubroutinesuiv; PFNGLUNMAPBUFFERPROC gl3wUnmapBuffer; PFNGLUNMAPNAMEDBUFFERPROC gl3wUnmapNamedBuffer; PFNGLUSEPROGRAMPROC gl3wUseProgram; PFNGLUSEPROGRAMSTAGESPROC gl3wUseProgramStages; PFNGLVALIDATEPROGRAMPROC gl3wValidateProgram; PFNGLVALIDATEPROGRAMPIPELINEPROC gl3wValidateProgramPipeline; PFNGLVERTEXARRAYATTRIBBINDINGPROC gl3wVertexArrayAttribBinding; PFNGLVERTEXARRAYATTRIBFORMATPROC gl3wVertexArrayAttribFormat; PFNGLVERTEXARRAYATTRIBIFORMATPROC gl3wVertexArrayAttribIFormat; PFNGLVERTEXARRAYATTRIBLFORMATPROC gl3wVertexArrayAttribLFormat; PFNGLVERTEXARRAYBINDINGDIVISORPROC gl3wVertexArrayBindingDivisor; PFNGLVERTEXARRAYELEMENTBUFFERPROC gl3wVertexArrayElementBuffer; PFNGLVERTEXARRAYVERTEXBUFFERPROC gl3wVertexArrayVertexBuffer; PFNGLVERTEXARRAYVERTEXBUFFERSPROC gl3wVertexArrayVertexBuffers; PFNGLVERTEXATTRIB1DPROC gl3wVertexAttrib1d; PFNGLVERTEXATTRIB1DVPROC gl3wVertexAttrib1dv; PFNGLVERTEXATTRIB1FPROC gl3wVertexAttrib1f; PFNGLVERTEXATTRIB1FVPROC gl3wVertexAttrib1fv; PFNGLVERTEXATTRIB1SPROC gl3wVertexAttrib1s; PFNGLVERTEXATTRIB1SVPROC gl3wVertexAttrib1sv; PFNGLVERTEXATTRIB2DPROC gl3wVertexAttrib2d; PFNGLVERTEXATTRIB2DVPROC gl3wVertexAttrib2dv; PFNGLVERTEXATTRIB2FPROC gl3wVertexAttrib2f; PFNGLVERTEXATTRIB2FVPROC gl3wVertexAttrib2fv; PFNGLVERTEXATTRIB2SPROC gl3wVertexAttrib2s; PFNGLVERTEXATTRIB2SVPROC gl3wVertexAttrib2sv; PFNGLVERTEXATTRIB3DPROC gl3wVertexAttrib3d; PFNGLVERTEXATTRIB3DVPROC gl3wVertexAttrib3dv; PFNGLVERTEXATTRIB3FPROC gl3wVertexAttrib3f; PFNGLVERTEXATTRIB3FVPROC gl3wVertexAttrib3fv; PFNGLVERTEXATTRIB3SPROC gl3wVertexAttrib3s; PFNGLVERTEXATTRIB3SVPROC gl3wVertexAttrib3sv; PFNGLVERTEXATTRIB4NBVPROC gl3wVertexAttrib4Nbv; PFNGLVERTEXATTRIB4NIVPROC gl3wVertexAttrib4Niv; PFNGLVERTEXATTRIB4NSVPROC gl3wVertexAttrib4Nsv; PFNGLVERTEXATTRIB4NUBPROC gl3wVertexAttrib4Nub; PFNGLVERTEXATTRIB4NUBVPROC gl3wVertexAttrib4Nubv; PFNGLVERTEXATTRIB4NUIVPROC gl3wVertexAttrib4Nuiv; PFNGLVERTEXATTRIB4NUSVPROC gl3wVertexAttrib4Nusv; PFNGLVERTEXATTRIB4BVPROC gl3wVertexAttrib4bv; PFNGLVERTEXATTRIB4DPROC gl3wVertexAttrib4d; PFNGLVERTEXATTRIB4DVPROC gl3wVertexAttrib4dv; PFNGLVERTEXATTRIB4FPROC gl3wVertexAttrib4f; PFNGLVERTEXATTRIB4FVPROC gl3wVertexAttrib4fv; PFNGLVERTEXATTRIB4IVPROC gl3wVertexAttrib4iv; PFNGLVERTEXATTRIB4SPROC gl3wVertexAttrib4s; PFNGLVERTEXATTRIB4SVPROC gl3wVertexAttrib4sv; PFNGLVERTEXATTRIB4UBVPROC gl3wVertexAttrib4ubv; PFNGLVERTEXATTRIB4UIVPROC gl3wVertexAttrib4uiv; PFNGLVERTEXATTRIB4USVPROC gl3wVertexAttrib4usv; PFNGLVERTEXATTRIBBINDINGPROC gl3wVertexAttribBinding; PFNGLVERTEXATTRIBDIVISORPROC gl3wVertexAttribDivisor; PFNGLVERTEXATTRIBFORMATPROC gl3wVertexAttribFormat; PFNGLVERTEXATTRIBI1IPROC gl3wVertexAttribI1i; PFNGLVERTEXATTRIBI1IVPROC gl3wVertexAttribI1iv; PFNGLVERTEXATTRIBI1UIPROC gl3wVertexAttribI1ui; PFNGLVERTEXATTRIBI1UIVPROC gl3wVertexAttribI1uiv; PFNGLVERTEXATTRIBI2IPROC gl3wVertexAttribI2i; PFNGLVERTEXATTRIBI2IVPROC gl3wVertexAttribI2iv; PFNGLVERTEXATTRIBI2UIPROC gl3wVertexAttribI2ui; PFNGLVERTEXATTRIBI2UIVPROC gl3wVertexAttribI2uiv; PFNGLVERTEXATTRIBI3IPROC gl3wVertexAttribI3i; PFNGLVERTEXATTRIBI3IVPROC gl3wVertexAttribI3iv; PFNGLVERTEXATTRIBI3UIPROC gl3wVertexAttribI3ui; PFNGLVERTEXATTRIBI3UIVPROC gl3wVertexAttribI3uiv; PFNGLVERTEXATTRIBI4BVPROC gl3wVertexAttribI4bv; PFNGLVERTEXATTRIBI4IPROC gl3wVertexAttribI4i; PFNGLVERTEXATTRIBI4IVPROC gl3wVertexAttribI4iv; PFNGLVERTEXATTRIBI4SVPROC gl3wVertexAttribI4sv; PFNGLVERTEXATTRIBI4UBVPROC gl3wVertexAttribI4ubv; PFNGLVERTEXATTRIBI4UIPROC gl3wVertexAttribI4ui; PFNGLVERTEXATTRIBI4UIVPROC gl3wVertexAttribI4uiv; PFNGLVERTEXATTRIBI4USVPROC gl3wVertexAttribI4usv; PFNGLVERTEXATTRIBIFORMATPROC gl3wVertexAttribIFormat; PFNGLVERTEXATTRIBIPOINTERPROC gl3wVertexAttribIPointer; PFNGLVERTEXATTRIBL1DPROC gl3wVertexAttribL1d; PFNGLVERTEXATTRIBL1DVPROC gl3wVertexAttribL1dv; PFNGLVERTEXATTRIBL1UI64ARBPROC gl3wVertexAttribL1ui64ARB; PFNGLVERTEXATTRIBL1UI64VARBPROC gl3wVertexAttribL1ui64vARB; PFNGLVERTEXATTRIBL2DPROC gl3wVertexAttribL2d; PFNGLVERTEXATTRIBL2DVPROC gl3wVertexAttribL2dv; PFNGLVERTEXATTRIBL3DPROC gl3wVertexAttribL3d; PFNGLVERTEXATTRIBL3DVPROC gl3wVertexAttribL3dv; PFNGLVERTEXATTRIBL4DPROC gl3wVertexAttribL4d; PFNGLVERTEXATTRIBL4DVPROC gl3wVertexAttribL4dv; PFNGLVERTEXATTRIBLFORMATPROC gl3wVertexAttribLFormat; PFNGLVERTEXATTRIBLPOINTERPROC gl3wVertexAttribLPointer; PFNGLVERTEXATTRIBP1UIPROC gl3wVertexAttribP1ui; PFNGLVERTEXATTRIBP1UIVPROC gl3wVertexAttribP1uiv; PFNGLVERTEXATTRIBP2UIPROC gl3wVertexAttribP2ui; PFNGLVERTEXATTRIBP2UIVPROC gl3wVertexAttribP2uiv; PFNGLVERTEXATTRIBP3UIPROC gl3wVertexAttribP3ui; PFNGLVERTEXATTRIBP3UIVPROC gl3wVertexAttribP3uiv; PFNGLVERTEXATTRIBP4UIPROC gl3wVertexAttribP4ui; PFNGLVERTEXATTRIBP4UIVPROC gl3wVertexAttribP4uiv; PFNGLVERTEXATTRIBPOINTERPROC gl3wVertexAttribPointer; PFNGLVERTEXBINDINGDIVISORPROC gl3wVertexBindingDivisor; PFNGLVIEWPORTPROC gl3wViewport; PFNGLVIEWPORTARRAYVPROC gl3wViewportArrayv; PFNGLVIEWPORTINDEXEDFPROC gl3wViewportIndexedf; PFNGLVIEWPORTINDEXEDFVPROC gl3wViewportIndexedfv; PFNGLWAITSYNCPROC gl3wWaitSync; /* --------------------------------------------------------------------------------------------- */ static void gl3w_load_all_functions(void) { gl3wActiveShaderProgram = ( PFNGLACTIVESHADERPROGRAMPROC ) gl3w_fn("glActiveShaderProgram"); gl3wActiveTexture = ( PFNGLACTIVETEXTUREPROC ) gl3w_fn("glActiveTexture"); gl3wAttachShader = ( PFNGLATTACHSHADERPROC ) gl3w_fn("glAttachShader"); gl3wBeginConditionalRender = ( PFNGLBEGINCONDITIONALRENDERPROC ) gl3w_fn("glBeginConditionalRender"); gl3wBeginQuery = ( PFNGLBEGINQUERYPROC ) gl3w_fn("glBeginQuery"); gl3wBeginQueryIndexed = ( PFNGLBEGINQUERYINDEXEDPROC ) gl3w_fn("glBeginQueryIndexed"); gl3wBeginTransformFeedback = ( PFNGLBEGINTRANSFORMFEEDBACKPROC ) gl3w_fn("glBeginTransformFeedback"); gl3wBindAttribLocation = ( PFNGLBINDATTRIBLOCATIONPROC ) gl3w_fn("glBindAttribLocation"); gl3wBindBuffer = ( PFNGLBINDBUFFERPROC ) gl3w_fn("glBindBuffer"); gl3wBindBufferBase = ( PFNGLBINDBUFFERBASEPROC ) gl3w_fn("glBindBufferBase"); gl3wBindBufferRange = ( PFNGLBINDBUFFERRANGEPROC ) gl3w_fn("glBindBufferRange"); gl3wBindBuffersBase = ( PFNGLBINDBUFFERSBASEPROC ) gl3w_fn("glBindBuffersBase"); gl3wBindBuffersRange = ( PFNGLBINDBUFFERSRANGEPROC ) gl3w_fn("glBindBuffersRange"); gl3wBindFragDataLocation = ( PFNGLBINDFRAGDATALOCATIONPROC ) gl3w_fn("glBindFragDataLocation"); gl3wBindFragDataLocationIndexed = ( PFNGLBINDFRAGDATALOCATIONINDEXEDPROC ) gl3w_fn("glBindFragDataLocationIndexed"); gl3wBindFramebuffer = ( PFNGLBINDFRAMEBUFFERPROC ) gl3w_fn("glBindFramebuffer"); gl3wBindImageTexture = ( PFNGLBINDIMAGETEXTUREPROC ) gl3w_fn("glBindImageTexture"); gl3wBindImageTextures = ( PFNGLBINDIMAGETEXTURESPROC ) gl3w_fn("glBindImageTextures"); gl3wBindProgramPipeline = ( PFNGLBINDPROGRAMPIPELINEPROC ) gl3w_fn("glBindProgramPipeline"); gl3wBindRenderbuffer = ( PFNGLBINDRENDERBUFFERPROC ) gl3w_fn("glBindRenderbuffer"); gl3wBindSampler = ( PFNGLBINDSAMPLERPROC ) gl3w_fn("glBindSampler"); gl3wBindSamplers = ( PFNGLBINDSAMPLERSPROC ) gl3w_fn("glBindSamplers"); gl3wBindTexture = ( PFNGLBINDTEXTUREPROC ) gl3w_fn("glBindTexture"); gl3wBindTextureUnit = ( PFNGLBINDTEXTUREUNITPROC ) gl3w_fn("glBindTextureUnit"); gl3wBindTextures = ( PFNGLBINDTEXTURESPROC ) gl3w_fn("glBindTextures"); gl3wBindTransformFeedback = ( PFNGLBINDTRANSFORMFEEDBACKPROC ) gl3w_fn("glBindTransformFeedback"); gl3wBindVertexArray = ( PFNGLBINDVERTEXARRAYPROC ) gl3w_fn("glBindVertexArray"); gl3wBindVertexBuffer = ( PFNGLBINDVERTEXBUFFERPROC ) gl3w_fn("glBindVertexBuffer"); gl3wBindVertexBuffers = ( PFNGLBINDVERTEXBUFFERSPROC ) gl3w_fn("glBindVertexBuffers"); gl3wBlendColor = ( PFNGLBLENDCOLORPROC ) gl3w_fn("glBlendColor"); gl3wBlendEquation = ( PFNGLBLENDEQUATIONPROC ) gl3w_fn("glBlendEquation"); gl3wBlendEquationSeparate = ( PFNGLBLENDEQUATIONSEPARATEPROC ) gl3w_fn("glBlendEquationSeparate"); gl3wBlendEquationSeparatei = ( PFNGLBLENDEQUATIONSEPARATEIPROC ) gl3w_fn("glBlendEquationSeparatei"); gl3wBlendEquationSeparateiARB = ( PFNGLBLENDEQUATIONSEPARATEIARBPROC ) gl3w_fn("glBlendEquationSeparateiARB"); gl3wBlendEquationi = ( PFNGLBLENDEQUATIONIPROC ) gl3w_fn("glBlendEquationi"); gl3wBlendEquationiARB = ( PFNGLBLENDEQUATIONIARBPROC ) gl3w_fn("glBlendEquationiARB"); gl3wBlendFunc = ( PFNGLBLENDFUNCPROC ) gl3w_fn("glBlendFunc"); gl3wBlendFuncSeparate = ( PFNGLBLENDFUNCSEPARATEPROC ) gl3w_fn("glBlendFuncSeparate"); gl3wBlendFuncSeparatei = ( PFNGLBLENDFUNCSEPARATEIPROC ) gl3w_fn("glBlendFuncSeparatei"); gl3wBlendFuncSeparateiARB = ( PFNGLBLENDFUNCSEPARATEIARBPROC ) gl3w_fn("glBlendFuncSeparateiARB"); gl3wBlendFunci = ( PFNGLBLENDFUNCIPROC ) gl3w_fn("glBlendFunci"); gl3wBlendFunciARB = ( PFNGLBLENDFUNCIARBPROC ) gl3w_fn("glBlendFunciARB"); gl3wBlitFramebuffer = ( PFNGLBLITFRAMEBUFFERPROC ) gl3w_fn("glBlitFramebuffer"); gl3wBlitNamedFramebuffer = ( PFNGLBLITNAMEDFRAMEBUFFERPROC ) gl3w_fn("glBlitNamedFramebuffer"); gl3wBufferData = ( PFNGLBUFFERDATAPROC ) gl3w_fn("glBufferData"); gl3wBufferPageCommitmentARB = ( PFNGLBUFFERPAGECOMMITMENTARBPROC ) gl3w_fn("glBufferPageCommitmentARB"); gl3wBufferStorage = ( PFNGLBUFFERSTORAGEPROC ) gl3w_fn("glBufferStorage"); gl3wBufferSubData = ( PFNGLBUFFERSUBDATAPROC ) gl3w_fn("glBufferSubData"); gl3wCheckFramebufferStatus = ( PFNGLCHECKFRAMEBUFFERSTATUSPROC ) gl3w_fn("glCheckFramebufferStatus"); gl3wCheckNamedFramebufferStatus = ( PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC ) gl3w_fn("glCheckNamedFramebufferStatus"); gl3wClampColor = ( PFNGLCLAMPCOLORPROC ) gl3w_fn("glClampColor"); gl3wClear = ( PFNGLCLEARPROC ) gl3w_fn("glClear"); gl3wClearBufferData = ( PFNGLCLEARBUFFERDATAPROC ) gl3w_fn("glClearBufferData"); gl3wClearBufferSubData = ( PFNGLCLEARBUFFERSUBDATAPROC ) gl3w_fn("glClearBufferSubData"); gl3wClearBufferfi = ( PFNGLCLEARBUFFERFIPROC ) gl3w_fn("glClearBufferfi"); gl3wClearBufferfv = ( PFNGLCLEARBUFFERFVPROC ) gl3w_fn("glClearBufferfv"); gl3wClearBufferiv = ( PFNGLCLEARBUFFERIVPROC ) gl3w_fn("glClearBufferiv"); gl3wClearBufferuiv = ( PFNGLCLEARBUFFERUIVPROC ) gl3w_fn("glClearBufferuiv"); gl3wClearColor = ( PFNGLCLEARCOLORPROC ) gl3w_fn("glClearColor"); gl3wClearDepth = ( PFNGLCLEARDEPTHPROC ) gl3w_fn("glClearDepth"); gl3wClearDepthf = ( PFNGLCLEARDEPTHFPROC ) gl3w_fn("glClearDepthf"); gl3wClearNamedBufferData = ( PFNGLCLEARNAMEDBUFFERDATAPROC ) gl3w_fn("glClearNamedBufferData"); gl3wClearNamedBufferSubData = ( PFNGLCLEARNAMEDBUFFERSUBDATAPROC ) gl3w_fn("glClearNamedBufferSubData"); gl3wClearNamedFramebufferfi = ( PFNGLCLEARNAMEDFRAMEBUFFERFIPROC ) gl3w_fn("glClearNamedFramebufferfi"); gl3wClearNamedFramebufferfv = ( PFNGLCLEARNAMEDFRAMEBUFFERFVPROC ) gl3w_fn("glClearNamedFramebufferfv"); gl3wClearNamedFramebufferiv = ( PFNGLCLEARNAMEDFRAMEBUFFERIVPROC ) gl3w_fn("glClearNamedFramebufferiv"); gl3wClearNamedFramebufferuiv = ( PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC ) gl3w_fn("glClearNamedFramebufferuiv"); gl3wClearStencil = ( PFNGLCLEARSTENCILPROC ) gl3w_fn("glClearStencil"); gl3wClearTexImage = ( PFNGLCLEARTEXIMAGEPROC ) gl3w_fn("glClearTexImage"); gl3wClearTexSubImage = ( PFNGLCLEARTEXSUBIMAGEPROC ) gl3w_fn("glClearTexSubImage"); gl3wClientWaitSync = ( PFNGLCLIENTWAITSYNCPROC ) gl3w_fn("glClientWaitSync"); gl3wClipControl = ( PFNGLCLIPCONTROLPROC ) gl3w_fn("glClipControl"); gl3wColorMask = ( PFNGLCOLORMASKPROC ) gl3w_fn("glColorMask"); gl3wColorMaski = ( PFNGLCOLORMASKIPROC ) gl3w_fn("glColorMaski"); gl3wCompileShader = ( PFNGLCOMPILESHADERPROC ) gl3w_fn("glCompileShader"); gl3wCompileShaderIncludeARB = ( PFNGLCOMPILESHADERINCLUDEARBPROC ) gl3w_fn("glCompileShaderIncludeARB"); gl3wCompressedTexImage1D = ( PFNGLCOMPRESSEDTEXIMAGE1DPROC ) gl3w_fn("glCompressedTexImage1D"); gl3wCompressedTexImage2D = ( PFNGLCOMPRESSEDTEXIMAGE2DPROC ) gl3w_fn("glCompressedTexImage2D"); gl3wCompressedTexImage3D = ( PFNGLCOMPRESSEDTEXIMAGE3DPROC ) gl3w_fn("glCompressedTexImage3D"); gl3wCompressedTexSubImage1D = ( PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC ) gl3w_fn("glCompressedTexSubImage1D"); gl3wCompressedTexSubImage2D = ( PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC ) gl3w_fn("glCompressedTexSubImage2D"); gl3wCompressedTexSubImage3D = ( PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC ) gl3w_fn("glCompressedTexSubImage3D"); gl3wCompressedTextureSubImage1D = ( PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC ) gl3w_fn("glCompressedTextureSubImage1D"); gl3wCompressedTextureSubImage2D = ( PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC ) gl3w_fn("glCompressedTextureSubImage2D"); gl3wCompressedTextureSubImage3D = ( PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC ) gl3w_fn("glCompressedTextureSubImage3D"); gl3wCopyBufferSubData = ( PFNGLCOPYBUFFERSUBDATAPROC ) gl3w_fn("glCopyBufferSubData"); gl3wCopyImageSubData = ( PFNGLCOPYIMAGESUBDATAPROC ) gl3w_fn("glCopyImageSubData"); gl3wCopyNamedBufferSubData = ( PFNGLCOPYNAMEDBUFFERSUBDATAPROC ) gl3w_fn("glCopyNamedBufferSubData"); gl3wCopyTexImage1D = ( PFNGLCOPYTEXIMAGE1DPROC ) gl3w_fn("glCopyTexImage1D"); gl3wCopyTexImage2D = ( PFNGLCOPYTEXIMAGE2DPROC ) gl3w_fn("glCopyTexImage2D"); gl3wCopyTexSubImage1D = ( PFNGLCOPYTEXSUBIMAGE1DPROC ) gl3w_fn("glCopyTexSubImage1D"); gl3wCopyTexSubImage2D = ( PFNGLCOPYTEXSUBIMAGE2DPROC ) gl3w_fn("glCopyTexSubImage2D"); gl3wCopyTexSubImage3D = ( PFNGLCOPYTEXSUBIMAGE3DPROC ) gl3w_fn("glCopyTexSubImage3D"); gl3wCopyTextureSubImage1D = ( PFNGLCOPYTEXTURESUBIMAGE1DPROC ) gl3w_fn("glCopyTextureSubImage1D"); gl3wCopyTextureSubImage2D = ( PFNGLCOPYTEXTURESUBIMAGE2DPROC ) gl3w_fn("glCopyTextureSubImage2D"); gl3wCopyTextureSubImage3D = ( PFNGLCOPYTEXTURESUBIMAGE3DPROC ) gl3w_fn("glCopyTextureSubImage3D"); gl3wCreateBuffers = ( PFNGLCREATEBUFFERSPROC ) gl3w_fn("glCreateBuffers"); gl3wCreateFramebuffers = ( PFNGLCREATEFRAMEBUFFERSPROC ) gl3w_fn("glCreateFramebuffers"); gl3wCreateProgram = ( PFNGLCREATEPROGRAMPROC ) gl3w_fn("glCreateProgram"); gl3wCreateProgramPipelines = ( PFNGLCREATEPROGRAMPIPELINESPROC ) gl3w_fn("glCreateProgramPipelines"); gl3wCreateQueries = ( PFNGLCREATEQUERIESPROC ) gl3w_fn("glCreateQueries"); gl3wCreateRenderbuffers = ( PFNGLCREATERENDERBUFFERSPROC ) gl3w_fn("glCreateRenderbuffers"); gl3wCreateSamplers = ( PFNGLCREATESAMPLERSPROC ) gl3w_fn("glCreateSamplers"); gl3wCreateShader = ( PFNGLCREATESHADERPROC ) gl3w_fn("glCreateShader"); gl3wCreateShaderProgramv = ( PFNGLCREATESHADERPROGRAMVPROC ) gl3w_fn("glCreateShaderProgramv"); gl3wCreateSyncFromCLeventARB = ( PFNGLCREATESYNCFROMCLEVENTARBPROC ) gl3w_fn("glCreateSyncFromCLeventARB"); gl3wCreateTextures = ( PFNGLCREATETEXTURESPROC ) gl3w_fn("glCreateTextures"); gl3wCreateTransformFeedbacks = ( PFNGLCREATETRANSFORMFEEDBACKSPROC ) gl3w_fn("glCreateTransformFeedbacks"); gl3wCreateVertexArrays = ( PFNGLCREATEVERTEXARRAYSPROC ) gl3w_fn("glCreateVertexArrays"); gl3wCullFace = ( PFNGLCULLFACEPROC ) gl3w_fn("glCullFace"); gl3wDebugMessageCallback = ( PFNGLDEBUGMESSAGECALLBACKPROC ) gl3w_fn("glDebugMessageCallback"); gl3wDebugMessageCallbackARB = ( PFNGLDEBUGMESSAGECALLBACKARBPROC ) gl3w_fn("glDebugMessageCallbackARB"); gl3wDebugMessageControl = ( PFNGLDEBUGMESSAGECONTROLPROC ) gl3w_fn("glDebugMessageControl"); gl3wDebugMessageControlARB = ( PFNGLDEBUGMESSAGECONTROLARBPROC ) gl3w_fn("glDebugMessageControlARB"); gl3wDebugMessageInsert = ( PFNGLDEBUGMESSAGEINSERTPROC ) gl3w_fn("glDebugMessageInsert"); gl3wDebugMessageInsertARB = ( PFNGLDEBUGMESSAGEINSERTARBPROC ) gl3w_fn("glDebugMessageInsertARB"); gl3wDeleteBuffers = ( PFNGLDELETEBUFFERSPROC ) gl3w_fn("glDeleteBuffers"); gl3wDeleteFramebuffers = ( PFNGLDELETEFRAMEBUFFERSPROC ) gl3w_fn("glDeleteFramebuffers"); gl3wDeleteNamedStringARB = ( PFNGLDELETENAMEDSTRINGARBPROC ) gl3w_fn("glDeleteNamedStringARB"); gl3wDeleteProgram = ( PFNGLDELETEPROGRAMPROC ) gl3w_fn("glDeleteProgram"); gl3wDeleteProgramPipelines = ( PFNGLDELETEPROGRAMPIPELINESPROC ) gl3w_fn("glDeleteProgramPipelines"); gl3wDeleteQueries = ( PFNGLDELETEQUERIESPROC ) gl3w_fn("glDeleteQueries"); gl3wDeleteRenderbuffers = ( PFNGLDELETERENDERBUFFERSPROC ) gl3w_fn("glDeleteRenderbuffers"); gl3wDeleteSamplers = ( PFNGLDELETESAMPLERSPROC ) gl3w_fn("glDeleteSamplers"); gl3wDeleteShader = ( PFNGLDELETESHADERPROC ) gl3w_fn("glDeleteShader"); gl3wDeleteSync = ( PFNGLDELETESYNCPROC ) gl3w_fn("glDeleteSync"); gl3wDeleteTextures = ( PFNGLDELETETEXTURESPROC ) gl3w_fn("glDeleteTextures"); gl3wDeleteTransformFeedbacks = ( PFNGLDELETETRANSFORMFEEDBACKSPROC ) gl3w_fn("glDeleteTransformFeedbacks"); gl3wDeleteVertexArrays = ( PFNGLDELETEVERTEXARRAYSPROC ) gl3w_fn("glDeleteVertexArrays"); gl3wDepthFunc = ( PFNGLDEPTHFUNCPROC ) gl3w_fn("glDepthFunc"); gl3wDepthMask = ( PFNGLDEPTHMASKPROC ) gl3w_fn("glDepthMask"); gl3wDepthRange = ( PFNGLDEPTHRANGEPROC ) gl3w_fn("glDepthRange"); gl3wDepthRangeArrayv = ( PFNGLDEPTHRANGEARRAYVPROC ) gl3w_fn("glDepthRangeArrayv"); gl3wDepthRangeIndexed = ( PFNGLDEPTHRANGEINDEXEDPROC ) gl3w_fn("glDepthRangeIndexed"); gl3wDepthRangef = ( PFNGLDEPTHRANGEFPROC ) gl3w_fn("glDepthRangef"); gl3wDetachShader = ( PFNGLDETACHSHADERPROC ) gl3w_fn("glDetachShader"); gl3wDisable = ( PFNGLDISABLEPROC ) gl3w_fn("glDisable"); gl3wDisableVertexArrayAttrib = ( PFNGLDISABLEVERTEXARRAYATTRIBPROC ) gl3w_fn("glDisableVertexArrayAttrib"); gl3wDisableVertexAttribArray = ( PFNGLDISABLEVERTEXATTRIBARRAYPROC ) gl3w_fn("glDisableVertexAttribArray"); gl3wDisablei = ( PFNGLDISABLEIPROC ) gl3w_fn("glDisablei"); gl3wDispatchCompute = ( PFNGLDISPATCHCOMPUTEPROC ) gl3w_fn("glDispatchCompute"); gl3wDispatchComputeGroupSizeARB = ( PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC ) gl3w_fn("glDispatchComputeGroupSizeARB"); gl3wDispatchComputeIndirect = ( PFNGLDISPATCHCOMPUTEINDIRECTPROC ) gl3w_fn("glDispatchComputeIndirect"); gl3wDrawArrays = ( PFNGLDRAWARRAYSPROC ) gl3w_fn("glDrawArrays"); gl3wDrawArraysIndirect = ( PFNGLDRAWARRAYSINDIRECTPROC ) gl3w_fn("glDrawArraysIndirect"); gl3wDrawArraysInstanced = ( PFNGLDRAWARRAYSINSTANCEDPROC ) gl3w_fn("glDrawArraysInstanced"); gl3wDrawArraysInstancedBaseInstance = ( PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC ) gl3w_fn("glDrawArraysInstancedBaseInstance"); gl3wDrawBuffer = ( PFNGLDRAWBUFFERPROC ) gl3w_fn("glDrawBuffer"); gl3wDrawBuffers = ( PFNGLDRAWBUFFERSPROC ) gl3w_fn("glDrawBuffers"); gl3wDrawElements = ( PFNGLDRAWELEMENTSPROC ) gl3w_fn("glDrawElements"); gl3wDrawElementsBaseVertex = ( PFNGLDRAWELEMENTSBASEVERTEXPROC ) gl3w_fn("glDrawElementsBaseVertex"); gl3wDrawElementsIndirect = ( PFNGLDRAWELEMENTSINDIRECTPROC ) gl3w_fn("glDrawElementsIndirect"); gl3wDrawElementsInstanced = ( PFNGLDRAWELEMENTSINSTANCEDPROC ) gl3w_fn("glDrawElementsInstanced"); gl3wDrawElementsInstancedBaseInstance = ( PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC ) gl3w_fn("glDrawElementsInstancedBaseInstance"); gl3wDrawElementsInstancedBaseVertex = ( PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC ) gl3w_fn("glDrawElementsInstancedBaseVertex"); gl3wDrawElementsInstancedBaseVertexBaseInstance = ( PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC ) gl3w_fn("glDrawElementsInstancedBaseVertexBaseInstance"); gl3wDrawRangeElements = ( PFNGLDRAWRANGEELEMENTSPROC ) gl3w_fn("glDrawRangeElements"); gl3wDrawRangeElementsBaseVertex = ( PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC ) gl3w_fn("glDrawRangeElementsBaseVertex"); gl3wDrawTransformFeedback = ( PFNGLDRAWTRANSFORMFEEDBACKPROC ) gl3w_fn("glDrawTransformFeedback"); gl3wDrawTransformFeedbackInstanced = ( PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC ) gl3w_fn("glDrawTransformFeedbackInstanced"); gl3wDrawTransformFeedbackStream = ( PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC ) gl3w_fn("glDrawTransformFeedbackStream"); gl3wDrawTransformFeedbackStreamInstanced = ( PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC ) gl3w_fn("glDrawTransformFeedbackStreamInstanced"); gl3wEnable = ( PFNGLENABLEPROC ) gl3w_fn("glEnable"); gl3wEnableVertexArrayAttrib = ( PFNGLENABLEVERTEXARRAYATTRIBPROC ) gl3w_fn("glEnableVertexArrayAttrib"); gl3wEnableVertexAttribArray = ( PFNGLENABLEVERTEXATTRIBARRAYPROC ) gl3w_fn("glEnableVertexAttribArray"); gl3wEnablei = ( PFNGLENABLEIPROC ) gl3w_fn("glEnablei"); gl3wEndConditionalRender = ( PFNGLENDCONDITIONALRENDERPROC ) gl3w_fn("glEndConditionalRender"); gl3wEndQuery = ( PFNGLENDQUERYPROC ) gl3w_fn("glEndQuery"); gl3wEndQueryIndexed = ( PFNGLENDQUERYINDEXEDPROC ) gl3w_fn("glEndQueryIndexed"); gl3wEndTransformFeedback = ( PFNGLENDTRANSFORMFEEDBACKPROC ) gl3w_fn("glEndTransformFeedback"); gl3wFenceSync = ( PFNGLFENCESYNCPROC ) gl3w_fn("glFenceSync"); gl3wFinish = ( PFNGLFINISHPROC ) gl3w_fn("glFinish"); gl3wFlush = ( PFNGLFLUSHPROC ) gl3w_fn("glFlush"); gl3wFlushMappedBufferRange = ( PFNGLFLUSHMAPPEDBUFFERRANGEPROC ) gl3w_fn("glFlushMappedBufferRange"); gl3wFlushMappedNamedBufferRange = ( PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC ) gl3w_fn("glFlushMappedNamedBufferRange"); gl3wFramebufferParameteri = ( PFNGLFRAMEBUFFERPARAMETERIPROC ) gl3w_fn("glFramebufferParameteri"); gl3wFramebufferRenderbuffer = ( PFNGLFRAMEBUFFERRENDERBUFFERPROC ) gl3w_fn("glFramebufferRenderbuffer"); gl3wFramebufferTexture = ( PFNGLFRAMEBUFFERTEXTUREPROC ) gl3w_fn("glFramebufferTexture"); gl3wFramebufferTexture1D = ( PFNGLFRAMEBUFFERTEXTURE1DPROC ) gl3w_fn("glFramebufferTexture1D"); gl3wFramebufferTexture2D = ( PFNGLFRAMEBUFFERTEXTURE2DPROC ) gl3w_fn("glFramebufferTexture2D"); gl3wFramebufferTexture3D = ( PFNGLFRAMEBUFFERTEXTURE3DPROC ) gl3w_fn("glFramebufferTexture3D"); gl3wFramebufferTextureLayer = ( PFNGLFRAMEBUFFERTEXTURELAYERPROC ) gl3w_fn("glFramebufferTextureLayer"); gl3wFrontFace = ( PFNGLFRONTFACEPROC ) gl3w_fn("glFrontFace"); gl3wGenBuffers = ( PFNGLGENBUFFERSPROC ) gl3w_fn("glGenBuffers"); gl3wGenFramebuffers = ( PFNGLGENFRAMEBUFFERSPROC ) gl3w_fn("glGenFramebuffers"); gl3wGenProgramPipelines = ( PFNGLGENPROGRAMPIPELINESPROC ) gl3w_fn("glGenProgramPipelines"); gl3wGenQueries = ( PFNGLGENQUERIESPROC ) gl3w_fn("glGenQueries"); gl3wGenRenderbuffers = ( PFNGLGENRENDERBUFFERSPROC ) gl3w_fn("glGenRenderbuffers"); gl3wGenSamplers = ( PFNGLGENSAMPLERSPROC ) gl3w_fn("glGenSamplers"); gl3wGenTextures = ( PFNGLGENTEXTURESPROC ) gl3w_fn("glGenTextures"); gl3wGenTransformFeedbacks = ( PFNGLGENTRANSFORMFEEDBACKSPROC ) gl3w_fn("glGenTransformFeedbacks"); gl3wGenVertexArrays = ( PFNGLGENVERTEXARRAYSPROC ) gl3w_fn("glGenVertexArrays"); gl3wGenerateMipmap = ( PFNGLGENERATEMIPMAPPROC ) gl3w_fn("glGenerateMipmap"); gl3wGenerateTextureMipmap = ( PFNGLGENERATETEXTUREMIPMAPPROC ) gl3w_fn("glGenerateTextureMipmap"); gl3wGetActiveAtomicCounterBufferiv = ( PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC ) gl3w_fn("glGetActiveAtomicCounterBufferiv"); gl3wGetActiveAttrib = ( PFNGLGETACTIVEATTRIBPROC ) gl3w_fn("glGetActiveAttrib"); gl3wGetActiveSubroutineName = ( PFNGLGETACTIVESUBROUTINENAMEPROC ) gl3w_fn("glGetActiveSubroutineName"); gl3wGetActiveSubroutineUniformName = ( PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC ) gl3w_fn("glGetActiveSubroutineUniformName"); gl3wGetActiveSubroutineUniformiv = ( PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC ) gl3w_fn("glGetActiveSubroutineUniformiv"); gl3wGetActiveUniform = ( PFNGLGETACTIVEUNIFORMPROC ) gl3w_fn("glGetActiveUniform"); gl3wGetActiveUniformBlockName = ( PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC ) gl3w_fn("glGetActiveUniformBlockName"); gl3wGetActiveUniformBlockiv = ( PFNGLGETACTIVEUNIFORMBLOCKIVPROC ) gl3w_fn("glGetActiveUniformBlockiv"); gl3wGetActiveUniformName = ( PFNGLGETACTIVEUNIFORMNAMEPROC ) gl3w_fn("glGetActiveUniformName"); gl3wGetActiveUniformsiv = ( PFNGLGETACTIVEUNIFORMSIVPROC ) gl3w_fn("glGetActiveUniformsiv"); gl3wGetAttachedShaders = ( PFNGLGETATTACHEDSHADERSPROC ) gl3w_fn("glGetAttachedShaders"); gl3wGetAttribLocation = ( PFNGLGETATTRIBLOCATIONPROC ) gl3w_fn("glGetAttribLocation"); gl3wGetBooleani_v = ( PFNGLGETBOOLEANI_VPROC ) gl3w_fn("glGetBooleani_v"); gl3wGetBooleanv = ( PFNGLGETBOOLEANVPROC ) gl3w_fn("glGetBooleanv"); gl3wGetBufferParameteri64v = ( PFNGLGETBUFFERPARAMETERI64VPROC ) gl3w_fn("glGetBufferParameteri64v"); gl3wGetBufferParameteriv = ( PFNGLGETBUFFERPARAMETERIVPROC ) gl3w_fn("glGetBufferParameteriv"); gl3wGetBufferPointerv = ( PFNGLGETBUFFERPOINTERVPROC ) gl3w_fn("glGetBufferPointerv"); gl3wGetBufferSubData = ( PFNGLGETBUFFERSUBDATAPROC ) gl3w_fn("glGetBufferSubData"); gl3wGetCompressedTexImage = ( PFNGLGETCOMPRESSEDTEXIMAGEPROC ) gl3w_fn("glGetCompressedTexImage"); gl3wGetCompressedTextureImage = ( PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC ) gl3w_fn("glGetCompressedTextureImage"); gl3wGetCompressedTextureSubImage = ( PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC ) gl3w_fn("glGetCompressedTextureSubImage"); gl3wGetDebugMessageLog = ( PFNGLGETDEBUGMESSAGELOGPROC ) gl3w_fn("glGetDebugMessageLog"); gl3wGetDebugMessageLogARB = ( PFNGLGETDEBUGMESSAGELOGARBPROC ) gl3w_fn("glGetDebugMessageLogARB"); gl3wGetDoublei_v = ( PFNGLGETDOUBLEI_VPROC ) gl3w_fn("glGetDoublei_v"); gl3wGetDoublev = ( PFNGLGETDOUBLEVPROC ) gl3w_fn("glGetDoublev"); gl3wGetError = ( PFNGLGETERRORPROC ) gl3w_fn("glGetError"); gl3wGetFloati_v = ( PFNGLGETFLOATI_VPROC ) gl3w_fn("glGetFloati_v"); gl3wGetFloatv = ( PFNGLGETFLOATVPROC ) gl3w_fn("glGetFloatv"); gl3wGetFragDataIndex = ( PFNGLGETFRAGDATAINDEXPROC ) gl3w_fn("glGetFragDataIndex"); gl3wGetFragDataLocation = ( PFNGLGETFRAGDATALOCATIONPROC ) gl3w_fn("glGetFragDataLocation"); gl3wGetFramebufferAttachmentParameteriv = ( PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC ) gl3w_fn("glGetFramebufferAttachmentParameteriv"); gl3wGetFramebufferParameteriv = ( PFNGLGETFRAMEBUFFERPARAMETERIVPROC ) gl3w_fn("glGetFramebufferParameteriv"); gl3wGetGraphicsResetStatus = ( PFNGLGETGRAPHICSRESETSTATUSPROC ) gl3w_fn("glGetGraphicsResetStatus"); gl3wGetGraphicsResetStatusARB = ( PFNGLGETGRAPHICSRESETSTATUSARBPROC ) gl3w_fn("glGetGraphicsResetStatusARB"); gl3wGetImageHandleARB = ( PFNGLGETIMAGEHANDLEARBPROC ) gl3w_fn("glGetImageHandleARB"); gl3wGetInteger64i_v = ( PFNGLGETINTEGER64I_VPROC ) gl3w_fn("glGetInteger64i_v"); gl3wGetInteger64v = ( PFNGLGETINTEGER64VPROC ) gl3w_fn("glGetInteger64v"); gl3wGetIntegeri_v = ( PFNGLGETINTEGERI_VPROC ) gl3w_fn("glGetIntegeri_v"); gl3wGetIntegerv = ( PFNGLGETINTEGERVPROC ) gl3w_fn("glGetIntegerv"); gl3wGetInternalformati64v = ( PFNGLGETINTERNALFORMATI64VPROC ) gl3w_fn("glGetInternalformati64v"); gl3wGetInternalformativ = ( PFNGLGETINTERNALFORMATIVPROC ) gl3w_fn("glGetInternalformativ"); gl3wGetMultisamplefv = ( PFNGLGETMULTISAMPLEFVPROC ) gl3w_fn("glGetMultisamplefv"); gl3wGetNamedBufferParameteri64v = ( PFNGLGETNAMEDBUFFERPARAMETERI64VPROC ) gl3w_fn("glGetNamedBufferParameteri64v"); gl3wGetNamedBufferParameteriv = ( PFNGLGETNAMEDBUFFERPARAMETERIVPROC ) gl3w_fn("glGetNamedBufferParameteriv"); gl3wGetNamedBufferPointerv = ( PFNGLGETNAMEDBUFFERPOINTERVPROC ) gl3w_fn("glGetNamedBufferPointerv"); gl3wGetNamedBufferSubData = ( PFNGLGETNAMEDBUFFERSUBDATAPROC ) gl3w_fn("glGetNamedBufferSubData"); gl3wGetNamedFramebufferAttachmentParameteriv = ( PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC ) gl3w_fn("glGetNamedFramebufferAttachmentParameteriv"); gl3wGetNamedFramebufferParameteriv = ( PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC ) gl3w_fn("glGetNamedFramebufferParameteriv"); gl3wGetNamedRenderbufferParameteriv = ( PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC ) gl3w_fn("glGetNamedRenderbufferParameteriv"); gl3wGetNamedStringARB = ( PFNGLGETNAMEDSTRINGARBPROC ) gl3w_fn("glGetNamedStringARB"); gl3wGetNamedStringivARB = ( PFNGLGETNAMEDSTRINGIVARBPROC ) gl3w_fn("glGetNamedStringivARB"); gl3wGetObjectLabel = ( PFNGLGETOBJECTLABELPROC ) gl3w_fn("glGetObjectLabel"); gl3wGetObjectPtrLabel = ( PFNGLGETOBJECTPTRLABELPROC ) gl3w_fn("glGetObjectPtrLabel"); gl3wGetPointerv = ( PFNGLGETPOINTERVPROC ) gl3w_fn("glGetPointerv"); gl3wGetProgramBinary = ( PFNGLGETPROGRAMBINARYPROC ) gl3w_fn("glGetProgramBinary"); gl3wGetProgramInfoLog = ( PFNGLGETPROGRAMINFOLOGPROC ) gl3w_fn("glGetProgramInfoLog"); gl3wGetProgramInterfaceiv = ( PFNGLGETPROGRAMINTERFACEIVPROC ) gl3w_fn("glGetProgramInterfaceiv"); gl3wGetProgramPipelineInfoLog = ( PFNGLGETPROGRAMPIPELINEINFOLOGPROC ) gl3w_fn("glGetProgramPipelineInfoLog"); gl3wGetProgramPipelineiv = ( PFNGLGETPROGRAMPIPELINEIVPROC ) gl3w_fn("glGetProgramPipelineiv"); gl3wGetProgramResourceIndex = ( PFNGLGETPROGRAMRESOURCEINDEXPROC ) gl3w_fn("glGetProgramResourceIndex"); gl3wGetProgramResourceLocation = ( PFNGLGETPROGRAMRESOURCELOCATIONPROC ) gl3w_fn("glGetProgramResourceLocation"); gl3wGetProgramResourceLocationIndex = ( PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC ) gl3w_fn("glGetProgramResourceLocationIndex"); gl3wGetProgramResourceName = ( PFNGLGETPROGRAMRESOURCENAMEPROC ) gl3w_fn("glGetProgramResourceName"); gl3wGetProgramResourceiv = ( PFNGLGETPROGRAMRESOURCEIVPROC ) gl3w_fn("glGetProgramResourceiv"); gl3wGetProgramStageiv = ( PFNGLGETPROGRAMSTAGEIVPROC ) gl3w_fn("glGetProgramStageiv"); gl3wGetProgramiv = ( PFNGLGETPROGRAMIVPROC ) gl3w_fn("glGetProgramiv"); gl3wGetQueryBufferObjecti64v = ( PFNGLGETQUERYBUFFEROBJECTI64VPROC ) gl3w_fn("glGetQueryBufferObjecti64v"); gl3wGetQueryBufferObjectiv = ( PFNGLGETQUERYBUFFEROBJECTIVPROC ) gl3w_fn("glGetQueryBufferObjectiv"); gl3wGetQueryBufferObjectui64v = ( PFNGLGETQUERYBUFFEROBJECTUI64VPROC ) gl3w_fn("glGetQueryBufferObjectui64v"); gl3wGetQueryBufferObjectuiv = ( PFNGLGETQUERYBUFFEROBJECTUIVPROC ) gl3w_fn("glGetQueryBufferObjectuiv"); gl3wGetQueryIndexediv = ( PFNGLGETQUERYINDEXEDIVPROC ) gl3w_fn("glGetQueryIndexediv"); gl3wGetQueryObjecti64v = ( PFNGLGETQUERYOBJECTI64VPROC ) gl3w_fn("glGetQueryObjecti64v"); gl3wGetQueryObjectiv = ( PFNGLGETQUERYOBJECTIVPROC ) gl3w_fn("glGetQueryObjectiv"); gl3wGetQueryObjectui64v = ( PFNGLGETQUERYOBJECTUI64VPROC ) gl3w_fn("glGetQueryObjectui64v"); gl3wGetQueryObjectuiv = ( PFNGLGETQUERYOBJECTUIVPROC ) gl3w_fn("glGetQueryObjectuiv"); gl3wGetQueryiv = ( PFNGLGETQUERYIVPROC ) gl3w_fn("glGetQueryiv"); gl3wGetRenderbufferParameteriv = ( PFNGLGETRENDERBUFFERPARAMETERIVPROC ) gl3w_fn("glGetRenderbufferParameteriv"); gl3wGetSamplerParameterIiv = ( PFNGLGETSAMPLERPARAMETERIIVPROC ) gl3w_fn("glGetSamplerParameterIiv"); gl3wGetSamplerParameterIuiv = ( PFNGLGETSAMPLERPARAMETERIUIVPROC ) gl3w_fn("glGetSamplerParameterIuiv"); gl3wGetSamplerParameterfv = ( PFNGLGETSAMPLERPARAMETERFVPROC ) gl3w_fn("glGetSamplerParameterfv"); gl3wGetSamplerParameteriv = ( PFNGLGETSAMPLERPARAMETERIVPROC ) gl3w_fn("glGetSamplerParameteriv"); gl3wGetShaderInfoLog = ( PFNGLGETSHADERINFOLOGPROC ) gl3w_fn("glGetShaderInfoLog"); gl3wGetShaderPrecisionFormat = ( PFNGLGETSHADERPRECISIONFORMATPROC ) gl3w_fn("glGetShaderPrecisionFormat"); gl3wGetShaderSource = ( PFNGLGETSHADERSOURCEPROC ) gl3w_fn("glGetShaderSource"); gl3wGetShaderiv = ( PFNGLGETSHADERIVPROC ) gl3w_fn("glGetShaderiv"); gl3wGetString = ( PFNGLGETSTRINGPROC ) gl3w_fn("glGetString"); gl3wGetStringi = ( PFNGLGETSTRINGIPROC ) gl3w_fn("glGetStringi"); gl3wGetSubroutineIndex = ( PFNGLGETSUBROUTINEINDEXPROC ) gl3w_fn("glGetSubroutineIndex"); gl3wGetSubroutineUniformLocation = ( PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC ) gl3w_fn("glGetSubroutineUniformLocation"); gl3wGetSynciv = ( PFNGLGETSYNCIVPROC ) gl3w_fn("glGetSynciv"); gl3wGetTexImage = ( PFNGLGETTEXIMAGEPROC ) gl3w_fn("glGetTexImage"); gl3wGetTexLevelParameterfv = ( PFNGLGETTEXLEVELPARAMETERFVPROC ) gl3w_fn("glGetTexLevelParameterfv"); gl3wGetTexLevelParameteriv = ( PFNGLGETTEXLEVELPARAMETERIVPROC ) gl3w_fn("glGetTexLevelParameteriv"); gl3wGetTexParameterIiv = ( PFNGLGETTEXPARAMETERIIVPROC ) gl3w_fn("glGetTexParameterIiv"); gl3wGetTexParameterIuiv = ( PFNGLGETTEXPARAMETERIUIVPROC ) gl3w_fn("glGetTexParameterIuiv"); gl3wGetTexParameterfv = ( PFNGLGETTEXPARAMETERFVPROC ) gl3w_fn("glGetTexParameterfv"); gl3wGetTexParameteriv = ( PFNGLGETTEXPARAMETERIVPROC ) gl3w_fn("glGetTexParameteriv"); gl3wGetTextureHandleARB = ( PFNGLGETTEXTUREHANDLEARBPROC ) gl3w_fn("glGetTextureHandleARB"); gl3wGetTextureImage = ( PFNGLGETTEXTUREIMAGEPROC ) gl3w_fn("glGetTextureImage"); gl3wGetTextureLevelParameterfv = ( PFNGLGETTEXTURELEVELPARAMETERFVPROC ) gl3w_fn("glGetTextureLevelParameterfv"); gl3wGetTextureLevelParameteriv = ( PFNGLGETTEXTURELEVELPARAMETERIVPROC ) gl3w_fn("glGetTextureLevelParameteriv"); gl3wGetTextureParameterIiv = ( PFNGLGETTEXTUREPARAMETERIIVPROC ) gl3w_fn("glGetTextureParameterIiv"); gl3wGetTextureParameterIuiv = ( PFNGLGETTEXTUREPARAMETERIUIVPROC ) gl3w_fn("glGetTextureParameterIuiv"); gl3wGetTextureParameterfv = ( PFNGLGETTEXTUREPARAMETERFVPROC ) gl3w_fn("glGetTextureParameterfv"); gl3wGetTextureParameteriv = ( PFNGLGETTEXTUREPARAMETERIVPROC ) gl3w_fn("glGetTextureParameteriv"); gl3wGetTextureSamplerHandleARB = ( PFNGLGETTEXTURESAMPLERHANDLEARBPROC ) gl3w_fn("glGetTextureSamplerHandleARB"); gl3wGetTextureSubImage = ( PFNGLGETTEXTURESUBIMAGEPROC ) gl3w_fn("glGetTextureSubImage"); gl3wGetTransformFeedbackVarying = ( PFNGLGETTRANSFORMFEEDBACKVARYINGPROC ) gl3w_fn("glGetTransformFeedbackVarying"); gl3wGetTransformFeedbacki64_v = ( PFNGLGETTRANSFORMFEEDBACKI64_VPROC ) gl3w_fn("glGetTransformFeedbacki64_v"); gl3wGetTransformFeedbacki_v = ( PFNGLGETTRANSFORMFEEDBACKI_VPROC ) gl3w_fn("glGetTransformFeedbacki_v"); gl3wGetTransformFeedbackiv = ( PFNGLGETTRANSFORMFEEDBACKIVPROC ) gl3w_fn("glGetTransformFeedbackiv"); gl3wGetUniformBlockIndex = ( PFNGLGETUNIFORMBLOCKINDEXPROC ) gl3w_fn("glGetUniformBlockIndex"); gl3wGetUniformIndices = ( PFNGLGETUNIFORMINDICESPROC ) gl3w_fn("glGetUniformIndices"); gl3wGetUniformLocation = ( PFNGLGETUNIFORMLOCATIONPROC ) gl3w_fn("glGetUniformLocation"); gl3wGetUniformSubroutineuiv = ( PFNGLGETUNIFORMSUBROUTINEUIVPROC ) gl3w_fn("glGetUniformSubroutineuiv"); gl3wGetUniformdv = ( PFNGLGETUNIFORMDVPROC ) gl3w_fn("glGetUniformdv"); gl3wGetUniformfv = ( PFNGLGETUNIFORMFVPROC ) gl3w_fn("glGetUniformfv"); gl3wGetUniformiv = ( PFNGLGETUNIFORMIVPROC ) gl3w_fn("glGetUniformiv"); gl3wGetUniformuiv = ( PFNGLGETUNIFORMUIVPROC ) gl3w_fn("glGetUniformuiv"); gl3wGetVertexArrayIndexed64iv = ( PFNGLGETVERTEXARRAYINDEXED64IVPROC ) gl3w_fn("glGetVertexArrayIndexed64iv"); gl3wGetVertexArrayIndexediv = ( PFNGLGETVERTEXARRAYINDEXEDIVPROC ) gl3w_fn("glGetVertexArrayIndexediv"); gl3wGetVertexArrayiv = ( PFNGLGETVERTEXARRAYIVPROC ) gl3w_fn("glGetVertexArrayiv"); gl3wGetVertexAttribIiv = ( PFNGLGETVERTEXATTRIBIIVPROC ) gl3w_fn("glGetVertexAttribIiv"); gl3wGetVertexAttribIuiv = ( PFNGLGETVERTEXATTRIBIUIVPROC ) gl3w_fn("glGetVertexAttribIuiv"); gl3wGetVertexAttribLdv = ( PFNGLGETVERTEXATTRIBLDVPROC ) gl3w_fn("glGetVertexAttribLdv"); gl3wGetVertexAttribLui64vARB = ( PFNGLGETVERTEXATTRIBLUI64VARBPROC ) gl3w_fn("glGetVertexAttribLui64vARB"); gl3wGetVertexAttribPointerv = ( PFNGLGETVERTEXATTRIBPOINTERVPROC ) gl3w_fn("glGetVertexAttribPointerv"); gl3wGetVertexAttribdv = ( PFNGLGETVERTEXATTRIBDVPROC ) gl3w_fn("glGetVertexAttribdv"); gl3wGetVertexAttribfv = ( PFNGLGETVERTEXATTRIBFVPROC ) gl3w_fn("glGetVertexAttribfv"); gl3wGetVertexAttribiv = ( PFNGLGETVERTEXATTRIBIVPROC ) gl3w_fn("glGetVertexAttribiv"); gl3wGetnCompressedTexImage = ( PFNGLGETNCOMPRESSEDTEXIMAGEPROC ) gl3w_fn("glGetnCompressedTexImage"); gl3wGetnCompressedTexImageARB = ( PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC ) gl3w_fn("glGetnCompressedTexImageARB"); gl3wGetnTexImage = ( PFNGLGETNTEXIMAGEPROC ) gl3w_fn("glGetnTexImage"); gl3wGetnTexImageARB = ( PFNGLGETNTEXIMAGEARBPROC ) gl3w_fn("glGetnTexImageARB"); gl3wGetnUniformdv = ( PFNGLGETNUNIFORMDVPROC ) gl3w_fn("glGetnUniformdv"); gl3wGetnUniformdvARB = ( PFNGLGETNUNIFORMDVARBPROC ) gl3w_fn("glGetnUniformdvARB"); gl3wGetnUniformfv = ( PFNGLGETNUNIFORMFVPROC ) gl3w_fn("glGetnUniformfv"); gl3wGetnUniformfvARB = ( PFNGLGETNUNIFORMFVARBPROC ) gl3w_fn("glGetnUniformfvARB"); gl3wGetnUniformiv = ( PFNGLGETNUNIFORMIVPROC ) gl3w_fn("glGetnUniformiv"); gl3wGetnUniformivARB = ( PFNGLGETNUNIFORMIVARBPROC ) gl3w_fn("glGetnUniformivARB"); gl3wGetnUniformuiv = ( PFNGLGETNUNIFORMUIVPROC ) gl3w_fn("glGetnUniformuiv"); gl3wGetnUniformuivARB = ( PFNGLGETNUNIFORMUIVARBPROC ) gl3w_fn("glGetnUniformuivARB"); gl3wHint = ( PFNGLHINTPROC ) gl3w_fn("glHint"); gl3wInvalidateBufferData = ( PFNGLINVALIDATEBUFFERDATAPROC ) gl3w_fn("glInvalidateBufferData"); gl3wInvalidateBufferSubData = ( PFNGLINVALIDATEBUFFERSUBDATAPROC ) gl3w_fn("glInvalidateBufferSubData"); gl3wInvalidateFramebuffer = ( PFNGLINVALIDATEFRAMEBUFFERPROC ) gl3w_fn("glInvalidateFramebuffer"); gl3wInvalidateNamedFramebufferData = ( PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC ) gl3w_fn("glInvalidateNamedFramebufferData"); gl3wInvalidateNamedFramebufferSubData = ( PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC ) gl3w_fn("glInvalidateNamedFramebufferSubData"); gl3wInvalidateSubFramebuffer = ( PFNGLINVALIDATESUBFRAMEBUFFERPROC ) gl3w_fn("glInvalidateSubFramebuffer"); gl3wInvalidateTexImage = ( PFNGLINVALIDATETEXIMAGEPROC ) gl3w_fn("glInvalidateTexImage"); gl3wInvalidateTexSubImage = ( PFNGLINVALIDATETEXSUBIMAGEPROC ) gl3w_fn("glInvalidateTexSubImage"); gl3wIsBuffer = ( PFNGLISBUFFERPROC ) gl3w_fn("glIsBuffer"); gl3wIsEnabled = ( PFNGLISENABLEDPROC ) gl3w_fn("glIsEnabled"); gl3wIsEnabledi = ( PFNGLISENABLEDIPROC ) gl3w_fn("glIsEnabledi"); gl3wIsFramebuffer = ( PFNGLISFRAMEBUFFERPROC ) gl3w_fn("glIsFramebuffer"); gl3wIsImageHandleResidentARB = ( PFNGLISIMAGEHANDLERESIDENTARBPROC ) gl3w_fn("glIsImageHandleResidentARB"); gl3wIsNamedStringARB = ( PFNGLISNAMEDSTRINGARBPROC ) gl3w_fn("glIsNamedStringARB"); gl3wIsProgram = ( PFNGLISPROGRAMPROC ) gl3w_fn("glIsProgram"); gl3wIsProgramPipeline = ( PFNGLISPROGRAMPIPELINEPROC ) gl3w_fn("glIsProgramPipeline"); gl3wIsQuery = ( PFNGLISQUERYPROC ) gl3w_fn("glIsQuery"); gl3wIsRenderbuffer = ( PFNGLISRENDERBUFFERPROC ) gl3w_fn("glIsRenderbuffer"); gl3wIsSampler = ( PFNGLISSAMPLERPROC ) gl3w_fn("glIsSampler"); gl3wIsShader = ( PFNGLISSHADERPROC ) gl3w_fn("glIsShader"); gl3wIsSync = ( PFNGLISSYNCPROC ) gl3w_fn("glIsSync"); gl3wIsTexture = ( PFNGLISTEXTUREPROC ) gl3w_fn("glIsTexture"); gl3wIsTextureHandleResidentARB = ( PFNGLISTEXTUREHANDLERESIDENTARBPROC ) gl3w_fn("glIsTextureHandleResidentARB"); gl3wIsTransformFeedback = ( PFNGLISTRANSFORMFEEDBACKPROC ) gl3w_fn("glIsTransformFeedback"); gl3wIsVertexArray = ( PFNGLISVERTEXARRAYPROC ) gl3w_fn("glIsVertexArray"); gl3wLineWidth = ( PFNGLLINEWIDTHPROC ) gl3w_fn("glLineWidth"); gl3wLinkProgram = ( PFNGLLINKPROGRAMPROC ) gl3w_fn("glLinkProgram"); gl3wLogicOp = ( PFNGLLOGICOPPROC ) gl3w_fn("glLogicOp"); gl3wMakeImageHandleNonResidentARB = ( PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC ) gl3w_fn("glMakeImageHandleNonResidentARB"); gl3wMakeImageHandleResidentARB = ( PFNGLMAKEIMAGEHANDLERESIDENTARBPROC ) gl3w_fn("glMakeImageHandleResidentARB"); gl3wMakeTextureHandleNonResidentARB = ( PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC ) gl3w_fn("glMakeTextureHandleNonResidentARB"); gl3wMakeTextureHandleResidentARB = ( PFNGLMAKETEXTUREHANDLERESIDENTARBPROC ) gl3w_fn("glMakeTextureHandleResidentARB"); gl3wMapBuffer = ( PFNGLMAPBUFFERPROC ) gl3w_fn("glMapBuffer"); gl3wMapBufferRange = ( PFNGLMAPBUFFERRANGEPROC ) gl3w_fn("glMapBufferRange"); gl3wMapNamedBuffer = ( PFNGLMAPNAMEDBUFFERPROC ) gl3w_fn("glMapNamedBuffer"); gl3wMapNamedBufferRange = ( PFNGLMAPNAMEDBUFFERRANGEPROC ) gl3w_fn("glMapNamedBufferRange"); gl3wMemoryBarrier = ( PFNGLMEMORYBARRIERPROC ) gl3w_fn("glMemoryBarrier"); gl3wMemoryBarrierByRegion = ( PFNGLMEMORYBARRIERBYREGIONPROC ) gl3w_fn("glMemoryBarrierByRegion"); gl3wMinSampleShading = ( PFNGLMINSAMPLESHADINGPROC ) gl3w_fn("glMinSampleShading"); gl3wMinSampleShadingARB = ( PFNGLMINSAMPLESHADINGARBPROC ) gl3w_fn("glMinSampleShadingARB"); gl3wMultiDrawArrays = ( PFNGLMULTIDRAWARRAYSPROC ) gl3w_fn("glMultiDrawArrays"); gl3wMultiDrawArraysIndirect = ( PFNGLMULTIDRAWARRAYSINDIRECTPROC ) gl3w_fn("glMultiDrawArraysIndirect"); gl3wMultiDrawArraysIndirectCountARB = ( PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC ) gl3w_fn("glMultiDrawArraysIndirectCountARB"); gl3wMultiDrawElements = ( PFNGLMULTIDRAWELEMENTSPROC ) gl3w_fn("glMultiDrawElements"); gl3wMultiDrawElementsBaseVertex = ( PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC ) gl3w_fn("glMultiDrawElementsBaseVertex"); gl3wMultiDrawElementsIndirect = ( PFNGLMULTIDRAWELEMENTSINDIRECTPROC ) gl3w_fn("glMultiDrawElementsIndirect"); gl3wMultiDrawElementsIndirectCountARB = ( PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC ) gl3w_fn("glMultiDrawElementsIndirectCountARB"); gl3wNamedBufferData = ( PFNGLNAMEDBUFFERDATAPROC ) gl3w_fn("glNamedBufferData"); gl3wNamedBufferPageCommitmentARB = ( PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC ) gl3w_fn("glNamedBufferPageCommitmentARB"); gl3wNamedBufferPageCommitmentEXT = ( PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC ) gl3w_fn("glNamedBufferPageCommitmentEXT"); gl3wNamedBufferStorage = ( PFNGLNAMEDBUFFERSTORAGEPROC ) gl3w_fn("glNamedBufferStorage"); gl3wNamedBufferSubData = ( PFNGLNAMEDBUFFERSUBDATAPROC ) gl3w_fn("glNamedBufferSubData"); gl3wNamedFramebufferDrawBuffer = ( PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC ) gl3w_fn("glNamedFramebufferDrawBuffer"); gl3wNamedFramebufferDrawBuffers = ( PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC ) gl3w_fn("glNamedFramebufferDrawBuffers"); gl3wNamedFramebufferParameteri = ( PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC ) gl3w_fn("glNamedFramebufferParameteri"); gl3wNamedFramebufferReadBuffer = ( PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC ) gl3w_fn("glNamedFramebufferReadBuffer"); gl3wNamedFramebufferRenderbuffer = ( PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC ) gl3w_fn("glNamedFramebufferRenderbuffer"); gl3wNamedFramebufferTexture = ( PFNGLNAMEDFRAMEBUFFERTEXTUREPROC ) gl3w_fn("glNamedFramebufferTexture"); gl3wNamedFramebufferTextureLayer = ( PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC ) gl3w_fn("glNamedFramebufferTextureLayer"); gl3wNamedRenderbufferStorage = ( PFNGLNAMEDRENDERBUFFERSTORAGEPROC ) gl3w_fn("glNamedRenderbufferStorage"); gl3wNamedRenderbufferStorageMultisample = ( PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC ) gl3w_fn("glNamedRenderbufferStorageMultisample"); gl3wNamedStringARB = ( PFNGLNAMEDSTRINGARBPROC ) gl3w_fn("glNamedStringARB"); gl3wObjectLabel = ( PFNGLOBJECTLABELPROC ) gl3w_fn("glObjectLabel"); gl3wObjectPtrLabel = ( PFNGLOBJECTPTRLABELPROC ) gl3w_fn("glObjectPtrLabel"); gl3wPatchParameterfv = ( PFNGLPATCHPARAMETERFVPROC ) gl3w_fn("glPatchParameterfv"); gl3wPatchParameteri = ( PFNGLPATCHPARAMETERIPROC ) gl3w_fn("glPatchParameteri"); gl3wPauseTransformFeedback = ( PFNGLPAUSETRANSFORMFEEDBACKPROC ) gl3w_fn("glPauseTransformFeedback"); gl3wPixelStoref = ( PFNGLPIXELSTOREFPROC ) gl3w_fn("glPixelStoref"); gl3wPixelStorei = ( PFNGLPIXELSTOREIPROC ) gl3w_fn("glPixelStorei"); gl3wPointParameterf = ( PFNGLPOINTPARAMETERFPROC ) gl3w_fn("glPointParameterf"); gl3wPointParameterfv = ( PFNGLPOINTPARAMETERFVPROC ) gl3w_fn("glPointParameterfv"); gl3wPointParameteri = ( PFNGLPOINTPARAMETERIPROC ) gl3w_fn("glPointParameteri"); gl3wPointParameteriv = ( PFNGLPOINTPARAMETERIVPROC ) gl3w_fn("glPointParameteriv"); gl3wPointSize = ( PFNGLPOINTSIZEPROC ) gl3w_fn("glPointSize"); gl3wPolygonMode = ( PFNGLPOLYGONMODEPROC ) gl3w_fn("glPolygonMode"); gl3wPolygonOffset = ( PFNGLPOLYGONOFFSETPROC ) gl3w_fn("glPolygonOffset"); gl3wPopDebugGroup = ( PFNGLPOPDEBUGGROUPPROC ) gl3w_fn("glPopDebugGroup"); gl3wPrimitiveRestartIndex = ( PFNGLPRIMITIVERESTARTINDEXPROC ) gl3w_fn("glPrimitiveRestartIndex"); gl3wProgramBinary = ( PFNGLPROGRAMBINARYPROC ) gl3w_fn("glProgramBinary"); gl3wProgramParameteri = ( PFNGLPROGRAMPARAMETERIPROC ) gl3w_fn("glProgramParameteri"); gl3wProgramUniform1d = ( PFNGLPROGRAMUNIFORM1DPROC ) gl3w_fn("glProgramUniform1d"); gl3wProgramUniform1dv = ( PFNGLPROGRAMUNIFORM1DVPROC ) gl3w_fn("glProgramUniform1dv"); gl3wProgramUniform1f = ( PFNGLPROGRAMUNIFORM1FPROC ) gl3w_fn("glProgramUniform1f"); gl3wProgramUniform1fv = ( PFNGLPROGRAMUNIFORM1FVPROC ) gl3w_fn("glProgramUniform1fv"); gl3wProgramUniform1i = ( PFNGLPROGRAMUNIFORM1IPROC ) gl3w_fn("glProgramUniform1i"); gl3wProgramUniform1iv = ( PFNGLPROGRAMUNIFORM1IVPROC ) gl3w_fn("glProgramUniform1iv"); gl3wProgramUniform1ui = ( PFNGLPROGRAMUNIFORM1UIPROC ) gl3w_fn("glProgramUniform1ui"); gl3wProgramUniform1uiv = ( PFNGLPROGRAMUNIFORM1UIVPROC ) gl3w_fn("glProgramUniform1uiv"); gl3wProgramUniform2d = ( PFNGLPROGRAMUNIFORM2DPROC ) gl3w_fn("glProgramUniform2d"); gl3wProgramUniform2dv = ( PFNGLPROGRAMUNIFORM2DVPROC ) gl3w_fn("glProgramUniform2dv"); gl3wProgramUniform2f = ( PFNGLPROGRAMUNIFORM2FPROC ) gl3w_fn("glProgramUniform2f"); gl3wProgramUniform2fv = ( PFNGLPROGRAMUNIFORM2FVPROC ) gl3w_fn("glProgramUniform2fv"); gl3wProgramUniform2i = ( PFNGLPROGRAMUNIFORM2IPROC ) gl3w_fn("glProgramUniform2i"); gl3wProgramUniform2iv = ( PFNGLPROGRAMUNIFORM2IVPROC ) gl3w_fn("glProgramUniform2iv"); gl3wProgramUniform2ui = ( PFNGLPROGRAMUNIFORM2UIPROC ) gl3w_fn("glProgramUniform2ui"); gl3wProgramUniform2uiv = ( PFNGLPROGRAMUNIFORM2UIVPROC ) gl3w_fn("glProgramUniform2uiv"); gl3wProgramUniform3d = ( PFNGLPROGRAMUNIFORM3DPROC ) gl3w_fn("glProgramUniform3d"); gl3wProgramUniform3dv = ( PFNGLPROGRAMUNIFORM3DVPROC ) gl3w_fn("glProgramUniform3dv"); gl3wProgramUniform3f = ( PFNGLPROGRAMUNIFORM3FPROC ) gl3w_fn("glProgramUniform3f"); gl3wProgramUniform3fv = ( PFNGLPROGRAMUNIFORM3FVPROC ) gl3w_fn("glProgramUniform3fv"); gl3wProgramUniform3i = ( PFNGLPROGRAMUNIFORM3IPROC ) gl3w_fn("glProgramUniform3i"); gl3wProgramUniform3iv = ( PFNGLPROGRAMUNIFORM3IVPROC ) gl3w_fn("glProgramUniform3iv"); gl3wProgramUniform3ui = ( PFNGLPROGRAMUNIFORM3UIPROC ) gl3w_fn("glProgramUniform3ui"); gl3wProgramUniform3uiv = ( PFNGLPROGRAMUNIFORM3UIVPROC ) gl3w_fn("glProgramUniform3uiv"); gl3wProgramUniform4d = ( PFNGLPROGRAMUNIFORM4DPROC ) gl3w_fn("glProgramUniform4d"); gl3wProgramUniform4dv = ( PFNGLPROGRAMUNIFORM4DVPROC ) gl3w_fn("glProgramUniform4dv"); gl3wProgramUniform4f = ( PFNGLPROGRAMUNIFORM4FPROC ) gl3w_fn("glProgramUniform4f"); gl3wProgramUniform4fv = ( PFNGLPROGRAMUNIFORM4FVPROC ) gl3w_fn("glProgramUniform4fv"); gl3wProgramUniform4i = ( PFNGLPROGRAMUNIFORM4IPROC ) gl3w_fn("glProgramUniform4i"); gl3wProgramUniform4iv = ( PFNGLPROGRAMUNIFORM4IVPROC ) gl3w_fn("glProgramUniform4iv"); gl3wProgramUniform4ui = ( PFNGLPROGRAMUNIFORM4UIPROC ) gl3w_fn("glProgramUniform4ui"); gl3wProgramUniform4uiv = ( PFNGLPROGRAMUNIFORM4UIVPROC ) gl3w_fn("glProgramUniform4uiv"); gl3wProgramUniformHandleui64ARB = ( PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC ) gl3w_fn("glProgramUniformHandleui64ARB"); gl3wProgramUniformHandleui64vARB = ( PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC ) gl3w_fn("glProgramUniformHandleui64vARB"); gl3wProgramUniformMatrix2dv = ( PFNGLPROGRAMUNIFORMMATRIX2DVPROC ) gl3w_fn("glProgramUniformMatrix2dv"); gl3wProgramUniformMatrix2fv = ( PFNGLPROGRAMUNIFORMMATRIX2FVPROC ) gl3w_fn("glProgramUniformMatrix2fv"); gl3wProgramUniformMatrix2x3dv = ( PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC ) gl3w_fn("glProgramUniformMatrix2x3dv"); gl3wProgramUniformMatrix2x3fv = ( PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC ) gl3w_fn("glProgramUniformMatrix2x3fv"); gl3wProgramUniformMatrix2x4dv = ( PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC ) gl3w_fn("glProgramUniformMatrix2x4dv"); gl3wProgramUniformMatrix2x4fv = ( PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC ) gl3w_fn("glProgramUniformMatrix2x4fv"); gl3wProgramUniformMatrix3dv = ( PFNGLPROGRAMUNIFORMMATRIX3DVPROC ) gl3w_fn("glProgramUniformMatrix3dv"); gl3wProgramUniformMatrix3fv = ( PFNGLPROGRAMUNIFORMMATRIX3FVPROC ) gl3w_fn("glProgramUniformMatrix3fv"); gl3wProgramUniformMatrix3x2dv = ( PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC ) gl3w_fn("glProgramUniformMatrix3x2dv"); gl3wProgramUniformMatrix3x2fv = ( PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC ) gl3w_fn("glProgramUniformMatrix3x2fv"); gl3wProgramUniformMatrix3x4dv = ( PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC ) gl3w_fn("glProgramUniformMatrix3x4dv"); gl3wProgramUniformMatrix3x4fv = ( PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC ) gl3w_fn("glProgramUniformMatrix3x4fv"); gl3wProgramUniformMatrix4dv = ( PFNGLPROGRAMUNIFORMMATRIX4DVPROC ) gl3w_fn("glProgramUniformMatrix4dv"); gl3wProgramUniformMatrix4fv = ( PFNGLPROGRAMUNIFORMMATRIX4FVPROC ) gl3w_fn("glProgramUniformMatrix4fv"); gl3wProgramUniformMatrix4x2dv = ( PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC ) gl3w_fn("glProgramUniformMatrix4x2dv"); gl3wProgramUniformMatrix4x2fv = ( PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC ) gl3w_fn("glProgramUniformMatrix4x2fv"); gl3wProgramUniformMatrix4x3dv = ( PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC ) gl3w_fn("glProgramUniformMatrix4x3dv"); gl3wProgramUniformMatrix4x3fv = ( PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC ) gl3w_fn("glProgramUniformMatrix4x3fv"); gl3wProvokingVertex = ( PFNGLPROVOKINGVERTEXPROC ) gl3w_fn("glProvokingVertex"); gl3wPushDebugGroup = ( PFNGLPUSHDEBUGGROUPPROC ) gl3w_fn("glPushDebugGroup"); gl3wQueryCounter = ( PFNGLQUERYCOUNTERPROC ) gl3w_fn("glQueryCounter"); gl3wReadBuffer = ( PFNGLREADBUFFERPROC ) gl3w_fn("glReadBuffer"); gl3wReadPixels = ( PFNGLREADPIXELSPROC ) gl3w_fn("glReadPixels"); gl3wReadnPixels = ( PFNGLREADNPIXELSPROC ) gl3w_fn("glReadnPixels"); gl3wReadnPixelsARB = ( PFNGLREADNPIXELSARBPROC ) gl3w_fn("glReadnPixelsARB"); gl3wReleaseShaderCompiler = ( PFNGLRELEASESHADERCOMPILERPROC ) gl3w_fn("glReleaseShaderCompiler"); gl3wRenderbufferStorage = ( PFNGLRENDERBUFFERSTORAGEPROC ) gl3w_fn("glRenderbufferStorage"); gl3wRenderbufferStorageMultisample = ( PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC ) gl3w_fn("glRenderbufferStorageMultisample"); gl3wResumeTransformFeedback = ( PFNGLRESUMETRANSFORMFEEDBACKPROC ) gl3w_fn("glResumeTransformFeedback"); gl3wSampleCoverage = ( PFNGLSAMPLECOVERAGEPROC ) gl3w_fn("glSampleCoverage"); gl3wSampleMaski = ( PFNGLSAMPLEMASKIPROC ) gl3w_fn("glSampleMaski"); gl3wSamplerParameterIiv = ( PFNGLSAMPLERPARAMETERIIVPROC ) gl3w_fn("glSamplerParameterIiv"); gl3wSamplerParameterIuiv = ( PFNGLSAMPLERPARAMETERIUIVPROC ) gl3w_fn("glSamplerParameterIuiv"); gl3wSamplerParameterf = ( PFNGLSAMPLERPARAMETERFPROC ) gl3w_fn("glSamplerParameterf"); gl3wSamplerParameterfv = ( PFNGLSAMPLERPARAMETERFVPROC ) gl3w_fn("glSamplerParameterfv"); gl3wSamplerParameteri = ( PFNGLSAMPLERPARAMETERIPROC ) gl3w_fn("glSamplerParameteri"); gl3wSamplerParameteriv = ( PFNGLSAMPLERPARAMETERIVPROC ) gl3w_fn("glSamplerParameteriv"); gl3wScissor = ( PFNGLSCISSORPROC ) gl3w_fn("glScissor"); gl3wScissorArrayv = ( PFNGLSCISSORARRAYVPROC ) gl3w_fn("glScissorArrayv"); gl3wScissorIndexed = ( PFNGLSCISSORINDEXEDPROC ) gl3w_fn("glScissorIndexed"); gl3wScissorIndexedv = ( PFNGLSCISSORINDEXEDVPROC ) gl3w_fn("glScissorIndexedv"); gl3wShaderBinary = ( PFNGLSHADERBINARYPROC ) gl3w_fn("glShaderBinary"); gl3wShaderSource = ( PFNGLSHADERSOURCEPROC ) gl3w_fn("glShaderSource"); gl3wShaderStorageBlockBinding = ( PFNGLSHADERSTORAGEBLOCKBINDINGPROC ) gl3w_fn("glShaderStorageBlockBinding"); gl3wStencilFunc = ( PFNGLSTENCILFUNCPROC ) gl3w_fn("glStencilFunc"); gl3wStencilFuncSeparate = ( PFNGLSTENCILFUNCSEPARATEPROC ) gl3w_fn("glStencilFuncSeparate"); gl3wStencilMask = ( PFNGLSTENCILMASKPROC ) gl3w_fn("glStencilMask"); gl3wStencilMaskSeparate = ( PFNGLSTENCILMASKSEPARATEPROC ) gl3w_fn("glStencilMaskSeparate"); gl3wStencilOp = ( PFNGLSTENCILOPPROC ) gl3w_fn("glStencilOp"); gl3wStencilOpSeparate = ( PFNGLSTENCILOPSEPARATEPROC ) gl3w_fn("glStencilOpSeparate"); gl3wTexBuffer = ( PFNGLTEXBUFFERPROC ) gl3w_fn("glTexBuffer"); gl3wTexBufferRange = ( PFNGLTEXBUFFERRANGEPROC ) gl3w_fn("glTexBufferRange"); gl3wTexImage1D = ( PFNGLTEXIMAGE1DPROC ) gl3w_fn("glTexImage1D"); gl3wTexImage2D = ( PFNGLTEXIMAGE2DPROC ) gl3w_fn("glTexImage2D"); gl3wTexImage2DMultisample = ( PFNGLTEXIMAGE2DMULTISAMPLEPROC ) gl3w_fn("glTexImage2DMultisample"); gl3wTexImage3D = ( PFNGLTEXIMAGE3DPROC ) gl3w_fn("glTexImage3D"); gl3wTexImage3DMultisample = ( PFNGLTEXIMAGE3DMULTISAMPLEPROC ) gl3w_fn("glTexImage3DMultisample"); gl3wTexPageCommitmentARB = ( PFNGLTEXPAGECOMMITMENTARBPROC ) gl3w_fn("glTexPageCommitmentARB"); gl3wTexParameterIiv = ( PFNGLTEXPARAMETERIIVPROC ) gl3w_fn("glTexParameterIiv"); gl3wTexParameterIuiv = ( PFNGLTEXPARAMETERIUIVPROC ) gl3w_fn("glTexParameterIuiv"); gl3wTexParameterf = ( PFNGLTEXPARAMETERFPROC ) gl3w_fn("glTexParameterf"); gl3wTexParameterfv = ( PFNGLTEXPARAMETERFVPROC ) gl3w_fn("glTexParameterfv"); gl3wTexParameteri = ( PFNGLTEXPARAMETERIPROC ) gl3w_fn("glTexParameteri"); gl3wTexParameteriv = ( PFNGLTEXPARAMETERIVPROC ) gl3w_fn("glTexParameteriv"); gl3wTexStorage1D = ( PFNGLTEXSTORAGE1DPROC ) gl3w_fn("glTexStorage1D"); gl3wTexStorage2D = ( PFNGLTEXSTORAGE2DPROC ) gl3w_fn("glTexStorage2D"); gl3wTexStorage2DMultisample = ( PFNGLTEXSTORAGE2DMULTISAMPLEPROC ) gl3w_fn("glTexStorage2DMultisample"); gl3wTexStorage3D = ( PFNGLTEXSTORAGE3DPROC ) gl3w_fn("glTexStorage3D"); gl3wTexStorage3DMultisample = ( PFNGLTEXSTORAGE3DMULTISAMPLEPROC ) gl3w_fn("glTexStorage3DMultisample"); gl3wTexSubImage1D = ( PFNGLTEXSUBIMAGE1DPROC ) gl3w_fn("glTexSubImage1D"); gl3wTexSubImage2D = ( PFNGLTEXSUBIMAGE2DPROC ) gl3w_fn("glTexSubImage2D"); gl3wTexSubImage3D = ( PFNGLTEXSUBIMAGE3DPROC ) gl3w_fn("glTexSubImage3D"); gl3wTextureBarrier = ( PFNGLTEXTUREBARRIERPROC ) gl3w_fn("glTextureBarrier"); gl3wTextureBuffer = ( PFNGLTEXTUREBUFFERPROC ) gl3w_fn("glTextureBuffer"); gl3wTextureBufferRange = ( PFNGLTEXTUREBUFFERRANGEPROC ) gl3w_fn("glTextureBufferRange"); gl3wTextureParameterIiv = ( PFNGLTEXTUREPARAMETERIIVPROC ) gl3w_fn("glTextureParameterIiv"); gl3wTextureParameterIuiv = ( PFNGLTEXTUREPARAMETERIUIVPROC ) gl3w_fn("glTextureParameterIuiv"); gl3wTextureParameterf = ( PFNGLTEXTUREPARAMETERFPROC ) gl3w_fn("glTextureParameterf"); gl3wTextureParameterfv = ( PFNGLTEXTUREPARAMETERFVPROC ) gl3w_fn("glTextureParameterfv"); gl3wTextureParameteri = ( PFNGLTEXTUREPARAMETERIPROC ) gl3w_fn("glTextureParameteri"); gl3wTextureParameteriv = ( PFNGLTEXTUREPARAMETERIVPROC ) gl3w_fn("glTextureParameteriv"); gl3wTextureStorage1D = ( PFNGLTEXTURESTORAGE1DPROC ) gl3w_fn("glTextureStorage1D"); gl3wTextureStorage2D = ( PFNGLTEXTURESTORAGE2DPROC ) gl3w_fn("glTextureStorage2D"); gl3wTextureStorage2DMultisample = ( PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC ) gl3w_fn("glTextureStorage2DMultisample"); gl3wTextureStorage3D = ( PFNGLTEXTURESTORAGE3DPROC ) gl3w_fn("glTextureStorage3D"); gl3wTextureStorage3DMultisample = ( PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC ) gl3w_fn("glTextureStorage3DMultisample"); gl3wTextureSubImage1D = ( PFNGLTEXTURESUBIMAGE1DPROC ) gl3w_fn("glTextureSubImage1D"); gl3wTextureSubImage2D = ( PFNGLTEXTURESUBIMAGE2DPROC ) gl3w_fn("glTextureSubImage2D"); gl3wTextureSubImage3D = ( PFNGLTEXTURESUBIMAGE3DPROC ) gl3w_fn("glTextureSubImage3D"); gl3wTextureView = ( PFNGLTEXTUREVIEWPROC ) gl3w_fn("glTextureView"); gl3wTransformFeedbackBufferBase = ( PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC ) gl3w_fn("glTransformFeedbackBufferBase"); gl3wTransformFeedbackBufferRange = ( PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC ) gl3w_fn("glTransformFeedbackBufferRange"); gl3wTransformFeedbackVaryings = ( PFNGLTRANSFORMFEEDBACKVARYINGSPROC ) gl3w_fn("glTransformFeedbackVaryings"); gl3wUniform1d = ( PFNGLUNIFORM1DPROC ) gl3w_fn("glUniform1d"); gl3wUniform1dv = ( PFNGLUNIFORM1DVPROC ) gl3w_fn("glUniform1dv"); gl3wUniform1f = ( PFNGLUNIFORM1FPROC ) gl3w_fn("glUniform1f"); gl3wUniform1fv = ( PFNGLUNIFORM1FVPROC ) gl3w_fn("glUniform1fv"); gl3wUniform1i = ( PFNGLUNIFORM1IPROC ) gl3w_fn("glUniform1i"); gl3wUniform1iv = ( PFNGLUNIFORM1IVPROC ) gl3w_fn("glUniform1iv"); gl3wUniform1ui = ( PFNGLUNIFORM1UIPROC ) gl3w_fn("glUniform1ui"); gl3wUniform1uiv = ( PFNGLUNIFORM1UIVPROC ) gl3w_fn("glUniform1uiv"); gl3wUniform2d = ( PFNGLUNIFORM2DPROC ) gl3w_fn("glUniform2d"); gl3wUniform2dv = ( PFNGLUNIFORM2DVPROC ) gl3w_fn("glUniform2dv"); gl3wUniform2f = ( PFNGLUNIFORM2FPROC ) gl3w_fn("glUniform2f"); gl3wUniform2fv = ( PFNGLUNIFORM2FVPROC ) gl3w_fn("glUniform2fv"); gl3wUniform2i = ( PFNGLUNIFORM2IPROC ) gl3w_fn("glUniform2i"); gl3wUniform2iv = ( PFNGLUNIFORM2IVPROC ) gl3w_fn("glUniform2iv"); gl3wUniform2ui = ( PFNGLUNIFORM2UIPROC ) gl3w_fn("glUniform2ui"); gl3wUniform2uiv = ( PFNGLUNIFORM2UIVPROC ) gl3w_fn("glUniform2uiv"); gl3wUniform3d = ( PFNGLUNIFORM3DPROC ) gl3w_fn("glUniform3d"); gl3wUniform3dv = ( PFNGLUNIFORM3DVPROC ) gl3w_fn("glUniform3dv"); gl3wUniform3f = ( PFNGLUNIFORM3FPROC ) gl3w_fn("glUniform3f"); gl3wUniform3fv = ( PFNGLUNIFORM3FVPROC ) gl3w_fn("glUniform3fv"); gl3wUniform3i = ( PFNGLUNIFORM3IPROC ) gl3w_fn("glUniform3i"); gl3wUniform3iv = ( PFNGLUNIFORM3IVPROC ) gl3w_fn("glUniform3iv"); gl3wUniform3ui = ( PFNGLUNIFORM3UIPROC ) gl3w_fn("glUniform3ui"); gl3wUniform3uiv = ( PFNGLUNIFORM3UIVPROC ) gl3w_fn("glUniform3uiv"); gl3wUniform4d = ( PFNGLUNIFORM4DPROC ) gl3w_fn("glUniform4d"); gl3wUniform4dv = ( PFNGLUNIFORM4DVPROC ) gl3w_fn("glUniform4dv"); gl3wUniform4f = ( PFNGLUNIFORM4FPROC ) gl3w_fn("glUniform4f"); gl3wUniform4fv = ( PFNGLUNIFORM4FVPROC ) gl3w_fn("glUniform4fv"); gl3wUniform4i = ( PFNGLUNIFORM4IPROC ) gl3w_fn("glUniform4i"); gl3wUniform4iv = ( PFNGLUNIFORM4IVPROC ) gl3w_fn("glUniform4iv"); gl3wUniform4ui = ( PFNGLUNIFORM4UIPROC ) gl3w_fn("glUniform4ui"); gl3wUniform4uiv = ( PFNGLUNIFORM4UIVPROC ) gl3w_fn("glUniform4uiv"); gl3wUniformBlockBinding = ( PFNGLUNIFORMBLOCKBINDINGPROC ) gl3w_fn("glUniformBlockBinding"); gl3wUniformHandleui64ARB = ( PFNGLUNIFORMHANDLEUI64ARBPROC ) gl3w_fn("glUniformHandleui64ARB"); gl3wUniformHandleui64vARB = ( PFNGLUNIFORMHANDLEUI64VARBPROC ) gl3w_fn("glUniformHandleui64vARB"); gl3wUniformMatrix2dv = ( PFNGLUNIFORMMATRIX2DVPROC ) gl3w_fn("glUniformMatrix2dv"); gl3wUniformMatrix2fv = ( PFNGLUNIFORMMATRIX2FVPROC ) gl3w_fn("glUniformMatrix2fv"); gl3wUniformMatrix2x3dv = ( PFNGLUNIFORMMATRIX2X3DVPROC ) gl3w_fn("glUniformMatrix2x3dv"); gl3wUniformMatrix2x3fv = ( PFNGLUNIFORMMATRIX2X3FVPROC ) gl3w_fn("glUniformMatrix2x3fv"); gl3wUniformMatrix2x4dv = ( PFNGLUNIFORMMATRIX2X4DVPROC ) gl3w_fn("glUniformMatrix2x4dv"); gl3wUniformMatrix2x4fv = ( PFNGLUNIFORMMATRIX2X4FVPROC ) gl3w_fn("glUniformMatrix2x4fv"); gl3wUniformMatrix3dv = ( PFNGLUNIFORMMATRIX3DVPROC ) gl3w_fn("glUniformMatrix3dv"); gl3wUniformMatrix3fv = ( PFNGLUNIFORMMATRIX3FVPROC ) gl3w_fn("glUniformMatrix3fv"); gl3wUniformMatrix3x2dv = ( PFNGLUNIFORMMATRIX3X2DVPROC ) gl3w_fn("glUniformMatrix3x2dv"); gl3wUniformMatrix3x2fv = ( PFNGLUNIFORMMATRIX3X2FVPROC ) gl3w_fn("glUniformMatrix3x2fv"); gl3wUniformMatrix3x4dv = ( PFNGLUNIFORMMATRIX3X4DVPROC ) gl3w_fn("glUniformMatrix3x4dv"); gl3wUniformMatrix3x4fv = ( PFNGLUNIFORMMATRIX3X4FVPROC ) gl3w_fn("glUniformMatrix3x4fv"); gl3wUniformMatrix4dv = ( PFNGLUNIFORMMATRIX4DVPROC ) gl3w_fn("glUniformMatrix4dv"); gl3wUniformMatrix4fv = ( PFNGLUNIFORMMATRIX4FVPROC ) gl3w_fn("glUniformMatrix4fv"); gl3wUniformMatrix4x2dv = ( PFNGLUNIFORMMATRIX4X2DVPROC ) gl3w_fn("glUniformMatrix4x2dv"); gl3wUniformMatrix4x2fv = ( PFNGLUNIFORMMATRIX4X2FVPROC ) gl3w_fn("glUniformMatrix4x2fv"); gl3wUniformMatrix4x3dv = ( PFNGLUNIFORMMATRIX4X3DVPROC ) gl3w_fn("glUniformMatrix4x3dv"); gl3wUniformMatrix4x3fv = ( PFNGLUNIFORMMATRIX4X3FVPROC ) gl3w_fn("glUniformMatrix4x3fv"); gl3wUniformSubroutinesuiv = ( PFNGLUNIFORMSUBROUTINESUIVPROC ) gl3w_fn("glUniformSubroutinesuiv"); gl3wUnmapBuffer = ( PFNGLUNMAPBUFFERPROC ) gl3w_fn("glUnmapBuffer"); gl3wUnmapNamedBuffer = ( PFNGLUNMAPNAMEDBUFFERPROC ) gl3w_fn("glUnmapNamedBuffer"); gl3wUseProgram = ( PFNGLUSEPROGRAMPROC ) gl3w_fn("glUseProgram"); gl3wUseProgramStages = ( PFNGLUSEPROGRAMSTAGESPROC ) gl3w_fn("glUseProgramStages"); gl3wValidateProgram = ( PFNGLVALIDATEPROGRAMPROC ) gl3w_fn("glValidateProgram"); gl3wValidateProgramPipeline = ( PFNGLVALIDATEPROGRAMPIPELINEPROC ) gl3w_fn("glValidateProgramPipeline"); gl3wVertexArrayAttribBinding = ( PFNGLVERTEXARRAYATTRIBBINDINGPROC ) gl3w_fn("glVertexArrayAttribBinding"); gl3wVertexArrayAttribFormat = ( PFNGLVERTEXARRAYATTRIBFORMATPROC ) gl3w_fn("glVertexArrayAttribFormat"); gl3wVertexArrayAttribIFormat = ( PFNGLVERTEXARRAYATTRIBIFORMATPROC ) gl3w_fn("glVertexArrayAttribIFormat"); gl3wVertexArrayAttribLFormat = ( PFNGLVERTEXARRAYATTRIBLFORMATPROC ) gl3w_fn("glVertexArrayAttribLFormat"); gl3wVertexArrayBindingDivisor = ( PFNGLVERTEXARRAYBINDINGDIVISORPROC ) gl3w_fn("glVertexArrayBindingDivisor"); gl3wVertexArrayElementBuffer = ( PFNGLVERTEXARRAYELEMENTBUFFERPROC ) gl3w_fn("glVertexArrayElementBuffer"); gl3wVertexArrayVertexBuffer = ( PFNGLVERTEXARRAYVERTEXBUFFERPROC ) gl3w_fn("glVertexArrayVertexBuffer"); gl3wVertexArrayVertexBuffers = ( PFNGLVERTEXARRAYVERTEXBUFFERSPROC ) gl3w_fn("glVertexArrayVertexBuffers"); gl3wVertexAttrib1d = ( PFNGLVERTEXATTRIB1DPROC ) gl3w_fn("glVertexAttrib1d"); gl3wVertexAttrib1dv = ( PFNGLVERTEXATTRIB1DVPROC ) gl3w_fn("glVertexAttrib1dv"); gl3wVertexAttrib1f = ( PFNGLVERTEXATTRIB1FPROC ) gl3w_fn("glVertexAttrib1f"); gl3wVertexAttrib1fv = ( PFNGLVERTEXATTRIB1FVPROC ) gl3w_fn("glVertexAttrib1fv"); gl3wVertexAttrib1s = ( PFNGLVERTEXATTRIB1SPROC ) gl3w_fn("glVertexAttrib1s"); gl3wVertexAttrib1sv = ( PFNGLVERTEXATTRIB1SVPROC ) gl3w_fn("glVertexAttrib1sv"); gl3wVertexAttrib2d = ( PFNGLVERTEXATTRIB2DPROC ) gl3w_fn("glVertexAttrib2d"); gl3wVertexAttrib2dv = ( PFNGLVERTEXATTRIB2DVPROC ) gl3w_fn("glVertexAttrib2dv"); gl3wVertexAttrib2f = ( PFNGLVERTEXATTRIB2FPROC ) gl3w_fn("glVertexAttrib2f"); gl3wVertexAttrib2fv = ( PFNGLVERTEXATTRIB2FVPROC ) gl3w_fn("glVertexAttrib2fv"); gl3wVertexAttrib2s = ( PFNGLVERTEXATTRIB2SPROC ) gl3w_fn("glVertexAttrib2s"); gl3wVertexAttrib2sv = ( PFNGLVERTEXATTRIB2SVPROC ) gl3w_fn("glVertexAttrib2sv"); gl3wVertexAttrib3d = ( PFNGLVERTEXATTRIB3DPROC ) gl3w_fn("glVertexAttrib3d"); gl3wVertexAttrib3dv = ( PFNGLVERTEXATTRIB3DVPROC ) gl3w_fn("glVertexAttrib3dv"); gl3wVertexAttrib3f = ( PFNGLVERTEXATTRIB3FPROC ) gl3w_fn("glVertexAttrib3f"); gl3wVertexAttrib3fv = ( PFNGLVERTEXATTRIB3FVPROC ) gl3w_fn("glVertexAttrib3fv"); gl3wVertexAttrib3s = ( PFNGLVERTEXATTRIB3SPROC ) gl3w_fn("glVertexAttrib3s"); gl3wVertexAttrib3sv = ( PFNGLVERTEXATTRIB3SVPROC ) gl3w_fn("glVertexAttrib3sv"); gl3wVertexAttrib4Nbv = ( PFNGLVERTEXATTRIB4NBVPROC ) gl3w_fn("glVertexAttrib4Nbv"); gl3wVertexAttrib4Niv = ( PFNGLVERTEXATTRIB4NIVPROC ) gl3w_fn("glVertexAttrib4Niv"); gl3wVertexAttrib4Nsv = ( PFNGLVERTEXATTRIB4NSVPROC ) gl3w_fn("glVertexAttrib4Nsv"); gl3wVertexAttrib4Nub = ( PFNGLVERTEXATTRIB4NUBPROC ) gl3w_fn("glVertexAttrib4Nub"); gl3wVertexAttrib4Nubv = ( PFNGLVERTEXATTRIB4NUBVPROC ) gl3w_fn("glVertexAttrib4Nubv"); gl3wVertexAttrib4Nuiv = ( PFNGLVERTEXATTRIB4NUIVPROC ) gl3w_fn("glVertexAttrib4Nuiv"); gl3wVertexAttrib4Nusv = ( PFNGLVERTEXATTRIB4NUSVPROC ) gl3w_fn("glVertexAttrib4Nusv"); gl3wVertexAttrib4bv = ( PFNGLVERTEXATTRIB4BVPROC ) gl3w_fn("glVertexAttrib4bv"); gl3wVertexAttrib4d = ( PFNGLVERTEXATTRIB4DPROC ) gl3w_fn("glVertexAttrib4d"); gl3wVertexAttrib4dv = ( PFNGLVERTEXATTRIB4DVPROC ) gl3w_fn("glVertexAttrib4dv"); gl3wVertexAttrib4f = ( PFNGLVERTEXATTRIB4FPROC ) gl3w_fn("glVertexAttrib4f"); gl3wVertexAttrib4fv = ( PFNGLVERTEXATTRIB4FVPROC ) gl3w_fn("glVertexAttrib4fv"); gl3wVertexAttrib4iv = ( PFNGLVERTEXATTRIB4IVPROC ) gl3w_fn("glVertexAttrib4iv"); gl3wVertexAttrib4s = ( PFNGLVERTEXATTRIB4SPROC ) gl3w_fn("glVertexAttrib4s"); gl3wVertexAttrib4sv = ( PFNGLVERTEXATTRIB4SVPROC ) gl3w_fn("glVertexAttrib4sv"); gl3wVertexAttrib4ubv = ( PFNGLVERTEXATTRIB4UBVPROC ) gl3w_fn("glVertexAttrib4ubv"); gl3wVertexAttrib4uiv = ( PFNGLVERTEXATTRIB4UIVPROC ) gl3w_fn("glVertexAttrib4uiv"); gl3wVertexAttrib4usv = ( PFNGLVERTEXATTRIB4USVPROC ) gl3w_fn("glVertexAttrib4usv"); gl3wVertexAttribBinding = ( PFNGLVERTEXATTRIBBINDINGPROC ) gl3w_fn("glVertexAttribBinding"); gl3wVertexAttribDivisor = ( PFNGLVERTEXATTRIBDIVISORPROC ) gl3w_fn("glVertexAttribDivisor"); gl3wVertexAttribFormat = ( PFNGLVERTEXATTRIBFORMATPROC ) gl3w_fn("glVertexAttribFormat"); gl3wVertexAttribI1i = ( PFNGLVERTEXATTRIBI1IPROC ) gl3w_fn("glVertexAttribI1i"); gl3wVertexAttribI1iv = ( PFNGLVERTEXATTRIBI1IVPROC ) gl3w_fn("glVertexAttribI1iv"); gl3wVertexAttribI1ui = ( PFNGLVERTEXATTRIBI1UIPROC ) gl3w_fn("glVertexAttribI1ui"); gl3wVertexAttribI1uiv = ( PFNGLVERTEXATTRIBI1UIVPROC ) gl3w_fn("glVertexAttribI1uiv"); gl3wVertexAttribI2i = ( PFNGLVERTEXATTRIBI2IPROC ) gl3w_fn("glVertexAttribI2i"); gl3wVertexAttribI2iv = ( PFNGLVERTEXATTRIBI2IVPROC ) gl3w_fn("glVertexAttribI2iv"); gl3wVertexAttribI2ui = ( PFNGLVERTEXATTRIBI2UIPROC ) gl3w_fn("glVertexAttribI2ui"); gl3wVertexAttribI2uiv = ( PFNGLVERTEXATTRIBI2UIVPROC ) gl3w_fn("glVertexAttribI2uiv"); gl3wVertexAttribI3i = ( PFNGLVERTEXATTRIBI3IPROC ) gl3w_fn("glVertexAttribI3i"); gl3wVertexAttribI3iv = ( PFNGLVERTEXATTRIBI3IVPROC ) gl3w_fn("glVertexAttribI3iv"); gl3wVertexAttribI3ui = ( PFNGLVERTEXATTRIBI3UIPROC ) gl3w_fn("glVertexAttribI3ui"); gl3wVertexAttribI3uiv = ( PFNGLVERTEXATTRIBI3UIVPROC ) gl3w_fn("glVertexAttribI3uiv"); gl3wVertexAttribI4bv = ( PFNGLVERTEXATTRIBI4BVPROC ) gl3w_fn("glVertexAttribI4bv"); gl3wVertexAttribI4i = ( PFNGLVERTEXATTRIBI4IPROC ) gl3w_fn("glVertexAttribI4i"); gl3wVertexAttribI4iv = ( PFNGLVERTEXATTRIBI4IVPROC ) gl3w_fn("glVertexAttribI4iv"); gl3wVertexAttribI4sv = ( PFNGLVERTEXATTRIBI4SVPROC ) gl3w_fn("glVertexAttribI4sv"); gl3wVertexAttribI4ubv = ( PFNGLVERTEXATTRIBI4UBVPROC ) gl3w_fn("glVertexAttribI4ubv"); gl3wVertexAttribI4ui = ( PFNGLVERTEXATTRIBI4UIPROC ) gl3w_fn("glVertexAttribI4ui"); gl3wVertexAttribI4uiv = ( PFNGLVERTEXATTRIBI4UIVPROC ) gl3w_fn("glVertexAttribI4uiv"); gl3wVertexAttribI4usv = ( PFNGLVERTEXATTRIBI4USVPROC ) gl3w_fn("glVertexAttribI4usv"); gl3wVertexAttribIFormat = ( PFNGLVERTEXATTRIBIFORMATPROC ) gl3w_fn("glVertexAttribIFormat"); gl3wVertexAttribIPointer = ( PFNGLVERTEXATTRIBIPOINTERPROC ) gl3w_fn("glVertexAttribIPointer"); gl3wVertexAttribL1d = ( PFNGLVERTEXATTRIBL1DPROC ) gl3w_fn("glVertexAttribL1d"); gl3wVertexAttribL1dv = ( PFNGLVERTEXATTRIBL1DVPROC ) gl3w_fn("glVertexAttribL1dv"); gl3wVertexAttribL1ui64ARB = ( PFNGLVERTEXATTRIBL1UI64ARBPROC ) gl3w_fn("glVertexAttribL1ui64ARB"); gl3wVertexAttribL1ui64vARB = ( PFNGLVERTEXATTRIBL1UI64VARBPROC ) gl3w_fn("glVertexAttribL1ui64vARB"); gl3wVertexAttribL2d = ( PFNGLVERTEXATTRIBL2DPROC ) gl3w_fn("glVertexAttribL2d"); gl3wVertexAttribL2dv = ( PFNGLVERTEXATTRIBL2DVPROC ) gl3w_fn("glVertexAttribL2dv"); gl3wVertexAttribL3d = ( PFNGLVERTEXATTRIBL3DPROC ) gl3w_fn("glVertexAttribL3d"); gl3wVertexAttribL3dv = ( PFNGLVERTEXATTRIBL3DVPROC ) gl3w_fn("glVertexAttribL3dv"); gl3wVertexAttribL4d = ( PFNGLVERTEXATTRIBL4DPROC ) gl3w_fn("glVertexAttribL4d"); gl3wVertexAttribL4dv = ( PFNGLVERTEXATTRIBL4DVPROC ) gl3w_fn("glVertexAttribL4dv"); gl3wVertexAttribLFormat = ( PFNGLVERTEXATTRIBLFORMATPROC ) gl3w_fn("glVertexAttribLFormat"); gl3wVertexAttribLPointer = ( PFNGLVERTEXATTRIBLPOINTERPROC ) gl3w_fn("glVertexAttribLPointer"); gl3wVertexAttribP1ui = ( PFNGLVERTEXATTRIBP1UIPROC ) gl3w_fn("glVertexAttribP1ui"); gl3wVertexAttribP1uiv = ( PFNGLVERTEXATTRIBP1UIVPROC ) gl3w_fn("glVertexAttribP1uiv"); gl3wVertexAttribP2ui = ( PFNGLVERTEXATTRIBP2UIPROC ) gl3w_fn("glVertexAttribP2ui"); gl3wVertexAttribP2uiv = ( PFNGLVERTEXATTRIBP2UIVPROC ) gl3w_fn("glVertexAttribP2uiv"); gl3wVertexAttribP3ui = ( PFNGLVERTEXATTRIBP3UIPROC ) gl3w_fn("glVertexAttribP3ui"); gl3wVertexAttribP3uiv = ( PFNGLVERTEXATTRIBP3UIVPROC ) gl3w_fn("glVertexAttribP3uiv"); gl3wVertexAttribP4ui = ( PFNGLVERTEXATTRIBP4UIPROC ) gl3w_fn("glVertexAttribP4ui"); gl3wVertexAttribP4uiv = ( PFNGLVERTEXATTRIBP4UIVPROC ) gl3w_fn("glVertexAttribP4uiv"); gl3wVertexAttribPointer = ( PFNGLVERTEXATTRIBPOINTERPROC ) gl3w_fn("glVertexAttribPointer"); gl3wVertexBindingDivisor = ( PFNGLVERTEXBINDINGDIVISORPROC ) gl3w_fn("glVertexBindingDivisor"); gl3wViewport = ( PFNGLVIEWPORTPROC ) gl3w_fn("glViewport"); gl3wViewportArrayv = ( PFNGLVIEWPORTARRAYVPROC ) gl3w_fn("glViewportArrayv"); gl3wViewportIndexedf = ( PFNGLVIEWPORTINDEXEDFPROC ) gl3w_fn("glViewportIndexedf"); gl3wViewportIndexedfv = ( PFNGLVIEWPORTINDEXEDFVPROC ) gl3w_fn("glViewportIndexedfv"); gl3wWaitSync = ( PFNGLWAITSYNCPROC ) gl3w_fn("glWaitSync"); } ================================================ FILE: samples/sample_d3d11.cpp ================================================ // ================================================================================================ // -*- C++ -*- // File: sample_d3d11.cpp // Author: Guilherme R. Lampert // Brief: D3D11 Debug Draw sample. Also uses the newer explicit context API. // // This software is in the public domain. Where that dedication is not recognized, // you are granted a perpetual, irrevocable license to copy, distribute, and modify // this file as you see fit. // ================================================================================================ #define DEBUG_DRAW_IMPLEMENTATION #define DEBUG_DRAW_EXPLICIT_CONTEXT #include "debug_draw.hpp" #define DD_SAMPLES_NOGL #include "samples_common.hpp" using namespace ddSamplesCommon; #include #include #define NOIME #define NOMINMAX #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #include #include #pragma comment(lib, "Shcore") #pragma comment(lib, "d3d11") #pragma comment(lib, "dxguid") #pragma comment(lib, "d3dcompiler") using Microsoft::WRL::ComPtr; // ======================================================== // Helper functions // ======================================================== static void panicF(const char * format, ...) { va_list args; char buffer[2048] = {'\0'}; va_start(args, format); std::vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); MessageBoxA(nullptr, buffer, "Fatal Error", MB_OK); std::abort(); } // ======================================================== // Window // ======================================================== const wchar_t WindowTitle[] = L"Debug Draw - D3D11 Sample"; const wchar_t WindowClassName[] = L"DebugDrawD3D11"; class Window { public: HINSTANCE hInst = nullptr; HWND hWindow = nullptr; Window(HINSTANCE hInstance, int nCmdShow) : hInst(hInstance) { registerClass(); createWindow(nCmdShow); } virtual ~Window() { if (hWindow != nullptr) { DestroyWindow(hWindow); } if (hInst != nullptr) { UnregisterClass(WindowClassName, hInst); } } void runMessageLoop() { MSG msg = {0}; while (msg.message != WM_QUIT) { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } onRender(); } } virtual void onRender() { } // // DPI scaling helpers: // static const std::tuple DpiXY; static const int WidthScaled; static const int HeightScaled; static int GetDpiAdjustedX(int size) { return static_cast(size * std::get<0>(DpiXY) / 96.0f); } static int GetDpiAdjustedY(int size) { return static_cast(size * std::get<1>(DpiXY) / 96.0f); } static std::tuple GetDpiXY() { const POINT ptZero = {0,0}; HMONITOR hm = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY); UINT dpiX = 0, dpiY = 0; if (FAILED(GetDpiForMonitor(hm, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) { dpiX = dpiY = 192; // Some arbitrary default (2x scaling) } return {float(dpiX), float(dpiY)}; } private: void registerClass() { WNDCLASSEX wcex = {0}; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = &Window::WndProc; wcex.hInstance = hInst; wcex.lpszClassName = WindowClassName; wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.hIcon = LoadIcon(nullptr, IDI_APPLICATION); wcex.hIconSm = LoadIcon(nullptr, IDI_APPLICATION); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); RegisterClassEx(&wcex); } void createWindow(int nCmdShow) { hWindow = CreateWindow(WindowClassName, WindowTitle, WS_OVERLAPPEDWINDOW, 0, 0, WidthScaled, HeightScaled, nullptr, nullptr, hInst, nullptr); if (hWindow == nullptr) { panicF("Failed to create application window!"); } ShowWindow(hWindow, nCmdShow); UpdateWindow(hWindow); } static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_KEYDOWN: if (wParam == VK_RETURN) { keys.showGrid = !keys.showGrid; } if (wParam == VK_SPACE) { keys.showLabels = !keys.showLabels; } return 0; case WM_MOUSEMOVE: { int mx = LOWORD(lParam); int my = HIWORD(lParam); // Clamp to window bounds: if (mx > WidthScaled) { mx = WidthScaled; } else if (mx < 0) { mx = 0; } if (my > HeightScaled) { my = HeightScaled; } else if (my < 0) { my = 0; } mouse.deltaX = mx - mouse.lastPosX; mouse.deltaY = my - mouse.lastPosY; mouse.lastPosX = mx; mouse.lastPosY = my; // Clamp between -/+ max delta: if (mouse.deltaX > Mouse::MaxDelta) { mouse.deltaX = Mouse::MaxDelta; } else if (mouse.deltaX < -Mouse::MaxDelta) { mouse.deltaX = -Mouse::MaxDelta; } if (mouse.deltaY > Mouse::MaxDelta) { mouse.deltaY = Mouse::MaxDelta; } else if (mouse.deltaY < -Mouse::MaxDelta) { mouse.deltaY = -Mouse::MaxDelta; } } return 0; default: break; } // switch return DefWindowProc(hWnd, message, wParam, lParam); } }; // Caching these for convenience const std::tuple Window::DpiXY = Window::GetDpiXY(); const int Window::WidthScaled = Window::GetDpiAdjustedX(WindowWidth); const int Window::HeightScaled = Window::GetDpiAdjustedY(WindowHeight); // ======================================================== // RenderWindowD3D11 // ======================================================== class RenderWindowD3D11 final : public Window { public: ComPtr swapChain; ComPtr d3dDevice; ComPtr deviceContext; ComPtr renderTargetView; std::function renderCallback; RenderWindowD3D11(HINSTANCE hInstance, int nCmdShow) : Window(hInstance, nCmdShow) { initD3D(); } void onRender() override { const float clearColor[] = {0.2f, 0.2f, 0.2f, 1.0f}; deviceContext->ClearRenderTargetView(renderTargetView.Get(), clearColor); if (renderCallback) { renderCallback(); } swapChain->Present(0, 0); } private: void initD3D() { UINT createDeviceFlags = 0; const UINT width = Window::WidthScaled; const UINT height = Window::HeightScaled; // If the project is in a debug build, enable debugging via SDK Layers with this flag. #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif // DEBUG // Acceptable driver types. const D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; const UINT numDriverTypes = ARRAYSIZE(driverTypes); // This array defines the ordering of feature levels that D3D should attempt to create. const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; const UINT numFeatureLevels = ARRAYSIZE(featureLevels); DXGI_SWAP_CHAIN_DESC sd = {0}; sd.BufferCount = 2; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = hWindow; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; HRESULT hr; D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; // Try to create the device and swap chain: for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; ++driverTypeIndex) { auto driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, swapChain.GetAddressOf(), d3dDevice.GetAddressOf(), &featureLevel, deviceContext.GetAddressOf()); if (hr == E_INVALIDARG) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &sd, swapChain.GetAddressOf(), d3dDevice.GetAddressOf(), &featureLevel, deviceContext.GetAddressOf()); } if (SUCCEEDED(hr)) { break; } } if (FAILED(hr)) { panicF("Failed to create D3D device or swap chain!"); } // Create a render target view for the framebuffer: ID3D11Texture2D * backBuffer = nullptr; hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer); if (FAILED(hr)) { panicF("Failed to get framebuffer from swap chain!"); } hr = d3dDevice->CreateRenderTargetView(backBuffer, nullptr, renderTargetView.GetAddressOf()); backBuffer->Release(); if (FAILED(hr)) { panicF("Failed to create RTV for framebuffer!"); } deviceContext->OMSetRenderTargets(1, renderTargetView.GetAddressOf(), nullptr); // Setup the viewport: D3D11_VIEWPORT vp; vp.Width = static_cast(width); vp.Height = static_cast(height); vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; deviceContext->RSSetViewports(1, &vp); } }; // ======================================================== // ShaderSetD3D11 // ======================================================== struct ShaderSetD3D11 final { using InputLayoutDesc = std::tuple; ComPtr vs; ComPtr ps; ComPtr vertexLayout; ShaderSetD3D11() = default; void loadFromFxFile(ID3D11Device * device, const wchar_t * filename, const char * vsEntry, const char * psEntry, const InputLayoutDesc & layout) { assert(filename != nullptr && filename[0] != L'\0'); assert(vsEntry != nullptr && vsEntry[0] != '\0'); assert(psEntry != nullptr && psEntry[0] != '\0'); ComPtr vsBlob; compileShaderFromFile(filename, vsEntry, "vs_4_0", vsBlob.GetAddressOf()); assert(vsBlob != nullptr); ComPtr psBlob; compileShaderFromFile(filename, psEntry, "ps_4_0", psBlob.GetAddressOf()); assert(psBlob != nullptr); HRESULT hr; // Create the vertex shader: hr = device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, vs.GetAddressOf()); if (FAILED(hr)) { panicF("Failed to create vertex shader '%s'", vsEntry); } // Create the pixel shader: hr = device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, ps.GetAddressOf()); if (FAILED(hr)) { panicF("Failed to create pixel shader '%s'", psEntry); } // Create vertex input layout: hr = device->CreateInputLayout(std::get<0>(layout), std::get<1>(layout), vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), vertexLayout.GetAddressOf()); if (FAILED(hr)) { panicF("Failed to create vertex layout!"); } } static void compileShaderFromFile(const wchar_t * fileName, const char * entryPoint, const char * shaderModel, ID3DBlob ** ppBlobOut) { UINT shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. // Setting this flag improves the shader debugging experience, but still allows // the shaders to be optimized and to run exactly the way they will run in // the release configuration. #if defined(DEBUG) || defined(_DEBUG) shaderFlags |= D3DCOMPILE_DEBUG; #endif // DEBUG ComPtr pErrorBlob; HRESULT hr = D3DCompileFromFile(fileName, nullptr, nullptr, entryPoint, shaderModel, shaderFlags, 0, ppBlobOut, pErrorBlob.GetAddressOf()); if (FAILED(hr)) { auto * details = (pErrorBlob ? static_cast(pErrorBlob->GetBufferPointer()) : ""); panicF("Failed to compile shader! Error info: %s", details); } } }; // ======================================================== // RenderInterfaceD3D11 // ======================================================== class RenderInterfaceD3D11 final : public dd::RenderInterface { public: RenderInterfaceD3D11(const ComPtr & pDevice, const ComPtr & pContext) : d3dDevice(pDevice) , deviceContext(pContext) { initShaders(); initBuffers(); } void setMvpMatrixPtr(const float * const mtx) { constantBufferData.mvpMatrix = DirectX::XMMATRIX(mtx); } void setCameraFrame(const Vector3 & up, const Vector3 & right, const Vector3 & origin) { camUp = up; camRight = right; camOrigin = origin; } // // dd::RenderInterface overrides: // void beginDraw() override { // Update and set the constant buffer for this frame deviceContext->UpdateSubresource(constantBuffer.Get(), 0, nullptr, &constantBufferData, 0, 0); deviceContext->VSSetConstantBuffers(0, 1, constantBuffer.GetAddressOf()); // Disable culling for the screen text deviceContext->RSSetState(rasterizerState.Get()); } void endDraw() override { // No work done here at the moment. } dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override { UINT numQualityLevels = 0; d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8_UNORM, 1, &numQualityLevels); D3D11_TEXTURE2D_DESC tex2dDesc = {}; tex2dDesc.Usage = D3D11_USAGE_DEFAULT; tex2dDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; tex2dDesc.Format = DXGI_FORMAT_R8_UNORM; tex2dDesc.Width = width; tex2dDesc.Height = height; tex2dDesc.MipLevels = 1; tex2dDesc.ArraySize = 1; tex2dDesc.SampleDesc.Count = 1; tex2dDesc.SampleDesc.Quality = numQualityLevels - 1; D3D11_SAMPLER_DESC samplerDesc = {}; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; samplerDesc.MaxAnisotropy = 1; samplerDesc.MipLODBias = 0.0f; samplerDesc.MinLOD = 0.0f; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; D3D11_SUBRESOURCE_DATA initData = {}; initData.pSysMem = pixels; initData.SysMemPitch = width; auto * texImpl = new TextureImpl{}; if (FAILED(d3dDevice->CreateTexture2D(&tex2dDesc, &initData, &texImpl->d3dTexPtr))) { errorF("CreateTexture2D failed!"); destroyGlyphTexture(texImpl); return nullptr; } if (FAILED(d3dDevice->CreateShaderResourceView(texImpl->d3dTexPtr, nullptr, &texImpl->d3dTexSRV))) { errorF("CreateShaderResourceView failed!"); destroyGlyphTexture(texImpl); return nullptr; } if (FAILED(d3dDevice->CreateSamplerState(&samplerDesc, &texImpl->d3dSampler))) { errorF("CreateSamplerState failed!"); destroyGlyphTexture(texImpl); return nullptr; } return static_cast(texImpl); } void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override { auto * texImpl = static_cast(glyphTex); if (texImpl) { if (texImpl->d3dSampler) { texImpl->d3dSampler->Release(); } if (texImpl->d3dTexSRV) { texImpl->d3dTexSRV->Release(); } if (texImpl->d3dTexPtr) { texImpl->d3dTexPtr->Release(); } delete texImpl; } } void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override { assert(glyphs != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); auto * texImpl = static_cast(glyphTex); assert(texImpl != nullptr); // Map the vertex buffer: D3D11_MAPPED_SUBRESOURCE mapInfo; if (FAILED(deviceContext->Map(glyphVertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo))) { panicF("Failed to map vertex buffer!"); } // Copy into mapped buffer: auto * verts = static_cast(mapInfo.pData); for (int v = 0; v < count; ++v) { verts[v].pos.x = glyphs[v].glyph.x; verts[v].pos.y = glyphs[v].glyph.y; verts[v].pos.z = 0.0f; verts[v].pos.w = 1.0f; verts[v].uv.x = glyphs[v].glyph.u; verts[v].uv.y = glyphs[v].glyph.v; verts[v].uv.z = 0.0f; verts[v].uv.w = 0.0f; verts[v].color.x = glyphs[v].glyph.r; verts[v].color.y = glyphs[v].glyph.g; verts[v].color.z = glyphs[v].glyph.b; verts[v].color.w = 1.0f; } // Unmap and draw: deviceContext->Unmap(glyphVertexBuffer.Get(), 0); // Bind texture & sampler (t0, s0): deviceContext->PSSetShaderResources(0, 1, &texImpl->d3dTexSRV); deviceContext->PSSetSamplers(0, 1, &texImpl->d3dSampler); const float blendFactor[] = {1.0f, 1.0f, 1.0f, 1.0f}; deviceContext->OMSetBlendState(blendStateText.Get(), blendFactor, 0xFFFFFFFF); // Draw with the current buffer: drawHelper(count, glyphShaders, glyphVertexBuffer.Get(), D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Restore default blend state. deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF); } void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override { (void)depthEnabled; // TODO: not implemented yet - not required by this sample // Emulating points as billboarded quads, so each point will use 6 vertexes. // D3D11 doesn't support "point sprites" like OpenGL (gl_PointSize). const int maxVerts = DEBUG_DRAW_VERTEX_BUFFER_SIZE / 6; // OpenGL point size scaling produces gigantic points with the billboarding fallback. // This is some arbitrary down-scaling factor to more or less match the OpenGL samples. const float D3DPointSpriteScalingFactor = 0.01f; assert(points != nullptr); assert(count > 0 && count <= maxVerts); // Map the vertex buffer: D3D11_MAPPED_SUBRESOURCE mapInfo; if (FAILED(deviceContext->Map(pointVertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo))) { panicF("Failed to map vertex buffer!"); } const int numVerts = count * 6; const int indexes[6] = {0, 1, 2, 2, 3, 0}; int v = 0; auto * verts = static_cast(mapInfo.pData); // Expand each point into a quad: for (int p = 0; p < count; ++p) { const float ptSize = points[p].point.size * D3DPointSpriteScalingFactor; const Vector3 halfWidth = (ptSize * 0.5f) * camRight; // X const Vector3 halfHeigh = (ptSize * 0.5f) * camUp; // Y const Vector3 origin = Vector3{ points[p].point.x, points[p].point.y, points[p].point.z }; Vector3 corners[4]; corners[0] = origin + halfWidth + halfHeigh; corners[1] = origin - halfWidth + halfHeigh; corners[2] = origin - halfWidth - halfHeigh; corners[3] = origin + halfWidth - halfHeigh; for (int i : indexes) { verts[v].pos.x = corners[i].getX(); verts[v].pos.y = corners[i].getY(); verts[v].pos.z = corners[i].getZ(); verts[v].pos.w = 1.0f; verts[v].color.x = points[p].point.r; verts[v].color.y = points[p].point.g; verts[v].color.z = points[p].point.b; verts[v].color.w = 1.0f; ++v; } } assert(v == numVerts); // Unmap and draw: deviceContext->Unmap(pointVertexBuffer.Get(), 0); // Draw with the current buffer: drawHelper(numVerts, pointShaders, pointVertexBuffer.Get(), D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); } void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override { (void)depthEnabled; // TODO: not implemented yet - not required by this sample assert(lines != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); // Map the vertex buffer: D3D11_MAPPED_SUBRESOURCE mapInfo; if (FAILED(deviceContext->Map(lineVertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo))) { panicF("Failed to map vertex buffer!"); } // Copy into mapped buffer: auto * verts = static_cast(mapInfo.pData); for (int v = 0; v < count; ++v) { verts[v].pos.x = lines[v].line.x; verts[v].pos.y = lines[v].line.y; verts[v].pos.z = lines[v].line.z; verts[v].pos.w = 1.0f; verts[v].color.x = lines[v].line.r; verts[v].color.y = lines[v].line.g; verts[v].color.z = lines[v].line.b; verts[v].color.w = 1.0f; } // Unmap and draw: deviceContext->Unmap(lineVertexBuffer.Get(), 0); // Draw with the current buffer: drawHelper(count, lineShaders, lineVertexBuffer.Get(), D3D11_PRIMITIVE_TOPOLOGY_LINELIST); } private: // // Local types: // struct ConstantBufferData { DirectX::XMMATRIX mvpMatrix = DirectX::XMMatrixIdentity(); DirectX::XMFLOAT4 screenDimensions = {float(WindowWidth), float(WindowHeight), 0.0f, 0.0f}; }; struct Vertex { DirectX::XMFLOAT4A pos; // 3D position DirectX::XMFLOAT4A uv; // Texture coordinates DirectX::XMFLOAT4A color; // RGBA float }; struct TextureImpl : public dd::OpaqueTextureType { ID3D11Texture2D * d3dTexPtr = nullptr; ID3D11ShaderResourceView * d3dTexSRV = nullptr; ID3D11SamplerState * d3dSampler = nullptr; }; // // Members: // ComPtr d3dDevice; ComPtr deviceContext; ComPtr rasterizerState; ComPtr blendStateText; ComPtr constantBuffer; ConstantBufferData constantBufferData; ComPtr lineVertexBuffer; ShaderSetD3D11 lineShaders; ComPtr pointVertexBuffer; ShaderSetD3D11 pointShaders; ComPtr glyphVertexBuffer; ShaderSetD3D11 glyphShaders; // Camera vectors for the emulated point sprites Vector3 camUp = Vector3{0.0f}; Vector3 camRight = Vector3{0.0f}; Vector3 camOrigin = Vector3{0.0f}; void initShaders() { // Same vertex format used by all buffers to simplify things. const D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; const ShaderSetD3D11::InputLayoutDesc inputDesc{ layout, int(ARRAYSIZE(layout)) }; // 3D lines shader: lineShaders.loadFromFxFile(d3dDevice.Get(), L"ddShader.fx", "VS_LinePoint", "PS_LinePoint", inputDesc); // 3D points shader: pointShaders.loadFromFxFile(d3dDevice.Get(), L"ddShader.fx", "VS_LinePoint", "PS_LinePoint", inputDesc); // 2D glyphs shader: glyphShaders.loadFromFxFile(d3dDevice.Get(), L"ddShader.fx", "VS_TextGlyph", "PS_TextGlyph", inputDesc); // Rasterizer state for the screen text: D3D11_RASTERIZER_DESC rsDesc = {}; rsDesc.FillMode = D3D11_FILL_SOLID; rsDesc.CullMode = D3D11_CULL_NONE; rsDesc.FrontCounterClockwise = true; rsDesc.DepthBias = 0; rsDesc.DepthBiasClamp = 0.0f; rsDesc.SlopeScaledDepthBias = 0.0f; rsDesc.DepthClipEnable = false; rsDesc.ScissorEnable = false; rsDesc.MultisampleEnable = false; rsDesc.AntialiasedLineEnable = false; if (FAILED(d3dDevice->CreateRasterizerState(&rsDesc, rasterizerState.GetAddressOf()))) { errorF("CreateRasterizerState failed!"); } // Blend state for the screen text: D3D11_BLEND_DESC bsDesc = {}; bsDesc.RenderTarget[0].BlendEnable = true; bsDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; bsDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; bsDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; bsDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; bsDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bsDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; bsDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; if (FAILED(d3dDevice->CreateBlendState(&bsDesc, blendStateText.GetAddressOf()))) { errorF("CreateBlendState failed!"); } } void initBuffers() { D3D11_BUFFER_DESC bd; // Create the shared constant buffer: bd = {}; bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(ConstantBufferData); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; if (FAILED(d3dDevice->CreateBuffer(&bd, nullptr, constantBuffer.GetAddressOf()))) { panicF("Failed to create shader constant buffer!"); } // Create the vertex buffers for lines/points/glyphs: bd = {}; bd.Usage = D3D11_USAGE_DYNAMIC; bd.ByteWidth = sizeof(Vertex) * DEBUG_DRAW_VERTEX_BUFFER_SIZE; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; if (FAILED(d3dDevice->CreateBuffer(&bd, nullptr, lineVertexBuffer.GetAddressOf()))) { panicF("Failed to create lines vertex buffer!"); } if (FAILED(d3dDevice->CreateBuffer(&bd, nullptr, pointVertexBuffer.GetAddressOf()))) { panicF("Failed to create points vertex buffer!"); } if (FAILED(d3dDevice->CreateBuffer(&bd, nullptr, glyphVertexBuffer.GetAddressOf()))) { panicF("Failed to create glyphs vertex buffer!"); } } void drawHelper(const int numVerts, const ShaderSetD3D11 & ss, ID3D11Buffer * vb, const D3D11_PRIMITIVE_TOPOLOGY topology) { const UINT offset = 0; const UINT stride = sizeof(Vertex); deviceContext->IASetVertexBuffers(0, 1, &vb, &stride, &offset); deviceContext->IASetPrimitiveTopology(topology); deviceContext->IASetInputLayout(ss.vertexLayout.Get()); deviceContext->VSSetShader(ss.vs.Get(), nullptr, 0); deviceContext->PSSetShader(ss.ps.Get(), nullptr, 0); deviceContext->Draw(numVerts, 0); } }; // ======================================================== // Sample drawing // ======================================================== static void drawGrid(dd::ContextHandle ctx) { if (!keys.showGrid) { return; } // Grid from -50 to +50 in both X & Z dd::xzSquareGrid(ctx, -50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); } static void drawLabel(dd::ContextHandle ctx, ddVec3_In pos, const char * name) { if (!keys.showLabels) { return; } // Only draw labels inside the camera frustum. if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2])) { const ddVec3 textColor = { 0.8f, 0.8f, 1.0f }; dd::projectedText(ctx, name, pos, textColor, toFloatPtr(camera.vpMatrix), 0, 0, WindowWidth, WindowHeight, 0.5f); } } static void drawMiscObjects(dd::ContextHandle ctx) { // Start a row of objects at this position: ddVec3 origin = { -15.0f, 0.0f, 0.0f }; // Box with a point at it's center: drawLabel(ctx, origin, "box"); dd::box(ctx, origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f); dd::point(ctx, origin, dd::colors::White, 15.0f); origin[0] += 3.0f; // Sphere with a point at its center drawLabel(ctx, origin, "sphere"); dd::sphere(ctx, origin, dd::colors::Red, 1.0f); dd::point(ctx, origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Two cones, one open and one closed: const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f }; origin[1] -= 1.0f; drawLabel(ctx, origin, "cone (open)"); dd::cone(ctx, origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f); dd::point(ctx, origin, dd::colors::White, 15.0f); origin[0] += 4.0f; drawLabel(ctx, origin, "cone (closed)"); dd::cone(ctx, origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f); dd::point(ctx, origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Axis-aligned bounding box: const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f }; const ddVec3 bbMaxs = { 1.0f, 2.2f, 1.0f }; const ddVec3 bbCenter = { (bbMins[0] + bbMaxs[0]) * 0.5f, (bbMins[1] + bbMaxs[1]) * 0.5f, (bbMins[2] + bbMaxs[2]) * 0.5f }; drawLabel(ctx, origin, "AABB"); dd::aabb(ctx, bbMins, bbMaxs, dd::colors::Orange); dd::point(ctx, bbCenter, dd::colors::White, 15.0f); // Move along the Z for another row: origin[0] = -15.0f; origin[2] += 5.0f; // A big arrow pointing up: const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] }; const ddVec3 arrowTo = { origin[0], origin[1] + 5.0f, origin[2] }; drawLabel(ctx, arrowFrom, "arrow"); dd::arrow(ctx, arrowFrom, arrowTo, dd::colors::Magenta, 1.0f); dd::point(ctx, arrowFrom, dd::colors::White, 15.0f); dd::point(ctx, arrowTo, dd::colors::White, 15.0f); origin[0] += 4.0f; // Plane with normal vector: const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f }; drawLabel(ctx, origin, "plane"); dd::plane(ctx, origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f); dd::point(ctx, origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Circle on the Y plane: drawLabel(ctx, origin, "circle"); dd::circle(ctx, origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f); dd::point(ctx, origin, dd::colors::White, 15.0f); origin[0] += 3.2f; // Tangent basis vectors: const ddVec3 normal = { 0.0f, 1.0f, 0.0f }; const ddVec3 tangent = { 1.0f, 0.0f, 0.0f }; const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f }; origin[1] += 0.1f; drawLabel(ctx, origin, "tangent basis"); dd::tangentBasis(ctx, origin, normal, tangent, bitangent, 2.5f); dd::point(ctx, origin, dd::colors::White, 15.0f); // And a set of intersecting axes: origin[0] += 4.0f; origin[1] += 1.0f; drawLabel(ctx, origin, "cross"); dd::cross(ctx, origin, 2.0f); dd::point(ctx, origin, dd::colors::White, 15.0f); } static void drawFrustum(dd::ContextHandle ctx) { const ddVec3 color = { 0.8f, 0.3f, 1.0f }; const ddVec3 origin = { -8.0f, 0.5f, 14.0f }; drawLabel(ctx, origin, "frustum + axes"); // The frustum will depict a fake camera: const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f); const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis()); const Matrix4 clip = inverse(proj * view); dd::frustum(ctx, toFloatPtr(clip), color); // A white dot at the eye position: dd::point(ctx, origin, dd::colors::White, 15.0f); // A set of arrows at the camera's origin/eye: const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f)); dd::axisTriad(ctx, toFloatPtr(transform), 0.3f, 2.0f); } static void drawText(dd::ContextHandle ctx) { // HUD text: const ddVec3 textColor = { 1.0f, 1.0f, 1.0f }; const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f }; dd::screenText(ctx, "Welcome to the D3D11 Debug Draw demo.\n\n" "[SPACE] to toggle labels on/off\n" "[RETURN] to toggle grid on/off", textPos2D, textColor, 0.55f); } static void inputUpdate(const Window & win) { if (GetForegroundWindow() != win.hWindow) { return; // Don't update if window out of focus. } auto testKeyPressed = [](int key) -> bool { return (GetKeyState(key) & 0x80) > 0; }; // Keyboard movement keys: keys.wDown = testKeyPressed('W') || testKeyPressed(VK_UP); keys.sDown = testKeyPressed('S') || testKeyPressed(VK_DOWN); keys.aDown = testKeyPressed('A') || testKeyPressed(VK_LEFT); keys.dDown = testKeyPressed('D') || testKeyPressed(VK_RIGHT); // Mouse buttons: mouse.leftButtonDown = testKeyPressed(VK_LBUTTON); mouse.rightButtonDown = testKeyPressed(VK_RBUTTON); } // ======================================================== // WinMain // ======================================================== int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow) { printDDBuildConfig(); RenderWindowD3D11 renderWindow(hInstance, nCmdShow); RenderInterfaceD3D11 renderInterface(renderWindow.d3dDevice, renderWindow.deviceContext); dd::ContextHandle ddContext = nullptr; dd::initialize(&ddContext, &renderInterface); renderWindow.renderCallback = [ddContext, &renderWindow, &renderInterface]() { const double t0s = getTimeSeconds(); inputUpdate(renderWindow); camera.checkKeyboardMovement(); camera.checkMouseRotation(); camera.updateMatrices(); const Matrix4 mvpMatrix = transpose(camera.vpMatrix); renderInterface.setMvpMatrixPtr(toFloatPtr(mvpMatrix)); renderInterface.setCameraFrame(camera.up, camera.right, camera.eye); // Call some DD functions to add stuff to the debug draw queues: drawGrid(ddContext); drawMiscObjects(ddContext); drawFrustum(ddContext); drawText(ddContext); // Flush the draw queues: dd::flush(ddContext); const double t1s = getTimeSeconds(); deltaTime.seconds = static_cast(t1s - t0s); deltaTime.milliseconds = static_cast(deltaTime.seconds * 1000.0); }; renderWindow.runMessageLoop(); dd::shutdown(ddContext); return 0; } // ======================================================== ================================================ FILE: samples/sample_gl_core.cpp ================================================ // ================================================================================================ // -*- C++ -*- // File: sample_gl_core.cpp // Author: Guilherme R. Lampert // Brief: Debug Draw usage sample with Core Profile OpenGL (version 3+) // // This software is in the public domain. Where that dedication is not recognized, // you are granted a perpetual, irrevocable license to copy, distribute, and modify // this file as you see fit. // ================================================================================================ #define DEBUG_DRAW_IMPLEMENTATION #include "debug_draw.hpp" // Debug Draw API. Notice that we need the DEBUG_DRAW_IMPLEMENTATION macro here! #include // An OpenGL extension wrangler (https://github.com/skaslev/gl3w). #include "samples_common.hpp" // Common code shared by the samples (camera, input, etc). using namespace ddSamplesCommon; // ======================================================== // Debug Draw RenderInterface for Core OpenGL: // ======================================================== class DDRenderInterfaceCoreGL final : public dd::RenderInterface { public: // // dd::RenderInterface overrides: // void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override { assert(points != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); glBindVertexArray(linePointVAO); glUseProgram(linePointProgram); glUniformMatrix4fv(linePointProgram_MvpMatrixLocation, 1, GL_FALSE, toFloatPtr(mvpMatrix)); if (depthEnabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick... glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), points); // Issue the draw call: glDrawArrays(GL_POINTS, 0, count); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); checkGLError(__FILE__, __LINE__); } void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override { assert(lines != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); glBindVertexArray(linePointVAO); glUseProgram(linePointProgram); glUniformMatrix4fv(linePointProgram_MvpMatrixLocation, 1, GL_FALSE, toFloatPtr(mvpMatrix)); if (depthEnabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick... glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), lines); // Issue the draw call: glDrawArrays(GL_LINES, 0, count); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); checkGLError(__FILE__, __LINE__); } void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override { assert(glyphs != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); glBindVertexArray(textVAO); glUseProgram(textProgram); // These doesn't have to be reset every draw call, I'm just being lazy ;) glUniform1i(textProgram_GlyphTextureLocation, 0); glUniform2f(textProgram_ScreenDimensions, static_cast(WindowWidth), static_cast(WindowHeight)); if (glyphTex != nullptr) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, handleToGL(glyphTex)); } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); glBindBuffer(GL_ARRAY_BUFFER, textVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), glyphs); glDrawArrays(GL_TRIANGLES, 0, count); // Issue the draw call glDisable(GL_BLEND); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); checkGLError(__FILE__, __LINE__); } dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override { assert(width > 0 && height > 0); assert(pixels != nullptr); GLuint textureId = 0; glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); checkGLError(__FILE__, __LINE__); return GLToHandle(textureId); } void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override { if (glyphTex == nullptr) { return; } const GLuint textureId = handleToGL(glyphTex); glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &textureId); } // These two can also be implemented to perform GL render // state setup/cleanup, but we don't use them in this sample. //void beginDraw() override { } //void endDraw() override { } // // Local methods: // DDRenderInterfaceCoreGL() : mvpMatrix(Matrix4::identity()) , linePointProgram(0) , linePointProgram_MvpMatrixLocation(-1) , textProgram(0) , textProgram_GlyphTextureLocation(-1) , textProgram_ScreenDimensions(-1) , linePointVAO(0) , linePointVBO(0) , textVAO(0) , textVBO(0) { std::printf("\n"); std::printf("GL_VENDOR : %s\n", glGetString(GL_VENDOR)); std::printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER)); std::printf("GL_VERSION : %s\n", glGetString(GL_VERSION)); std::printf("GLSL_VERSION : %s\n\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); std::printf("DDRenderInterfaceCoreGL initializing ...\n"); // Default OpenGL states: glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); // This has to be enabled since the point drawing shader will use gl_PointSize. glEnable(GL_PROGRAM_POINT_SIZE); setupShaderPrograms(); setupVertexBuffers(); std::printf("DDRenderInterfaceCoreGL ready!\n\n"); } ~DDRenderInterfaceCoreGL() { glDeleteProgram(linePointProgram); glDeleteProgram(textProgram); glDeleteVertexArrays(1, &linePointVAO); glDeleteBuffers(1, &linePointVBO); glDeleteVertexArrays(1, &textVAO); glDeleteBuffers(1, &textVBO); } void setupShaderPrograms() { std::printf("> DDRenderInterfaceCoreGL::setupShaderPrograms()\n"); // // Line/point drawing shader: // { GLuint linePointVS = glCreateShader(GL_VERTEX_SHADER); glShaderSource(linePointVS, 1, &linePointVertShaderSrc, nullptr); compileShader(linePointVS); GLint linePointFS = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(linePointFS, 1, &linePointFragShaderSrc, nullptr); compileShader(linePointFS); linePointProgram = glCreateProgram(); glAttachShader(linePointProgram, linePointVS); glAttachShader(linePointProgram, linePointFS); glBindAttribLocation(linePointProgram, 0, "in_Position"); glBindAttribLocation(linePointProgram, 1, "in_ColorPointSize"); linkProgram(linePointProgram); linePointProgram_MvpMatrixLocation = glGetUniformLocation(linePointProgram, "u_MvpMatrix"); if (linePointProgram_MvpMatrixLocation < 0) { errorF("Unable to get u_MvpMatrix uniform location!"); } checkGLError(__FILE__, __LINE__); } // // Text rendering shader: // { GLuint textVS = glCreateShader(GL_VERTEX_SHADER); glShaderSource(textVS, 1, &textVertShaderSrc, nullptr); compileShader(textVS); GLint textFS = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(textFS, 1, &textFragShaderSrc, nullptr); compileShader(textFS); textProgram = glCreateProgram(); glAttachShader(textProgram, textVS); glAttachShader(textProgram, textFS); glBindAttribLocation(textProgram, 0, "in_Position"); glBindAttribLocation(textProgram, 1, "in_TexCoords"); glBindAttribLocation(textProgram, 2, "in_Color"); linkProgram(textProgram); textProgram_GlyphTextureLocation = glGetUniformLocation(textProgram, "u_glyphTexture"); if (textProgram_GlyphTextureLocation < 0) { errorF("Unable to get u_glyphTexture uniform location!"); } textProgram_ScreenDimensions = glGetUniformLocation(textProgram, "u_screenDimensions"); if (textProgram_ScreenDimensions < 0) { errorF("Unable to get u_screenDimensions uniform location!"); } checkGLError(__FILE__, __LINE__); } } void setupVertexBuffers() { std::printf("> DDRenderInterfaceCoreGL::setupVertexBuffers()\n"); // // Lines/points vertex buffer: // { glGenVertexArrays(1, &linePointVAO); glGenBuffers(1, &linePointVBO); checkGLError(__FILE__, __LINE__); glBindVertexArray(linePointVAO); glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); // RenderInterface will never be called with a batch larger than // DEBUG_DRAW_VERTEX_BUFFER_SIZE vertexes, so we can allocate the same amount here. glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW); checkGLError(__FILE__, __LINE__); // Set the vertex format expected by 3D points and lines: std::size_t offset = 0; glEnableVertexAttribArray(0); // in_Position (vec3) glVertexAttribPointer( /* index = */ 0, /* size = */ 3, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 3; glEnableVertexAttribArray(1); // in_ColorPointSize (vec4) glVertexAttribPointer( /* index = */ 1, /* size = */ 4, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); checkGLError(__FILE__, __LINE__); // VAOs can be a pain in the neck if left enabled... glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); } // // Text rendering vertex buffer: // { glGenVertexArrays(1, &textVAO); glGenBuffers(1, &textVBO); checkGLError(__FILE__, __LINE__); glBindVertexArray(textVAO); glBindBuffer(GL_ARRAY_BUFFER, textVBO); // NOTE: A more optimized implementation might consider combining // both the lines/points and text buffers to save some memory! glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW); checkGLError(__FILE__, __LINE__); // Set the vertex format expected by the 2D text: std::size_t offset = 0; glEnableVertexAttribArray(0); // in_Position (vec2) glVertexAttribPointer( /* index = */ 0, /* size = */ 2, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 2; glEnableVertexAttribArray(1); // in_TexCoords (vec2) glVertexAttribPointer( /* index = */ 1, /* size = */ 2, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 2; glEnableVertexAttribArray(2); // in_Color (vec4) glVertexAttribPointer( /* index = */ 2, /* size = */ 4, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); checkGLError(__FILE__, __LINE__); // Ditto. glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); } } static GLuint handleToGL(dd::GlyphTextureHandle handle) { const std::size_t temp = reinterpret_cast(handle); return static_cast(temp); } static dd::GlyphTextureHandle GLToHandle(const GLuint id) { const std::size_t temp = static_cast(id); return reinterpret_cast(temp); } static void checkGLError(const char * file, const int line) { GLenum err; while ((err = glGetError()) != GL_NO_ERROR) { errorF("%s(%d) : GL_CORE_ERROR=0x%X - %s", file, line, err, errorToString(err)); } } static void compileShader(const GLuint shader) { glCompileShader(shader); checkGLError(__FILE__, __LINE__); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); checkGLError(__FILE__, __LINE__); if (status == GL_FALSE) { GLchar strInfoLog[1024] = {0}; glGetShaderInfoLog(shader, sizeof(strInfoLog) - 1, nullptr, strInfoLog); errorF("\n>>> Shader compiler errors:\n%s", strInfoLog); } } static void linkProgram(const GLuint program) { glLinkProgram(program); checkGLError(__FILE__, __LINE__); GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); checkGLError(__FILE__, __LINE__); if (status == GL_FALSE) { GLchar strInfoLog[1024] = {0}; glGetProgramInfoLog(program, sizeof(strInfoLog) - 1, nullptr, strInfoLog); errorF("\n>>> Program linker errors:\n%s", strInfoLog); } } // The "model-view-projection" matrix for the scene. // In this demo, it consists of the camera's view and projection matrices only. Matrix4 mvpMatrix; private: GLuint linePointProgram; GLint linePointProgram_MvpMatrixLocation; GLuint textProgram; GLint textProgram_GlyphTextureLocation; GLint textProgram_ScreenDimensions; GLuint linePointVAO; GLuint linePointVBO; GLuint textVAO; GLuint textVBO; static const char * linePointVertShaderSrc; static const char * linePointFragShaderSrc; static const char * textVertShaderSrc; static const char * textFragShaderSrc; }; // class DDRenderInterfaceCoreGL // ======================================================== // Minimal shaders we need for the debug primitives: // ======================================================== const char * DDRenderInterfaceCoreGL::linePointVertShaderSrc = "\n" "#version 150\n" "\n" "in vec3 in_Position;\n" "in vec4 in_ColorPointSize;\n" "\n" "out vec4 v_Color;\n" "uniform mat4 u_MvpMatrix;\n" "\n" "void main()\n" "{\n" " gl_Position = u_MvpMatrix * vec4(in_Position, 1.0);\n" " gl_PointSize = in_ColorPointSize.w;\n" " v_Color = vec4(in_ColorPointSize.xyz, 1.0);\n" "}\n"; const char * DDRenderInterfaceCoreGL::linePointFragShaderSrc = "\n" "#version 150\n" "\n" "in vec4 v_Color;\n" "out vec4 out_FragColor;\n" "\n" "void main()\n" "{\n" " out_FragColor = v_Color;\n" "}\n"; const char * DDRenderInterfaceCoreGL::textVertShaderSrc = "\n" "#version 150\n" "\n" "in vec2 in_Position;\n" "in vec2 in_TexCoords;\n" "in vec3 in_Color;\n" "\n" "uniform vec2 u_screenDimensions;\n" "\n" "out vec2 v_TexCoords;\n" "out vec4 v_Color;\n" "\n" "void main()\n" "{\n" " // Map to normalized clip coordinates:\n" " float x = ((2.0 * (in_Position.x - 0.5)) / u_screenDimensions.x) - 1.0;\n" " float y = 1.0 - ((2.0 * (in_Position.y - 0.5)) / u_screenDimensions.y);\n" "\n" " gl_Position = vec4(x, y, 0.0, 1.0);\n" " v_TexCoords = in_TexCoords;\n" " v_Color = vec4(in_Color, 1.0);\n" "}\n"; const char * DDRenderInterfaceCoreGL::textFragShaderSrc = "\n" "#version 150\n" "\n" "in vec2 v_TexCoords;\n" "in vec4 v_Color;\n" "\n" "uniform sampler2D u_glyphTexture;\n" "out vec4 out_FragColor;\n" "\n" "void main()\n" "{\n" " out_FragColor = v_Color;\n" " out_FragColor.a = texture(u_glyphTexture, v_TexCoords).r;\n" "}\n"; // ======================================================== // GLFW / window management / sample drawing: // ======================================================== static void drawGrid() { if (!keys.showGrid) { return; } dd::xzSquareGrid(-50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); // Grid from -50 to +50 in both X & Z } static void drawLabel(ddVec3_In pos, const char * name) { if (!keys.showLabels) { return; } // Only draw labels inside the camera frustum. if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2])) { const ddVec3 textColor = { 0.8f, 0.8f, 1.0f }; dd::projectedText(name, pos, textColor, toFloatPtr(camera.vpMatrix), 0, 0, WindowWidth, WindowHeight, 0.5f); } } static void drawMiscObjects() { // Start a row of objects at this position: ddVec3 origin = { -15.0f, 0.0f, 0.0f }; // Box with a point at it's center: drawLabel(origin, "box"); dd::box(origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 3.0f; // Sphere with a point at its center drawLabel(origin, "sphere"); dd::sphere(origin, dd::colors::Red, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Two cones, one open and one closed: const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f }; origin[1] -= 1.0f; drawLabel(origin, "cone (open)"); dd::cone(origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; drawLabel(origin, "cone (closed)"); dd::cone(origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Axis-aligned bounding box: const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f }; const ddVec3 bbMaxs = { 1.0f, 2.2f, 1.0f }; const ddVec3 bbCenter = { (bbMins[0] + bbMaxs[0]) * 0.5f, (bbMins[1] + bbMaxs[1]) * 0.5f, (bbMins[2] + bbMaxs[2]) * 0.5f }; drawLabel(origin, "AABB"); dd::aabb(bbMins, bbMaxs, dd::colors::Orange); dd::point(bbCenter, dd::colors::White, 15.0f); // Move along the Z for another row: origin[0] = -15.0f; origin[2] += 5.0f; // A big arrow pointing up: const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] }; const ddVec3 arrowTo = { origin[0], origin[1] + 5.0f, origin[2] }; drawLabel(arrowFrom, "arrow"); dd::arrow(arrowFrom, arrowTo, dd::colors::Magenta, 1.0f); dd::point(arrowFrom, dd::colors::White, 15.0f); dd::point(arrowTo, dd::colors::White, 15.0f); origin[0] += 4.0f; // Plane with normal vector: const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f }; drawLabel(origin, "plane"); dd::plane(origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Circle on the Y plane: drawLabel(origin, "circle"); dd::circle(origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 3.2f; // Tangent basis vectors: const ddVec3 normal = { 0.0f, 1.0f, 0.0f }; const ddVec3 tangent = { 1.0f, 0.0f, 0.0f }; const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f }; origin[1] += 0.1f; drawLabel(origin, "tangent basis"); dd::tangentBasis(origin, normal, tangent, bitangent, 2.5f); dd::point(origin, dd::colors::White, 15.0f); // And a set of intersecting axes: origin[0] += 4.0f; origin[1] += 1.0f; drawLabel(origin, "cross"); dd::cross(origin, 2.0f); dd::point(origin, dd::colors::White, 15.0f); } static void drawFrustum() { const ddVec3 color = { 0.8f, 0.3f, 1.0f }; const ddVec3 origin = { -8.0f, 0.5f, 14.0f }; drawLabel(origin, "frustum + axes"); // The frustum will depict a fake camera: const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f); const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis()); const Matrix4 clip = inverse(proj * view); dd::frustum(toFloatPtr(clip), color); // A white dot at the eye position: dd::point(origin, dd::colors::White, 15.0f); // A set of arrows at the camera's origin/eye: const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f)); dd::axisTriad(toFloatPtr(transform), 0.3f, 2.0f); } static void drawText() { // HUD text: const ddVec3 textColor = { 1.0f, 1.0f, 1.0f }; const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f }; dd::screenText("Welcome to the Core OpenGL Debug Draw demo.\n\n" "[SPACE] to toggle labels on/off\n" "[RETURN] to toggle grid on/off", textPos2D, textColor, 0.55f); } static void sampleAppDraw(DDRenderInterfaceCoreGL & ddRenderIfaceGL) { // Camera input update (the 'camera' object is declared in samples_common.hpp): camera.checkKeyboardMovement(); camera.checkMouseRotation(); camera.updateMatrices(); // Send the camera matrix to the shaders: ddRenderIfaceGL.mvpMatrix = camera.vpMatrix; glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Call some DD functions to add stuff to the debug draw queues: drawGrid(); drawMiscObjects(); drawFrustum(); drawText(); // Drawing only really happens now (here's where RenderInterface gets called). dd::flush(getTimeMilliseconds()); } static void sampleAppStart() { printDDBuildConfig(); if (!glfwInit()) { errorF("Failed to initialize GLFW!"); return; } // Things we need for the window / GL render context: glfwWindowHint(GLFW_RESIZABLE, false); glfwWindowHint(GLFW_DEPTH_BITS, 32); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); GLFWwindow * window = glfwCreateWindow(WindowWidth, WindowHeight, "Debug Draw Sample - Core OpenGL", nullptr, nullptr); if (!window) { errorF("Failed to create GLFW window!"); return; } glfwMakeContextCurrent(window); if (!gl3wInit()) { errorF("Failed to initialize GL3W extension library!"); return; } if (!gl3wIsSupported(3, 2)) { errorF("This sample application requires at least OpenGL version 3.2 to run!"); return; } // From samples_common.hpp initInput(window); // Set up the Debug Draw: DDRenderInterfaceCoreGL ddRenderIfaceGL; dd::initialize(&ddRenderIfaceGL); // Loop until the user closes the window: while (!glfwWindowShouldClose(window)) { const double t0s = glfwGetTime(); sampleAppDraw(ddRenderIfaceGL); glfwSwapBuffers(window); glfwPollEvents(); const double t1s = glfwGetTime(); deltaTime.seconds = static_cast(t1s - t0s); deltaTime.milliseconds = static_cast(deltaTime.seconds * 1000.0); } dd::shutdown(); } // ======================================================== // main(): // ======================================================== int main() { sampleAppStart(); gl3wShutdown(); glfwTerminate(); } ================================================ FILE: samples/sample_gl_core_multithreaded_explicit.cpp ================================================ // ================================================================================================ // -*- C++ -*- // File: sample_gl_core_multithreaded_explicit.cpp // Author: Guilherme R. Lampert // Brief: Debug Draw usage sample with Core Profile OpenGL and separate rendering thread. // Demonstrates the use of DEBUG_DRAW_EXPLICIT_CONTEXT with threads/async calls // and multiple contexts. // // This software is in the public domain. Where that dedication is not recognized, // you are granted a perpetual, irrevocable license to copy, distribute, and modify // this file as you see fit. // ================================================================================================ #define DEBUG_DRAW_IMPLEMENTATION #define DEBUG_DRAW_EXPLICIT_CONTEXT #include "debug_draw.hpp" // Debug Draw API. Notice that we need the DEBUG_DRAW_IMPLEMENTATION macro here! #include // An OpenGL extension wrangler (https://github.com/skaslev/gl3w). #include "samples_common.hpp" // Common code shared by the samples (camera, input, etc). using namespace ddSamplesCommon; // ======================================================== // Debug Draw RenderInterface for Core OpenGL: // ======================================================== class DDRenderInterfaceCoreGL final : public dd::RenderInterface { public: // // dd::RenderInterface overrides: // void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override { assert(points != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); assert(isMainThread()); // GL calls from the main thread only! glBindVertexArray(linePointVAO); glUseProgram(linePointProgram); glUniformMatrix4fv(linePointProgram_MvpMatrixLocation, 1, GL_FALSE, toFloatPtr(mvpMatrix)); if (depthEnabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick... glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), points); // Issue the draw call: glDrawArrays(GL_POINTS, 0, count); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); checkGLError(__FILE__, __LINE__); } void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override { assert(lines != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); assert(isMainThread()); // GL calls from the main thread only! glBindVertexArray(linePointVAO); glUseProgram(linePointProgram); glUniformMatrix4fv(linePointProgram_MvpMatrixLocation, 1, GL_FALSE, toFloatPtr(mvpMatrix)); if (depthEnabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick... glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), lines); // Issue the draw call: glDrawArrays(GL_LINES, 0, count); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); checkGLError(__FILE__, __LINE__); } void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override { assert(glyphs != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); assert(isMainThread()); // GL calls from the main thread only! glBindVertexArray(textVAO); glUseProgram(textProgram); // These doesn't have to be reset every draw call, I'm just being lazy ;) glUniform1i(textProgram_GlyphTextureLocation, 0); glUniform2f(textProgram_ScreenDimensions, static_cast(WindowWidth), static_cast(WindowHeight)); if (glyphTex != nullptr) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, handleToGL(glyphTex)); } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); glBindBuffer(GL_ARRAY_BUFFER, textVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), glyphs); glDrawArrays(GL_TRIANGLES, 0, count); // Issue the draw call glDisable(GL_BLEND); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); checkGLError(__FILE__, __LINE__); } dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override { assert(width > 0 && height > 0); assert(pixels != nullptr); assert(isMainThread()); // GL calls from the main thread only! GLuint textureId = 0; glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); checkGLError(__FILE__, __LINE__); return GLToHandle(textureId); } void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override { assert(isMainThread()); // GL calls from the main thread only! if (glyphTex == nullptr) { return; } const GLuint textureId = handleToGL(glyphTex); glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &textureId); } void beginDraw() override { assert(isMainThread()); } void endDraw() override { assert(isMainThread()); } // // Local methods: // DDRenderInterfaceCoreGL() : mvpMatrix(Matrix4::identity()) , linePointProgram(0) , linePointProgram_MvpMatrixLocation(-1) , textProgram(0) , textProgram_GlyphTextureLocation(-1) , textProgram_ScreenDimensions(-1) , linePointVAO(0) , linePointVBO(0) , textVAO(0) , textVBO(0) { std::printf("\n"); std::printf("GL_VENDOR : %s\n", glGetString(GL_VENDOR)); std::printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER)); std::printf("GL_VERSION : %s\n", glGetString(GL_VERSION)); std::printf("GLSL_VERSION : %s\n\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); std::printf("DDRenderInterfaceCoreGL MT initializing ...\n"); // Default OpenGL states: glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); // This has to be enabled since the point drawing shader will use gl_PointSize. glEnable(GL_PROGRAM_POINT_SIZE); setupShaderPrograms(); setupVertexBuffers(); std::printf("DDRenderInterfaceCoreGL MT ready!\n\n"); } ~DDRenderInterfaceCoreGL() { glDeleteProgram(linePointProgram); glDeleteProgram(textProgram); glDeleteVertexArrays(1, &linePointVAO); glDeleteBuffers(1, &linePointVBO); glDeleteVertexArrays(1, &textVAO); glDeleteBuffers(1, &textVBO); } void prepareDraw(const Matrix4 & mvp) { assert(isMainThread()); mvpMatrix = mvp; glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void setupShaderPrograms() { std::printf("> DDRenderInterfaceCoreGL::setupShaderPrograms()\n"); // // Line/point drawing shader: // { GLuint linePointVS = glCreateShader(GL_VERTEX_SHADER); glShaderSource(linePointVS, 1, &linePointVertShaderSrc, nullptr); compileShader(linePointVS); GLint linePointFS = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(linePointFS, 1, &linePointFragShaderSrc, nullptr); compileShader(linePointFS); linePointProgram = glCreateProgram(); glAttachShader(linePointProgram, linePointVS); glAttachShader(linePointProgram, linePointFS); glBindAttribLocation(linePointProgram, 0, "in_Position"); glBindAttribLocation(linePointProgram, 1, "in_ColorPointSize"); linkProgram(linePointProgram); linePointProgram_MvpMatrixLocation = glGetUniformLocation(linePointProgram, "u_MvpMatrix"); if (linePointProgram_MvpMatrixLocation < 0) { errorF("Unable to get u_MvpMatrix uniform location!"); } checkGLError(__FILE__, __LINE__); } // // Text rendering shader: // { GLuint textVS = glCreateShader(GL_VERTEX_SHADER); glShaderSource(textVS, 1, &textVertShaderSrc, nullptr); compileShader(textVS); GLint textFS = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(textFS, 1, &textFragShaderSrc, nullptr); compileShader(textFS); textProgram = glCreateProgram(); glAttachShader(textProgram, textVS); glAttachShader(textProgram, textFS); glBindAttribLocation(textProgram, 0, "in_Position"); glBindAttribLocation(textProgram, 1, "in_TexCoords"); glBindAttribLocation(textProgram, 2, "in_Color"); linkProgram(textProgram); textProgram_GlyphTextureLocation = glGetUniformLocation(textProgram, "u_glyphTexture"); if (textProgram_GlyphTextureLocation < 0) { errorF("Unable to get u_glyphTexture uniform location!"); } textProgram_ScreenDimensions = glGetUniformLocation(textProgram, "u_screenDimensions"); if (textProgram_ScreenDimensions < 0) { errorF("Unable to get u_screenDimensions uniform location!"); } checkGLError(__FILE__, __LINE__); } } void setupVertexBuffers() { std::printf("> DDRenderInterfaceCoreGL::setupVertexBuffers()\n"); // // Lines/points vertex buffer: // { glGenVertexArrays(1, &linePointVAO); glGenBuffers(1, &linePointVBO); checkGLError(__FILE__, __LINE__); glBindVertexArray(linePointVAO); glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); // RenderInterface will never be called with a batch larger than // DEBUG_DRAW_VERTEX_BUFFER_SIZE vertexes, so we can allocate the same amount here. glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW); checkGLError(__FILE__, __LINE__); // Set the vertex format expected by 3D points and lines: std::size_t offset = 0; glEnableVertexAttribArray(0); // in_Position (vec3) glVertexAttribPointer( /* index = */ 0, /* size = */ 3, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 3; glEnableVertexAttribArray(1); // in_ColorPointSize (vec4) glVertexAttribPointer( /* index = */ 1, /* size = */ 4, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); checkGLError(__FILE__, __LINE__); // VAOs can be a pain in the neck if left enabled... glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); } // // Text rendering vertex buffer: // { glGenVertexArrays(1, &textVAO); glGenBuffers(1, &textVBO); checkGLError(__FILE__, __LINE__); glBindVertexArray(textVAO); glBindBuffer(GL_ARRAY_BUFFER, textVBO); // NOTE: A more optimized implementation might consider combining // both the lines/points and text buffers to save some memory! glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW); checkGLError(__FILE__, __LINE__); // Set the vertex format expected by the 2D text: std::size_t offset = 0; glEnableVertexAttribArray(0); // in_Position (vec2) glVertexAttribPointer( /* index = */ 0, /* size = */ 2, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 2; glEnableVertexAttribArray(1); // in_TexCoords (vec2) glVertexAttribPointer( /* index = */ 1, /* size = */ 2, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 2; glEnableVertexAttribArray(2); // in_Color (vec4) glVertexAttribPointer( /* index = */ 2, /* size = */ 4, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); checkGLError(__FILE__, __LINE__); // Ditto. glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); } } static GLuint handleToGL(dd::GlyphTextureHandle handle) { const std::size_t temp = reinterpret_cast(handle); return static_cast(temp); } static dd::GlyphTextureHandle GLToHandle(const GLuint id) { const std::size_t temp = static_cast(id); return reinterpret_cast(temp); } static void checkGLError(const char * file, const int line) { GLenum err; while ((err = glGetError()) != GL_NO_ERROR) { errorF("%s(%d) : GL_CORE_ERROR=0x%X - %s", file, line, err, errorToString(err)); } } static void compileShader(const GLuint shader) { glCompileShader(shader); checkGLError(__FILE__, __LINE__); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); checkGLError(__FILE__, __LINE__); if (status == GL_FALSE) { GLchar strInfoLog[1024] = {0}; glGetShaderInfoLog(shader, sizeof(strInfoLog) - 1, nullptr, strInfoLog); errorF("\n>>> Shader compiler errors:\n%s", strInfoLog); } } static void linkProgram(const GLuint program) { glLinkProgram(program); checkGLError(__FILE__, __LINE__); GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); checkGLError(__FILE__, __LINE__); if (status == GL_FALSE) { GLchar strInfoLog[1024] = {0}; glGetProgramInfoLog(program, sizeof(strInfoLog) - 1, nullptr, strInfoLog); errorF("\n>>> Program linker errors:\n%s", strInfoLog); } } private: // The "model-view-projection" matrix for the scene. // In this demo, it consists of the camera's view and projection matrices only. Matrix4 mvpMatrix; GLuint linePointProgram; GLint linePointProgram_MvpMatrixLocation; GLuint textProgram; GLint textProgram_GlyphTextureLocation; GLint textProgram_ScreenDimensions; GLuint linePointVAO; GLuint linePointVBO; GLuint textVAO; GLuint textVBO; static const char * linePointVertShaderSrc; static const char * linePointFragShaderSrc; static const char * textVertShaderSrc; static const char * textFragShaderSrc; }; // class DDRenderInterfaceCoreGL // ======================================================== // Minimal shaders we need for the debug primitives: // ======================================================== const char * DDRenderInterfaceCoreGL::linePointVertShaderSrc = "\n" "#version 150\n" "\n" "in vec3 in_Position;\n" "in vec4 in_ColorPointSize;\n" "\n" "out vec4 v_Color;\n" "uniform mat4 u_MvpMatrix;\n" "\n" "void main()\n" "{\n" " gl_Position = u_MvpMatrix * vec4(in_Position, 1.0);\n" " gl_PointSize = in_ColorPointSize.w;\n" " v_Color = vec4(in_ColorPointSize.xyz, 1.0);\n" "}\n"; const char * DDRenderInterfaceCoreGL::linePointFragShaderSrc = "\n" "#version 150\n" "\n" "in vec4 v_Color;\n" "out vec4 out_FragColor;\n" "\n" "void main()\n" "{\n" " out_FragColor = v_Color;\n" "}\n"; const char * DDRenderInterfaceCoreGL::textVertShaderSrc = "\n" "#version 150\n" "\n" "in vec2 in_Position;\n" "in vec2 in_TexCoords;\n" "in vec3 in_Color;\n" "\n" "uniform vec2 u_screenDimensions;\n" "\n" "out vec2 v_TexCoords;\n" "out vec4 v_Color;\n" "\n" "void main()\n" "{\n" " // Map to normalized clip coordinates:\n" " float x = ((2.0 * (in_Position.x - 0.5)) / u_screenDimensions.x) - 1.0;\n" " float y = 1.0 - ((2.0 * (in_Position.y - 0.5)) / u_screenDimensions.y);\n" "\n" " gl_Position = vec4(x, y, 0.0, 1.0);\n" " v_TexCoords = in_TexCoords;\n" " v_Color = vec4(in_Color, 1.0);\n" "}\n"; const char * DDRenderInterfaceCoreGL::textFragShaderSrc = "\n" "#version 150\n" "\n" "in vec2 v_TexCoords;\n" "in vec4 v_Color;\n" "\n" "uniform sampler2D u_glyphTexture;\n" "out vec4 out_FragColor;\n" "\n" "void main()\n" "{\n" " out_FragColor = v_Color;\n" " out_FragColor.a = texture(u_glyphTexture, v_TexCoords).r;\n" "}\n"; // ======================================================== // GLFW / window management / sample drawing: // ======================================================== struct ThreadData { dd::ContextHandle ddContext; DDRenderInterfaceCoreGL * renderInterface; void (*threadDrawFunc)(const ThreadData &); void init(void (*fn)(const ThreadData &), DDRenderInterfaceCoreGL * ri) { ddContext = nullptr; renderInterface = ri; threadDrawFunc = fn; dd::initialize(&ddContext, renderInterface); } void shutdown() { dd::shutdown(ddContext); ddContext = nullptr; renderInterface = nullptr; threadDrawFunc = nullptr; } }; // ======================================================== static void drawLabel(const ThreadData & td, ddVec3_In pos, const char * name) { if (!keys.showLabels) { return; } // Only draw labels inside the camera frustum. if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2])) { const ddVec3 textColor = { 0.8f, 0.8f, 1.0f }; dd::projectedText(td.ddContext, name, pos, textColor, toFloatPtr(camera.vpMatrix), 0, 0, WindowWidth, WindowHeight, 0.5f); } } static void drawGrid(const ThreadData & td) { if (keys.showGrid) { dd::xzSquareGrid(td.ddContext, -50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); // Grid from -50 to +50 in both X & Z } } static void drawMiscObjects(const ThreadData & td) { // Start a row of objects at this position: ddVec3 origin = { -15.0f, 0.0f, 0.0f }; // Box with a point at it's center: drawLabel(td, origin, "box"); dd::box(td.ddContext, origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f); dd::point(td.ddContext, origin, dd::colors::White, 15.0f); origin[0] += 3.0f; // Sphere with a point at its center drawLabel(td, origin, "sphere"); dd::sphere(td.ddContext, origin, dd::colors::Red, 1.0f); dd::point(td.ddContext, origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Two cones, one open and one closed: const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f }; origin[1] -= 1.0f; drawLabel(td, origin, "cone (open)"); dd::cone(td.ddContext, origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f); dd::point(td.ddContext, origin, dd::colors::White, 15.0f); origin[0] += 4.0f; drawLabel(td, origin, "cone (closed)"); dd::cone(td.ddContext, origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f); dd::point(td.ddContext, origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Axis-aligned bounding box: const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f }; const ddVec3 bbMaxs = { 1.0f, 2.2f, 1.0f }; const ddVec3 bbCenter = { (bbMins[0] + bbMaxs[0]) * 0.5f, (bbMins[1] + bbMaxs[1]) * 0.5f, (bbMins[2] + bbMaxs[2]) * 0.5f }; drawLabel(td, origin, "AABB"); dd::aabb(td.ddContext, bbMins, bbMaxs, dd::colors::Orange); dd::point(td.ddContext, bbCenter, dd::colors::White, 15.0f); // Move along the Z for another row: origin[0] = -15.0f; origin[2] += 5.0f; // A big arrow pointing up: const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] }; const ddVec3 arrowTo = { origin[0], origin[1] + 5.0f, origin[2] }; drawLabel(td, arrowFrom, "arrow"); dd::arrow(td.ddContext, arrowFrom, arrowTo, dd::colors::Magenta, 1.0f); dd::point(td.ddContext, arrowFrom, dd::colors::White, 15.0f); dd::point(td.ddContext, arrowTo, dd::colors::White, 15.0f); origin[0] += 4.0f; // Plane with normal vector: const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f }; drawLabel(td, origin, "plane"); dd::plane(td.ddContext, origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f); dd::point(td.ddContext, origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Circle on the Y plane: drawLabel(td, origin, "circle"); dd::circle(td.ddContext, origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f); dd::point(td.ddContext, origin, dd::colors::White, 15.0f); origin[0] += 3.2f; // Tangent basis vectors: const ddVec3 normal = { 0.0f, 1.0f, 0.0f }; const ddVec3 tangent = { 1.0f, 0.0f, 0.0f }; const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f }; origin[1] += 0.1f; drawLabel(td, origin, "tangent basis"); dd::tangentBasis(td.ddContext, origin, normal, tangent, bitangent, 2.5f); dd::point(td.ddContext, origin, dd::colors::White, 15.0f); // And a set of intersecting axes: origin[0] += 4.0f; origin[1] += 1.0f; drawLabel(td, origin, "cross"); dd::cross(td.ddContext, origin, 2.0f); dd::point(td.ddContext, origin, dd::colors::White, 15.0f); } static void drawFrustum(const ThreadData & td) { const ddVec3 color = { 0.8f, 0.3f, 1.0f }; const ddVec3 origin = { -8.0f, 0.5f, 14.0f }; drawLabel(td, origin, "frustum + axes"); // The frustum will depict a fake camera: const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f); const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis()); const Matrix4 clip = inverse(proj * view); dd::frustum(td.ddContext, toFloatPtr(clip), color); // A white dot at the eye position: dd::point(td.ddContext, origin, dd::colors::White, 15.0f); // A set of arrows at the camera's origin/eye: const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f)); dd::axisTriad(td.ddContext, toFloatPtr(transform), 0.3f, 2.0f); } static void drawText(const ThreadData & td) { // HUD text: const ddVec3 textColor = { 1.0f, 1.0f, 1.0f }; const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f }; dd::screenText(td.ddContext, "Welcome to the multi-threaded Core OpenGL Debug Draw demo.\n\n" "[SPACE] to toggle labels on/off\n" "[RETURN] to toggle grid on/off", textPos2D, textColor, 0.55f); } static void sampleAppDraw(DDRenderInterfaceCoreGL & ddRenderIfaceGL, ThreadData tds[4], JobQueue & jobQ) { // Camera input update (the 'camera' object is declared in samples_common.hpp): camera.checkKeyboardMovement(); camera.checkMouseRotation(); camera.updateMatrices(); // Kick async render jobs: for (int i = 0; i < 4; ++i) { const ThreadData & td = tds[i]; jobQ.pushJob([td]() { td.threadDrawFunc(td); }); } // Begin a frame: ddRenderIfaceGL.prepareDraw(camera.vpMatrix); // Wait async draws to complete. In a more real life scenario this would // be the place to perform some other non-dependent work to avoid blocking. jobQ.waitAll(); // Flush each individual context from the main thread: for (int i = 0; i < 4; ++i) { dd::flush(tds[i].ddContext); } } static void sampleAppStart() { printDDBuildConfig(); if (!glfwInit()) { errorF("Failed to initialize GLFW!"); return; } // Things we need for the window / GL render context: glfwWindowHint(GLFW_RESIZABLE, false); glfwWindowHint(GLFW_DEPTH_BITS, 32); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); GLFWwindow * window = glfwCreateWindow(WindowWidth, WindowHeight, "Debug Draw Sample - Core OpenGL (MT, explicit context)", nullptr, nullptr); if (!window) { errorF("Failed to create GLFW window!"); return; } glfwMakeContextCurrent(window); if (!gl3wInit()) { errorF("Failed to initialize GL3W extension library!"); return; } if (!gl3wIsSupported(3, 2)) { errorF("This sample application requires at least OpenGL version 3.2 to run!"); return; } // From samples_common.hpp initInput(window); // Set up an OpenGL renderer: DDRenderInterfaceCoreGL ddRenderIfaceGL; // Draw contexts: ThreadData threads[4]; threads[0].init(&drawGrid, &ddRenderIfaceGL); threads[1].init(&drawMiscObjects, &ddRenderIfaceGL); threads[2].init(&drawFrustum, &ddRenderIfaceGL); threads[3].init(&drawText, &ddRenderIfaceGL); // Each draw function will be pushed into the async job queue // by the main thread every frame, then main will wait on it // and submit the GL draw commands with dd::flush(). JobQueue jobQ; jobQ.launch(); // Loop until the user closes the window: while (!glfwWindowShouldClose(window)) { const double t0s = glfwGetTime(); sampleAppDraw(ddRenderIfaceGL, threads, jobQ); glfwSwapBuffers(window); glfwPollEvents(); const double t1s = glfwGetTime(); deltaTime.seconds = static_cast(t1s - t0s); deltaTime.milliseconds = static_cast(deltaTime.seconds * 1000.0); } jobQ.waitAll(); for (int i = 0; i < 4; ++i) { threads[i].shutdown(); } } // ======================================================== // main(): // ======================================================== int main() { sampleAppStart(); gl3wShutdown(); glfwTerminate(); } ================================================ FILE: samples/sample_gl_core_multithreaded_tls.cpp ================================================ // ================================================================================================ // -*- C++ -*- // File: sample_gl_core_multithreaded_tls.cpp // Author: Guilherme R. Lampert // Brief: Debug Draw usage sample with Core Profile OpenGL and separate rendering thread. // Uses the implicit context as a thread-local variable of the rendering thread. // // This software is in the public domain. Where that dedication is not recognized, // you are granted a perpetual, irrevocable license to copy, distribute, and modify // this file as you see fit. // ================================================================================================ #define DEBUG_DRAW_IMPLEMENTATION #define DEBUG_DRAW_PER_THREAD_CONTEXT #include "debug_draw.hpp" // Debug Draw API. Notice that we need the DEBUG_DRAW_IMPLEMENTATION macro here! #include // An OpenGL extension wrangler (https://github.com/skaslev/gl3w). #include "samples_common.hpp" // Common code shared by the samples (camera, input, etc). using namespace ddSamplesCommon; // ======================================================== // Debug Draw RenderInterface for Core OpenGL: // ======================================================== class DDRenderInterfaceCoreGL final : public dd::RenderInterface { public: // // dd::RenderInterface overrides: // void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override { assert(points != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); assert(isOwnerThreadCall()); glBindVertexArray(linePointVAO); glUseProgram(linePointProgram); glUniformMatrix4fv(linePointProgram_MvpMatrixLocation, 1, GL_FALSE, toFloatPtr(mvpMatrix)); if (depthEnabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick... glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), points); // Issue the draw call: glDrawArrays(GL_POINTS, 0, count); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); checkGLError(__FILE__, __LINE__); } void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override { assert(lines != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); assert(isOwnerThreadCall()); glBindVertexArray(linePointVAO); glUseProgram(linePointProgram); glUniformMatrix4fv(linePointProgram_MvpMatrixLocation, 1, GL_FALSE, toFloatPtr(mvpMatrix)); if (depthEnabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } // NOTE: Could also use glBufferData to take advantage of the buffer orphaning trick... glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), lines); // Issue the draw call: glDrawArrays(GL_LINES, 0, count); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); checkGLError(__FILE__, __LINE__); } void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override { assert(glyphs != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); assert(isOwnerThreadCall()); glBindVertexArray(textVAO); glUseProgram(textProgram); // These doesn't have to be reset every draw call, I'm just being lazy ;) glUniform1i(textProgram_GlyphTextureLocation, 0); glUniform2f(textProgram_ScreenDimensions, static_cast(WindowWidth), static_cast(WindowHeight)); if (glyphTex != nullptr) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, handleToGL(glyphTex)); } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); glBindBuffer(GL_ARRAY_BUFFER, textVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(dd::DrawVertex), glyphs); glDrawArrays(GL_TRIANGLES, 0, count); // Issue the draw call glDisable(GL_BLEND); glUseProgram(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); checkGLError(__FILE__, __LINE__); } dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override { assert(width > 0 && height > 0); assert(pixels != nullptr); assert(isOwnerThreadCall()); GLuint textureId = 0; glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); checkGLError(__FILE__, __LINE__); return GLToHandle(textureId); } void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override { assert(isOwnerThreadCall()); if (glyphTex == nullptr) { return; } const GLuint textureId = handleToGL(glyphTex); glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &textureId); } void beginDraw() override { assert(isOwnerThreadCall()); } void endDraw() override { assert(isOwnerThreadCall()); } // // Local methods: // DDRenderInterfaceCoreGL() : mvpMatrix(Matrix4::identity()) , linePointProgram(0) , linePointProgram_MvpMatrixLocation(-1) , textProgram(0) , textProgram_GlyphTextureLocation(-1) , textProgram_ScreenDimensions(-1) , linePointVAO(0) , linePointVBO(0) , textVAO(0) , textVBO(0) { std::printf("\n"); std::printf("GL_VENDOR : %s\n", glGetString(GL_VENDOR)); std::printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER)); std::printf("GL_VERSION : %s\n", glGetString(GL_VERSION)); std::printf("GLSL_VERSION : %s\n\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); std::printf("DDRenderInterfaceCoreGL MT initializing ...\n"); // Default OpenGL states: glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); // This has to be enabled since the point drawing shader will use gl_PointSize. glEnable(GL_PROGRAM_POINT_SIZE); setupShaderPrograms(); setupVertexBuffers(); std::printf("DDRenderInterfaceCoreGL MT ready!\n\n"); } ~DDRenderInterfaceCoreGL() { glDeleteProgram(linePointProgram); glDeleteProgram(textProgram); glDeleteVertexArrays(1, &linePointVAO); glDeleteBuffers(1, &linePointVBO); glDeleteVertexArrays(1, &textVAO); glDeleteBuffers(1, &textVBO); } void prepareDraw(const Matrix4 & mvp) { assert(isOwnerThreadCall()); mvpMatrix = mvp; glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void setupShaderPrograms() { std::printf("> DDRenderInterfaceCoreGL::setupShaderPrograms()\n"); // // Line/point drawing shader: // { GLuint linePointVS = glCreateShader(GL_VERTEX_SHADER); glShaderSource(linePointVS, 1, &linePointVertShaderSrc, nullptr); compileShader(linePointVS); GLint linePointFS = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(linePointFS, 1, &linePointFragShaderSrc, nullptr); compileShader(linePointFS); linePointProgram = glCreateProgram(); glAttachShader(linePointProgram, linePointVS); glAttachShader(linePointProgram, linePointFS); glBindAttribLocation(linePointProgram, 0, "in_Position"); glBindAttribLocation(linePointProgram, 1, "in_ColorPointSize"); linkProgram(linePointProgram); linePointProgram_MvpMatrixLocation = glGetUniformLocation(linePointProgram, "u_MvpMatrix"); if (linePointProgram_MvpMatrixLocation < 0) { errorF("Unable to get u_MvpMatrix uniform location!"); } checkGLError(__FILE__, __LINE__); } // // Text rendering shader: // { GLuint textVS = glCreateShader(GL_VERTEX_SHADER); glShaderSource(textVS, 1, &textVertShaderSrc, nullptr); compileShader(textVS); GLint textFS = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(textFS, 1, &textFragShaderSrc, nullptr); compileShader(textFS); textProgram = glCreateProgram(); glAttachShader(textProgram, textVS); glAttachShader(textProgram, textFS); glBindAttribLocation(textProgram, 0, "in_Position"); glBindAttribLocation(textProgram, 1, "in_TexCoords"); glBindAttribLocation(textProgram, 2, "in_Color"); linkProgram(textProgram); textProgram_GlyphTextureLocation = glGetUniformLocation(textProgram, "u_glyphTexture"); if (textProgram_GlyphTextureLocation < 0) { errorF("Unable to get u_glyphTexture uniform location!"); } textProgram_ScreenDimensions = glGetUniformLocation(textProgram, "u_screenDimensions"); if (textProgram_ScreenDimensions < 0) { errorF("Unable to get u_screenDimensions uniform location!"); } checkGLError(__FILE__, __LINE__); } } void setupVertexBuffers() { std::printf("> DDRenderInterfaceCoreGL::setupVertexBuffers()\n"); // // Lines/points vertex buffer: // { glGenVertexArrays(1, &linePointVAO); glGenBuffers(1, &linePointVBO); checkGLError(__FILE__, __LINE__); glBindVertexArray(linePointVAO); glBindBuffer(GL_ARRAY_BUFFER, linePointVBO); // RenderInterface will never be called with a batch larger than // DEBUG_DRAW_VERTEX_BUFFER_SIZE vertexes, so we can allocate the same amount here. glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW); checkGLError(__FILE__, __LINE__); // Set the vertex format expected by 3D points and lines: std::size_t offset = 0; glEnableVertexAttribArray(0); // in_Position (vec3) glVertexAttribPointer( /* index = */ 0, /* size = */ 3, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 3; glEnableVertexAttribArray(1); // in_ColorPointSize (vec4) glVertexAttribPointer( /* index = */ 1, /* size = */ 4, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); checkGLError(__FILE__, __LINE__); // VAOs can be a pain in the neck if left enabled... glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); } // // Text rendering vertex buffer: // { glGenVertexArrays(1, &textVAO); glGenBuffers(1, &textVBO); checkGLError(__FILE__, __LINE__); glBindVertexArray(textVAO); glBindBuffer(GL_ARRAY_BUFFER, textVBO); // NOTE: A more optimized implementation might consider combining // both the lines/points and text buffers to save some memory! glBufferData(GL_ARRAY_BUFFER, DEBUG_DRAW_VERTEX_BUFFER_SIZE * sizeof(dd::DrawVertex), nullptr, GL_STREAM_DRAW); checkGLError(__FILE__, __LINE__); // Set the vertex format expected by the 2D text: std::size_t offset = 0; glEnableVertexAttribArray(0); // in_Position (vec2) glVertexAttribPointer( /* index = */ 0, /* size = */ 2, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 2; glEnableVertexAttribArray(1); // in_TexCoords (vec2) glVertexAttribPointer( /* index = */ 1, /* size = */ 2, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); offset += sizeof(float) * 2; glEnableVertexAttribArray(2); // in_Color (vec4) glVertexAttribPointer( /* index = */ 2, /* size = */ 4, /* type = */ GL_FLOAT, /* normalize = */ GL_FALSE, /* stride = */ sizeof(dd::DrawVertex), /* offset = */ reinterpret_cast(offset)); checkGLError(__FILE__, __LINE__); // Ditto. glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); } } static GLuint handleToGL(dd::GlyphTextureHandle handle) { const std::size_t temp = reinterpret_cast(handle); return static_cast(temp); } static dd::GlyphTextureHandle GLToHandle(const GLuint id) { const std::size_t temp = static_cast(id); return reinterpret_cast(temp); } static void checkGLError(const char * file, const int line) { GLenum err; while ((err = glGetError()) != GL_NO_ERROR) { errorF("%s(%d) : GL_CORE_ERROR=0x%X - %s", file, line, err, errorToString(err)); } } static void compileShader(const GLuint shader) { glCompileShader(shader); checkGLError(__FILE__, __LINE__); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); checkGLError(__FILE__, __LINE__); if (status == GL_FALSE) { GLchar strInfoLog[1024] = {0}; glGetShaderInfoLog(shader, sizeof(strInfoLog) - 1, nullptr, strInfoLog); errorF("\n>>> Shader compiler errors:\n%s", strInfoLog); } } static void linkProgram(const GLuint program) { glLinkProgram(program); checkGLError(__FILE__, __LINE__); GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); checkGLError(__FILE__, __LINE__); if (status == GL_FALSE) { GLchar strInfoLog[1024] = {0}; glGetProgramInfoLog(program, sizeof(strInfoLog) - 1, nullptr, strInfoLog); errorF("\n>>> Program linker errors:\n%s", strInfoLog); } } void setOwnerThread(std::thread::id tid) { ownerThreadId = tid; } bool isOwnerThreadCall() const { return std::this_thread::get_id() == ownerThreadId; } private: std::thread::id ownerThreadId; // The "model-view-projection" matrix for the scene. // In this demo, it consists of the camera's view and projection matrices only. Matrix4 mvpMatrix; GLuint linePointProgram; GLint linePointProgram_MvpMatrixLocation; GLuint textProgram; GLint textProgram_GlyphTextureLocation; GLint textProgram_ScreenDimensions; GLuint linePointVAO; GLuint linePointVBO; GLuint textVAO; GLuint textVBO; static const char * linePointVertShaderSrc; static const char * linePointFragShaderSrc; static const char * textVertShaderSrc; static const char * textFragShaderSrc; }; // class DDRenderInterfaceCoreGL // ======================================================== // Minimal shaders we need for the debug primitives: // ======================================================== const char * DDRenderInterfaceCoreGL::linePointVertShaderSrc = "\n" "#version 150\n" "\n" "in vec3 in_Position;\n" "in vec4 in_ColorPointSize;\n" "\n" "out vec4 v_Color;\n" "uniform mat4 u_MvpMatrix;\n" "\n" "void main()\n" "{\n" " gl_Position = u_MvpMatrix * vec4(in_Position, 1.0);\n" " gl_PointSize = in_ColorPointSize.w;\n" " v_Color = vec4(in_ColorPointSize.xyz, 1.0);\n" "}\n"; const char * DDRenderInterfaceCoreGL::linePointFragShaderSrc = "\n" "#version 150\n" "\n" "in vec4 v_Color;\n" "out vec4 out_FragColor;\n" "\n" "void main()\n" "{\n" " out_FragColor = v_Color;\n" "}\n"; const char * DDRenderInterfaceCoreGL::textVertShaderSrc = "\n" "#version 150\n" "\n" "in vec2 in_Position;\n" "in vec2 in_TexCoords;\n" "in vec3 in_Color;\n" "\n" "uniform vec2 u_screenDimensions;\n" "\n" "out vec2 v_TexCoords;\n" "out vec4 v_Color;\n" "\n" "void main()\n" "{\n" " // Map to normalized clip coordinates:\n" " float x = ((2.0 * (in_Position.x - 0.5)) / u_screenDimensions.x) - 1.0;\n" " float y = 1.0 - ((2.0 * (in_Position.y - 0.5)) / u_screenDimensions.y);\n" "\n" " gl_Position = vec4(x, y, 0.0, 1.0);\n" " v_TexCoords = in_TexCoords;\n" " v_Color = vec4(in_Color, 1.0);\n" "}\n"; const char * DDRenderInterfaceCoreGL::textFragShaderSrc = "\n" "#version 150\n" "\n" "in vec2 v_TexCoords;\n" "in vec4 v_Color;\n" "\n" "uniform sampler2D u_glyphTexture;\n" "out vec4 out_FragColor;\n" "\n" "void main()\n" "{\n" " out_FragColor = v_Color;\n" " out_FragColor.a = texture(u_glyphTexture, v_TexCoords).r;\n" "}\n"; // ======================================================== // GLFW / window management / sample drawing: // ======================================================== // https://stackoverflow.com/questions/4792449/c0x-has-no-semaphores-how-to-synchronize-threads class Semaphore final { public: Semaphore(int n = 0) : count(n) { } void signal() { std::unique_lock lock(mtx); count++; cv.notify_one(); } void wait() { std::unique_lock lock(mtx); while (count == 0) { cv.wait(lock); } count--; } private: std::mutex mtx; std::condition_variable cv; int count; }; // ======================================================== struct ThreadData { volatile bool shouldQuit; DDRenderInterfaceCoreGL * renderInterface; void (*threadFunc)(ThreadData &); GLFWwindow * window; std::thread threadObject; Semaphore mainDone; Semaphore renderDone; ThreadData() : mainDone(0), renderDone(1) { } void init(void (*fn)(ThreadData &), DDRenderInterfaceCoreGL * ri, GLFWwindow * win) { shouldQuit = false; renderInterface = ri; threadFunc = fn; window = win; threadObject = std::thread([this]{ threadFunc(*this); }); } void shutdown() { shouldQuit = true; if (threadObject.joinable()) { threadObject.join(); } renderInterface = nullptr; threadFunc = nullptr; window = nullptr; } }; // ======================================================== static void drawLabel(ddVec3_In pos, const char * name) { if (!keys.showLabels) { return; } // Only draw labels inside the camera frustum. if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2])) { const ddVec3 textColor = { 0.8f, 0.8f, 1.0f }; dd::projectedText(name, pos, textColor, toFloatPtr(camera.vpMatrix), 0, 0, WindowWidth, WindowHeight, 0.5f); } } static void drawGrid() { if (keys.showGrid) { dd::xzSquareGrid(-50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); // Grid from -50 to +50 in both X & Z } } static void drawMiscObjects() { // Start a row of objects at this position: ddVec3 origin = { -15.0f, 0.0f, 0.0f }; // Box with a point at it's center: drawLabel(origin, "box"); dd::box(origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 3.0f; // Sphere with a point at its center drawLabel(origin, "sphere"); dd::sphere(origin, dd::colors::Red, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Two cones, one open and one closed: const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f }; origin[1] -= 1.0f; drawLabel(origin, "cone (open)"); dd::cone(origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; drawLabel(origin, "cone (closed)"); dd::cone(origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Axis-aligned bounding box: const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f }; const ddVec3 bbMaxs = { 1.0f, 2.2f, 1.0f }; const ddVec3 bbCenter = { (bbMins[0] + bbMaxs[0]) * 0.5f, (bbMins[1] + bbMaxs[1]) * 0.5f, (bbMins[2] + bbMaxs[2]) * 0.5f }; drawLabel(origin, "AABB"); dd::aabb(bbMins, bbMaxs, dd::colors::Orange); dd::point(bbCenter, dd::colors::White, 15.0f); // Move along the Z for another row: origin[0] = -15.0f; origin[2] += 5.0f; // A big arrow pointing up: const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] }; const ddVec3 arrowTo = { origin[0], origin[1] + 5.0f, origin[2] }; drawLabel(arrowFrom, "arrow"); dd::arrow(arrowFrom, arrowTo, dd::colors::Magenta, 1.0f); dd::point(arrowFrom, dd::colors::White, 15.0f); dd::point(arrowTo, dd::colors::White, 15.0f); origin[0] += 4.0f; // Plane with normal vector: const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f }; drawLabel(origin, "plane"); dd::plane(origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Circle on the Y plane: drawLabel(origin, "circle"); dd::circle(origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 3.2f; // Tangent basis vectors: const ddVec3 normal = { 0.0f, 1.0f, 0.0f }; const ddVec3 tangent = { 1.0f, 0.0f, 0.0f }; const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f }; origin[1] += 0.1f; drawLabel(origin, "tangent basis"); dd::tangentBasis(origin, normal, tangent, bitangent, 2.5f); dd::point(origin, dd::colors::White, 15.0f); // And a set of intersecting axes: origin[0] += 4.0f; origin[1] += 1.0f; drawLabel(origin, "cross"); dd::cross(origin, 2.0f); dd::point(origin, dd::colors::White, 15.0f); } static void drawFrustum() { const ddVec3 color = { 0.8f, 0.3f, 1.0f }; const ddVec3 origin = { -8.0f, 0.5f, 14.0f }; drawLabel(origin, "frustum + axes"); // The frustum will depict a fake camera: const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f); const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis()); const Matrix4 clip = inverse(proj * view); dd::frustum(toFloatPtr(clip), color); // A white dot at the eye position: dd::point(origin, dd::colors::White, 15.0f); // A set of arrows at the camera's origin/eye: const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f)); dd::axisTriad(toFloatPtr(transform), 0.3f, 2.0f); } static void drawText() { // HUD text: const ddVec3 textColor = { 1.0f, 1.0f, 1.0f }; const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f }; dd::screenText("Welcome to the multi-threaded Core OpenGL Debug Draw demo.\n\n" "[SPACE] to toggle labels on/off\n" "[RETURN] to toggle grid on/off", textPos2D, textColor, 0.55f); } static void sampleAppRenderThread(ThreadData & td) { std::printf("Render thread starting...\n"); // Take ownership of the OpenGL context for this thread: glfwMakeContextCurrent(td.window); td.renderInterface->setOwnerThread(std::this_thread::get_id()); dd::initialize(td.renderInterface); while (!td.shouldQuit) { td.mainDone.wait(); td.renderInterface->prepareDraw(camera.vpMatrix); // Call some DD functions to add stuff to the debug draw queues: drawGrid(); drawMiscObjects(); drawFrustum(); drawText(); dd::flush(getTimeMilliseconds()); glfwSwapBuffers(td.window); td.renderDone.signal(); } std::printf("Render thread exiting...\n"); dd::shutdown(); } static void sampleAppStart() { printDDBuildConfig(); if (!glfwInit()) { errorF("Failed to initialize GLFW!"); return; } // Things we need for the window / GL render context: glfwWindowHint(GLFW_RESIZABLE, false); glfwWindowHint(GLFW_DEPTH_BITS, 32); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); GLFWwindow * window = glfwCreateWindow(WindowWidth, WindowHeight, "Debug Draw Sample - Core OpenGL (MT, implicit context)", nullptr, nullptr); if (!window) { errorF("Failed to create GLFW window!"); return; } glfwMakeContextCurrent(window); if (!gl3wInit()) { errorF("Failed to initialize GL3W extension library!"); return; } if (!gl3wIsSupported(3, 2)) { errorF("This sample application requires at least OpenGL version 3.2 to run!"); return; } // From samples_common.hpp initInput(window); // Set up an OpenGL renderer: DDRenderInterfaceCoreGL ddRenderIfaceGL; // Launch the rendering thread that will call the DD functions: ThreadData renderThread; renderThread.init(&sampleAppRenderThread, &ddRenderIfaceGL, window); // Loop until the user closes the window: while (!glfwWindowShouldClose(window)) { const double t0s = glfwGetTime(); renderThread.renderDone.wait(); camera.checkKeyboardMovement(); camera.checkMouseRotation(); camera.updateMatrices(); glfwPollEvents(); renderThread.mainDone.signal(); const double t1s = glfwGetTime(); deltaTime.seconds = static_cast(t1s - t0s); deltaTime.milliseconds = static_cast(deltaTime.seconds * 1000.0); } renderThread.shutdown(); } // ======================================================== // main(): // ======================================================== int main() { sampleAppStart(); gl3wShutdown(); glfwTerminate(); } ================================================ FILE: samples/sample_gl_legacy.cpp ================================================ // ================================================================================================ // -*- C++ -*- // File: sample_gl_legacy.cpp // Author: Guilherme R. Lampert // Brief: Debug Draw usage sample with legacy (AKA fixed function) OpenGL. // // This software is in the public domain. Where that dedication is not recognized, // you are granted a perpetual, irrevocable license to copy, distribute, and modify // this file as you see fit. // ================================================================================================ #define DEBUG_DRAW_IMPLEMENTATION #include "debug_draw.hpp" // Debug Draw API. Notice that we need the DEBUG_DRAW_IMPLEMENTATION macro here! #include "samples_common.hpp" // Common code shared by the samples (camera, input, etc). using namespace ddSamplesCommon; // ======================================================== // Debug Draw RenderInterface for legacy OpenGL: // ======================================================== class DDRenderInterfaceLegacyGL final : public dd::RenderInterface { public: // // dd::RenderInterface overrides: // void drawPointList(const dd::DrawVertex * points, int count, bool depthEnabled) override { assert(points != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); if (depthEnabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } for (int i = 0; i < count; ++i, ++points) { const dd::DrawVertex & v = *points; // PoinSize cannot be called between Begin/End, // so we can't hoist them out of this loop glPointSize(v.point.size); glBegin(GL_POINTS); glColor3f(v.point.r, v.point.g, v.point.b); glVertex3f(v.point.x, v.point.y, v.point.z); glEnd(); } checkGLError(__FILE__, __LINE__); } void drawLineList(const dd::DrawVertex * lines, int count, bool depthEnabled) override { assert(lines != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); if (depthEnabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } glBegin(GL_LINES); for (int i = 0; i < count; ++i, ++lines) { const dd::DrawVertex & v = *lines; glColor3f(v.line.r, v.line.g, v.line.b); glVertex3f(v.line.x, v.line.y, v.line.z); } glEnd(); checkGLError(__FILE__, __LINE__); } void drawGlyphList(const dd::DrawVertex * glyphs, int count, dd::GlyphTextureHandle glyphTex) override { assert(glyphs != nullptr); assert(count > 0 && count <= DEBUG_DRAW_VERTEX_BUFFER_SIZE); // Legacy 2D draw settings: glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, WindowWidth, WindowHeight, 0, -99999, 99999); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (glyphTex != nullptr) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, handleToGL(glyphTex)); } // DD will send the glyphs already triangulated to make // integration easier with modern OpenGL, which deprecated // GL_QUADS. But in this legacy GL sample we can still use it, // so two vertexes out of every six just get thrown away. glBegin(GL_QUADS); for (int i = 0; i < count; i += 6) { const dd::DrawVertex & t0_v0 = *glyphs++; const dd::DrawVertex & t0_v1 = *glyphs++; const dd::DrawVertex & t0_v2 = *glyphs++; /*const dd::DrawVertex & t1_v0 = */glyphs++; /*const dd::DrawVertex & t1_v1 = */glyphs++; const dd::DrawVertex & t1_v2 = *glyphs++; glColor3f(t0_v0.glyph.r, t0_v0.glyph.g, t0_v0.glyph.b); glTexCoord2f(t0_v0.glyph.u, t0_v0.glyph.v); glVertex2f(t0_v0.glyph.x, t0_v0.glyph.y); glColor3f(t0_v2.glyph.r, t0_v2.glyph.g, t0_v2.glyph.b); glTexCoord2f(t0_v2.glyph.u, t0_v2.glyph.v); glVertex2f(t0_v2.glyph.x, t0_v2.glyph.y); glColor3f(t1_v2.glyph.r, t1_v2.glyph.g, t1_v2.glyph.b); glTexCoord2f(t1_v2.glyph.u, t1_v2.glyph.v); glVertex2f(t1_v2.glyph.x, t1_v2.glyph.y); glColor3f(t0_v1.glyph.r, t0_v1.glyph.g, t0_v1.glyph.b); glTexCoord2f(t0_v1.glyph.u, t0_v1.glyph.v); glVertex2f(t0_v1.glyph.x, t0_v1.glyph.y); } glEnd(); glDisable(GL_BLEND); if (glyphTex != nullptr) { glDisable(GL_TEXTURE_2D); } checkGLError(__FILE__, __LINE__); } dd::GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels) override { assert(width > 0 && height > 0); assert(pixels != nullptr); GLuint textureId = 0; glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); // // I don't recall if there was a way of getting // similar behavior to GL_RED/GL_R8 in legacy OpenGL... // Tried GL_LUMINANCE/GL_ALPHA but it didn't work. // // Simplest way is to just expand the texture to RGBA manually. // Takes another memory allocation though, but this is a // sample, so performance is not paramount ;) // struct RGBA { std::uint8_t r, g, b, a; }; RGBA * expanded = new RGBA[width * height]; const std::uint8_t * p = static_cast(pixels); // Expand graymap the RGBA: for (int i = 0; i < width * height; ++i) { expanded[i].r = 255; expanded[i].g = 255; expanded[i].b = 255; expanded[i].a = p[i]; } glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, expanded); delete[] expanded; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); checkGLError(__FILE__, __LINE__); return GLToHandle(textureId); } void destroyGlyphTexture(dd::GlyphTextureHandle glyphTex) override { if (glyphTex == nullptr) { return; } const GLuint textureId = handleToGL(glyphTex); glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &textureId); } // These two can also be implemented to perform GL render // state setup/cleanup, but we don't use them in this sample. //void beginDraw() override { } //void endDraw() override { } // // Local methods: // DDRenderInterfaceLegacyGL() { std::printf("\n"); std::printf("GL_VENDOR : %s\n", glGetString(GL_VENDOR)); std::printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER)); std::printf("GL_VERSION : %s\n\n", glGetString(GL_VERSION)); std::printf("DDRenderInterfaceLegacyGL initializing ...\n"); // Default OpenGL states: glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); std::printf("DDRenderInterfaceLegacyGL ready!\n\n"); } static GLuint handleToGL(dd::GlyphTextureHandle handle) { const std::size_t temp = reinterpret_cast(handle); return static_cast(temp); } static dd::GlyphTextureHandle GLToHandle(const GLuint id) { const std::size_t temp = static_cast(id); return reinterpret_cast(temp); } static void checkGLError(const char * file, const int line) { GLenum err; while ((err = glGetError()) != GL_NO_ERROR) { errorF("%s(%d) : GL_ERROR=0x%X - %s", file, line, err, errorToString(err)); } } }; // class DDRenderInterfaceLegacyGL // ======================================================== // GLFW / window management / sample drawing: // ======================================================== static void drawGrid() { if (!keys.showGrid) { return; } dd::xzSquareGrid(-50.0f, 50.0f, -1.0f, 1.7f, dd::colors::Green); // Grid from -50 to +50 in both X & Z } static void drawLabel(ddVec3_In pos, const char * name) { if (!keys.showLabels) { return; } // Only draw labels inside the camera frustum. if (camera.isPointInsideFrustum(pos[0], pos[1], pos[2])) { const ddVec3 textColor = { 0.8f, 0.8f, 1.0f }; dd::projectedText(name, pos, textColor, toFloatPtr(camera.vpMatrix), 0, 0, WindowWidth, WindowHeight, 0.5f); } } static void drawMiscObjects() { // Start a row of objects at this position: ddVec3 origin = { -15.0f, 0.0f, 0.0f }; // Box with a point at it's center: drawLabel(origin, "box"); dd::box(origin, dd::colors::Blue, 1.5f, 1.5f, 1.5f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 3.0f; // Sphere with a point at its center drawLabel(origin, "sphere"); dd::sphere(origin, dd::colors::Red, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Two cones, one open and one closed: const ddVec3 condeDir = { 0.0f, 2.5f, 0.0f }; origin[1] -= 1.0f; drawLabel(origin, "cone (open)"); dd::cone(origin, condeDir, dd::colors::Yellow, 1.0f, 2.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; drawLabel(origin, "cone (closed)"); dd::cone(origin, condeDir, dd::colors::Cyan, 0.0f, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Axis-aligned bounding box: const ddVec3 bbMins = { -1.0f, -0.9f, -1.0f }; const ddVec3 bbMaxs = { 1.0f, 2.2f, 1.0f }; const ddVec3 bbCenter = { (bbMins[0] + bbMaxs[0]) * 0.5f, (bbMins[1] + bbMaxs[1]) * 0.5f, (bbMins[2] + bbMaxs[2]) * 0.5f }; drawLabel(origin, "AABB"); dd::aabb(bbMins, bbMaxs, dd::colors::Orange); dd::point(bbCenter, dd::colors::White, 15.0f); // Move along the Z for another row: origin[0] = -15.0f; origin[2] += 5.0f; // A big arrow pointing up: const ddVec3 arrowFrom = { origin[0], origin[1], origin[2] }; const ddVec3 arrowTo = { origin[0], origin[1] + 5.0f, origin[2] }; drawLabel(arrowFrom, "arrow"); dd::arrow(arrowFrom, arrowTo, dd::colors::Magenta, 1.0f); dd::point(arrowFrom, dd::colors::White, 15.0f); dd::point(arrowTo, dd::colors::White, 15.0f); origin[0] += 4.0f; // Plane with normal vector: const ddVec3 planeNormal = { 0.0f, 1.0f, 0.0f }; drawLabel(origin, "plane"); dd::plane(origin, planeNormal, dd::colors::Yellow, dd::colors::Blue, 1.5f, 1.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 4.0f; // Circle on the Y plane: drawLabel(origin, "circle"); dd::circle(origin, planeNormal, dd::colors::Orange, 1.5f, 15.0f); dd::point(origin, dd::colors::White, 15.0f); origin[0] += 3.2f; // Tangent basis vectors: const ddVec3 normal = { 0.0f, 1.0f, 0.0f }; const ddVec3 tangent = { 1.0f, 0.0f, 0.0f }; const ddVec3 bitangent = { 0.0f, 0.0f, 1.0f }; origin[1] += 0.1f; drawLabel(origin, "tangent basis"); dd::tangentBasis(origin, normal, tangent, bitangent, 2.5f); dd::point(origin, dd::colors::White, 15.0f); // And a set of intersecting axes: origin[0] += 4.0f; origin[1] += 1.0f; drawLabel(origin, "cross"); dd::cross(origin, 2.0f); dd::point(origin, dd::colors::White, 15.0f); } static void drawFrustum() { const ddVec3 color = { 0.8f, 0.3f, 1.0f }; const ddVec3 origin = { -8.0f, 0.5f, 14.0f }; drawLabel(origin, "frustum + axes"); // The frustum will depict a fake camera: const Matrix4 proj = Matrix4::perspective(degToRad(45.0f), 800.0f / 600.0f, 0.5f, 4.0f); const Matrix4 view = Matrix4::lookAt(Point3(-8.0f, 0.5f, 14.0f), Point3(-8.0f, 0.5f, -14.0f), Vector3::yAxis()); const Matrix4 clip = inverse(proj * view); dd::frustum(toFloatPtr(clip), color); // A white dot at the eye position: dd::point(origin, dd::colors::White, 15.0f); // A set of arrows at the camera's origin/eye: const Matrix4 transform = Matrix4::translation(Vector3(-8.0f, 0.5f, 14.0f)) * Matrix4::rotationZ(degToRad(60.0f)); dd::axisTriad(toFloatPtr(transform), 0.3f, 2.0f); } static void drawText() { // HUD text: const ddVec3 textColor = { 1.0f, 1.0f, 1.0f }; const ddVec3 textPos2D = { 10.0f, 15.0f, 0.0f }; dd::screenText("Welcome to the legacy OpenGL Debug Draw demo.\n\n" "[SPACE] to toggle labels on/off\n" "[RETURN] to toggle grid on/off", textPos2D, textColor, 0.55f); } static void sampleAppDraw() { // Camera input update (the 'camera' object is declared in samples_common.hpp): camera.checkKeyboardMovement(); camera.checkMouseRotation(); camera.updateMatrices(); glMatrixMode(GL_PROJECTION); glLoadMatrixf(toFloatPtr(camera.projMatrix)); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(toFloatPtr(camera.viewMatrix)); glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Call some DD functions to add stuff to the debug draw queues: drawGrid(); drawMiscObjects(); drawFrustum(); drawText(); // Drawing only really happens now (here's where RenderInterface gets called). dd::flush(getTimeMilliseconds()); } static void sampleAppStart() { printDDBuildConfig(); if (!glfwInit()) { errorF("Failed to initialize GLFW!"); return; } // Things we need for the window / GL render context: glfwWindowHint(GLFW_RESIZABLE, false); glfwWindowHint(GLFW_DEPTH_BITS, 32); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); GLFWwindow * window = glfwCreateWindow(WindowWidth, WindowHeight, "Debug Draw Sample - Legacy OpenGL", nullptr, nullptr); if (!window) { errorF("Failed to create GLFW window!"); return; } glfwMakeContextCurrent(window); // From samples_common.hpp initInput(window); // Set up the Debug Draw: DDRenderInterfaceLegacyGL ddRenderIfaceGL; dd::initialize(&ddRenderIfaceGL); // Loop until the user closes the window: while (!glfwWindowShouldClose(window)) { const double t0s = glfwGetTime(); sampleAppDraw(); glfwSwapBuffers(window); glfwPollEvents(); const double t1s = glfwGetTime(); deltaTime.seconds = static_cast(t1s - t0s); deltaTime.milliseconds = static_cast(deltaTime.seconds * 1000.0); } dd::shutdown(); } // ======================================================== // main(): // ======================================================== int main() { sampleAppStart(); glfwTerminate(); } ================================================ FILE: samples/sample_null_renderer.cpp ================================================ // ================================================================================================ // -*- C++ -*- // File: sample_null_renderer.cpp // Author: Guilherme R. Lampert // Brief: Minimal Debug Draw usage sample that does nothing (a null renderer). // // This software is in the public domain. Where that dedication is not recognized, // you are granted a perpetual, irrevocable license to copy, distribute, and modify // this file as you see fit. // ================================================================================================ #define DEBUG_DRAW_IMPLEMENTATION #include "debug_draw.hpp" class DDRenderInterfaceNull final : public dd::RenderInterface { public: ~DDRenderInterfaceNull() { } }; int main() { DDRenderInterfaceNull ddRenderIfaceNull; dd::initialize(&ddRenderIfaceNull); dd::flush(); dd::shutdown(); } ================================================ FILE: samples/samples_common.hpp ================================================ // ================================================================================================ // -*- C++ -*- // File: samples_common.hpp // Author: Guilherme R. Lampert // Brief: Common code shared by the Debug Draw samples. // // This software is in the public domain. Where that dedication is not recognized, // you are granted a perpetual, irrevocable license to copy, distribute, and modify // this file as you see fit. // ================================================================================================ #ifndef DD_SAMPLES_COMMON_HPP #define DD_SAMPLES_COMMON_HPP // #define DD_SAMPLES_NOGL to exclude all OpenGL/GLFW // related code (e.g.: for the D3D Win32 samples) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef DD_SAMPLES_NOGL #include #endif // DD_SAMPLES_NOGL namespace ddSamplesCommon { // App window dimensions; Not resizable. static const int WindowWidth = 1024; static const int WindowHeight = 768; // Angle in degrees to angle in radians for sin/cos/etc. static inline float degToRad(const float degrees) { return (degrees * 3.1415926535897931f / 180.0f); } #ifndef DD_SAMPLES_NOGL // Time in milliseconds since the application started. static inline std::int64_t getTimeMilliseconds() { const double seconds = glfwGetTime(); return static_cast(seconds * 1000.0); } // Time in seconds since the application started. static inline double getTimeSeconds() { return glfwGetTime(); } // GL error enum to printable string. static inline const char * errorToString(const GLenum errorCode) { switch (errorCode) { case GL_NO_ERROR : return "GL_NO_ERROR"; case GL_INVALID_ENUM : return "GL_INVALID_ENUM"; case GL_INVALID_VALUE : return "GL_INVALID_VALUE"; case GL_INVALID_OPERATION : return "GL_INVALID_OPERATION"; case GL_OUT_OF_MEMORY : return "GL_OUT_OF_MEMORY"; case GL_STACK_UNDERFLOW : return "GL_STACK_UNDERFLOW"; // Legacy; not used on GL3+ case GL_STACK_OVERFLOW : return "GL_STACK_OVERFLOW"; // Legacy; not used on GL3+ default : return "Unknown GL error"; } // switch (errorCode) } #else // DD_SAMPLES_NOGL defined using TimePoint = std::chrono::time_point; static TimePoint startupTime = std::chrono::high_resolution_clock::now(); static inline std::int64_t getTimeMilliseconds() { const auto currentTime = std::chrono::high_resolution_clock::now(); return std::chrono::duration_cast(currentTime - startupTime).count(); } static inline double getTimeSeconds() { return getTimeMilliseconds() * 0.001f; } #endif // DD_SAMPLES_NOGL // Prints error to standard error stream. static inline void errorF(const char * format, ...) { va_list args; va_start(args, format); std::vfprintf(stderr, format, args); va_end(args); // Default newline and flush (like std::endl) std::fputc('\n', stderr); std::fflush(stderr); } // Prints some of the compile-time build settings to stdout. static inline void printDDBuildConfig() { std::printf("\n"); #ifdef DEBUG_DRAW_CXX11_SUPPORTED std::printf("DEBUG_DRAW_CXX11_SUPPORTED = %u\n", DEBUG_DRAW_CXX11_SUPPORTED); #endif // DEBUG_DRAW_CXX11_SUPPORTED #ifdef DEBUG_DRAW_PER_THREAD_CONTEXT std::printf("DEBUG_DRAW_PER_THREAD_CONTEXT = %u\n", /*DEBUG_DRAW_PER_THREAD_CONTEXT*/1); #endif // DEBUG_DRAW_PER_THREAD_CONTEXT #ifdef DEBUG_DRAW_EXPLICIT_CONTEXT std::printf("DEBUG_DRAW_EXPLICIT_CONTEXT = %u\n", /*DEBUG_DRAW_EXPLICIT_CONTEXT*/1); #endif // DEBUG_DRAW_EXPLICIT_CONTEXT std::printf("DEBUG_DRAW_USE_STD_MATH = %u\n", DEBUG_DRAW_USE_STD_MATH); std::printf("DEBUG_DRAW_MAX_STRINGS = %u\n", DEBUG_DRAW_MAX_STRINGS); std::printf("DEBUG_DRAW_MAX_POINTS = %u\n", DEBUG_DRAW_MAX_POINTS); std::printf("DEBUG_DRAW_MAX_LINES = %u\n", DEBUG_DRAW_MAX_LINES); std::printf("DEBUG_DRAW_VERTEX_BUFFER_SIZE = %u\n", DEBUG_DRAW_VERTEX_BUFFER_SIZE); } // ======================================================== // Key/Mouse input + A simple 3D camera: // ======================================================== struct Keys { // For the first-person camera controls. bool wDown; bool sDown; bool aDown; bool dDown; // Flags: bool showLabels; // True if object labels are drawn. Toggle with the space bar. bool showGrid; // True if the ground grid is drawn. Toggle with the return key. } keys; struct Mouse { enum { MaxDelta = 100 }; int deltaX; int deltaY; int lastPosX; int lastPosY; bool leftButtonDown; bool rightButtonDown; } mouse; struct Time { float seconds; std::int64_t milliseconds; } deltaTime; struct Camera { // // Camera Axes: // // (up) // +Y +Z (forward) // | / // | / // | / // + ------ +X (right) // (eye) // Vector3 right; Vector3 up; Vector3 forward; Vector3 eye; Matrix4 viewMatrix; Matrix4 projMatrix; Matrix4 vpMatrix; // Frustum planes for clipping: enum { A, B, C, D }; Vector4 planes[6]; // Tunable values: float movementSpeed = 3.0f; float lookSpeed = 6.0f; enum MoveDir { Forward, // Move forward relative to the camera's space Back, // Move backward relative to the camera's space Left, // Move left relative to the camera's space Right // Move right relative to the camera's space }; Camera() { right = Vector3(1.0f, 0.0f, 0.0f); up = Vector3(0.0f, 1.0f, 0.0f); forward = Vector3(0.0f, 0.0f, 1.0f); eye = Vector3(0.0f, 0.0f, 0.0f); viewMatrix = Matrix4::identity(); vpMatrix = Matrix4::identity(); const float fovY = degToRad(60.0f); const float aspect = static_cast(WindowWidth) / static_cast(WindowHeight); projMatrix = Matrix4::perspective(fovY, aspect, 0.1f, 1000.0f); for (int i = 0; i < 6; ++i) { planes[i] = Vector4(0.0f); } } void pitch(const float angle) { // Pitches camera by 'angle' radians. forward = rotateAroundAxis(forward, right, angle); // Calculate new forward. up = cross(forward, right); // Calculate new camera up vector. } void rotate(const float angle) { // Rotates around world Y-axis by the given angle (in radians). const float sinAng = std::sin(angle); const float cosAng = std::cos(angle); float xxx, zzz; // Rotate forward vector: xxx = forward[0]; zzz = forward[2]; forward[0] = xxx * cosAng + zzz * sinAng; forward[2] = xxx * -sinAng + zzz * cosAng; // Rotate up vector: xxx = up[0]; zzz = up[2]; up[0] = xxx * cosAng + zzz * sinAng; up[2] = xxx * -sinAng + zzz * cosAng; // Rotate right vector: xxx = right[0]; zzz = right[2]; right[0] = xxx * cosAng + zzz * sinAng; right[2] = xxx * -sinAng + zzz * cosAng; } void move(const MoveDir dir, const float amount) { switch (dir) { case Camera::Forward : eye += forward * amount; break; case Camera::Back : eye -= forward * amount; break; case Camera::Left : eye += right * amount; break; case Camera::Right : eye -= right * amount; break; } } void checkKeyboardMovement() { const float moveSpeed = movementSpeed * deltaTime.seconds; if (keys.aDown) { move(Camera::Left, moveSpeed); } if (keys.dDown) { move(Camera::Right, moveSpeed); } if (keys.wDown) { move(Camera::Forward, moveSpeed); } if (keys.sDown) { move(Camera::Back, moveSpeed); } } void checkMouseRotation() { static const float maxAngle = 89.5f; // Max degrees of rotation static float pitchAmt; if (!mouse.leftButtonDown) { return; } const float rotateSpeed = lookSpeed * deltaTime.seconds; // Rotate left/right: float amt = static_cast(mouse.deltaX) * rotateSpeed; rotate(degToRad(-amt)); // Calculate amount to rotate up/down: amt = static_cast(mouse.deltaY) * rotateSpeed; // Clamp pitch amount: if ((pitchAmt + amt) <= -maxAngle) { amt = -maxAngle - pitchAmt; pitchAmt = -maxAngle; } else if ((pitchAmt + amt) >= maxAngle) { amt = maxAngle - pitchAmt; pitchAmt = maxAngle; } else { pitchAmt += amt; } pitch(degToRad(-amt)); } void updateMatrices() { viewMatrix = Matrix4::lookAt(Point3(eye), getTarget(), up); vpMatrix = projMatrix * viewMatrix; // Vectormath lib uses column-major OGL style, so multiply P*V*M // Compute and normalize the 6 frustum planes: const float * const m = toFloatPtr(vpMatrix); planes[0][A] = m[3] - m[0]; planes[0][B] = m[7] - m[4]; planes[0][C] = m[11] - m[8]; planes[0][D] = m[15] - m[12]; planes[0] = normalize(planes[0]); planes[1][A] = m[3] + m[0]; planes[1][B] = m[7] + m[4]; planes[1][C] = m[11] + m[8]; planes[1][D] = m[15] + m[12]; planes[1] = normalize(planes[1]); planes[2][A] = m[3] + m[1]; planes[2][B] = m[7] + m[5]; planes[2][C] = m[11] + m[9]; planes[2][D] = m[15] + m[13]; planes[2] = normalize(planes[2]); planes[3][A] = m[3] - m[1]; planes[3][B] = m[7] - m[5]; planes[3][C] = m[11] - m[9]; planes[3][D] = m[15] - m[13]; planes[3] = normalize(planes[3]); planes[4][A] = m[3] - m[2]; planes[4][B] = m[7] - m[6]; planes[4][C] = m[11] - m[10]; planes[4][D] = m[15] - m[14]; planes[4] = normalize(planes[4]); planes[5][A] = m[3] + m[2]; planes[5][B] = m[7] + m[6]; planes[5][C] = m[11] + m[10]; planes[5][D] = m[15] + m[14]; planes[5] = normalize(planes[5]); } Point3 getTarget() const { return Point3(eye[0] + forward[0], eye[1] + forward[1], eye[2] + forward[2]); } bool isPointInsideFrustum(const float x, const float y, const float z) const { for (int i = 0; i < 6; ++i) { if ((planes[i][A] * x + planes[i][B] * y + planes[i][C] * z + planes[i][D]) <= 0.0f) { return false; } } return true; } static Vector3 rotateAroundAxis(const Vector3 & vec, const Vector3 & axis, const float angle) { const float sinAng = std::sin(angle); const float cosAng = std::cos(angle); const float oneMinusCosAng = (1.0f - cosAng); const float aX = axis[0]; const float aY = axis[1]; const float aZ = axis[2]; float x = (aX * aX * oneMinusCosAng + cosAng) * vec[0] + (aX * aY * oneMinusCosAng + aZ * sinAng) * vec[1] + (aX * aZ * oneMinusCosAng - aY * sinAng) * vec[2]; float y = (aX * aY * oneMinusCosAng - aZ * sinAng) * vec[0] + (aY * aY * oneMinusCosAng + cosAng) * vec[1] + (aY * aZ * oneMinusCosAng + aX * sinAng) * vec[2]; float z = (aX * aZ * oneMinusCosAng + aY * sinAng) * vec[0] + (aY * aZ * oneMinusCosAng - aX * sinAng) * vec[1] + (aZ * aZ * oneMinusCosAng + cosAng) * vec[2]; return Vector3(x, y, z); } } camera; #ifndef DD_SAMPLES_NOGL // ======================================================== // Input callbacks for GLFW: // ======================================================== static void mousePositionCallback(GLFWwindow * window, const double xPos, const double yPos) { (void)window; // Unused. int mx = static_cast(xPos); int my = static_cast(yPos); // Clamp to window bounds: if (mx > WindowWidth) { mx = WindowWidth; } else if (mx < 0) { mx = 0; } if (my > WindowHeight) { my = WindowHeight; } else if (my < 0) { my = 0; } mouse.deltaX = mx - mouse.lastPosX; mouse.deltaY = my - mouse.lastPosY; mouse.lastPosX = mx; mouse.lastPosY = my; // Clamp between -/+ max delta: if (mouse.deltaX > Mouse::MaxDelta) { mouse.deltaX = Mouse::MaxDelta; } else if (mouse.deltaX < -Mouse::MaxDelta) { mouse.deltaX = -Mouse::MaxDelta; } if (mouse.deltaY > Mouse::MaxDelta) { mouse.deltaY = Mouse::MaxDelta; } else if (mouse.deltaY < -Mouse::MaxDelta) { mouse.deltaY = -Mouse::MaxDelta; } } static void mouseButtonCallback(GLFWwindow * window, const int button, const int action, const int mods) { // Unused. (void)window; (void)mods; if (button == GLFW_MOUSE_BUTTON_LEFT) { mouse.leftButtonDown = (action != GLFW_RELEASE); } else if (button == GLFW_MOUSE_BUTTON_RIGHT) { mouse.rightButtonDown = (action != GLFW_RELEASE); } } static void keyCallback(GLFWwindow * window, const int key, const int scancode, const int action, const int mods) { // Unused. (void)window; (void)scancode; (void)mods; if (key == GLFW_KEY_A || key == GLFW_KEY_LEFT) { keys.aDown = (action != GLFW_RELEASE); } else if (key == GLFW_KEY_D || key == GLFW_KEY_RIGHT) { keys.dDown = (action != GLFW_RELEASE); } else if (key == GLFW_KEY_W || key == GLFW_KEY_UP) { keys.wDown = (action != GLFW_RELEASE); } else if (key == GLFW_KEY_S || key == GLFW_KEY_DOWN) { keys.sDown = (action != GLFW_RELEASE); } // Toggleable flags: else if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) { keys.showLabels = !keys.showLabels; } else if (key == GLFW_KEY_ENTER && action == GLFW_PRESS) { keys.showGrid = !keys.showGrid; } } static void initInput(GLFWwindow * window) { std::memset(&keys, 0, sizeof(keys)); std::memset(&mouse, 0, sizeof(mouse)); // GLFW input callbacks: glfwSetCursorPosCallback(window, &mousePositionCallback); glfwSetMouseButtonCallback(window, &mouseButtonCallback); glfwSetKeyCallback(window, &keyCallback); } #endif // DD_SAMPLES_NOGL // ======================================================== // MainThreadChecker - test if the calling thread is main() // ======================================================== struct MainThreadChecker { const std::thread::id mainThreadId; MainThreadChecker() : mainThreadId(std::this_thread::get_id()) { } bool operator()() const { return std::this_thread::get_id() == mainThreadId; } } isMainThread; // ======================================================== // class JobQueue // ======================================================== class JobQueue final { public: typedef std::function Job; // Wait for the worker thread to exit. ~JobQueue() { if (worker.joinable()) { waitAll(); mutex.lock(); terminating = true; condition.notify_one(); mutex.unlock(); worker.join(); } } // Launch the worker thread. void launch() { assert(!worker.joinable()); // Not already launched! worker = std::thread(&JobQueue::queueLoop, this); } // Add a new job to the thread's queue. void pushJob(Job job) { std::lock_guard lock(mutex); queue.push(std::move(job)); condition.notify_one(); } // Wait until all work items have been completed. void waitAll() { std::unique_lock lock(mutex); condition.wait(lock, [this]() { return queue.empty(); }); } private: void queueLoop() { for (;;) { Job job; { std::unique_lock lock(mutex); condition.wait(lock, [this] { return !queue.empty() || terminating; }); if (terminating) { break; } job = queue.front(); } job(); { std::lock_guard lock(mutex); queue.pop(); condition.notify_one(); } } } bool terminating = false; std::thread worker; std::queue queue; std::mutex mutex; std::condition_variable condition; }; } // namespace ddSamplesCommon #endif // DD_SAMPLES_COMMON_HPP ================================================ FILE: samples/vectormath/LICENSE ================================================ Vector Math library for 3-D linear algebra (vector, matrix, quaternion) SIMD support for SSE, PowerPC (PPU) and the SPU. Also includes generic multi-platform scalar version. Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: samples/vectormath/SSE/cpp/boolInVec.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _BOOLINVEC_H #define _BOOLINVEC_H #include "defines.h" #include namespace Vectormath { class floatInVec; //-------------------------------------------------------------------------------------------------- // boolInVec class // _VECTORMATH_ALIGNED_TYPE_1 class boolInVec { private: __m128 mData; inline boolInVec(__m128 vec); public: inline boolInVec() {} // matches standard type conversions // inline boolInVec(const floatInVec &vec); // explicit cast from bool // explicit inline boolInVec(bool scalar); #ifdef _VECTORMATH_NO_SCALAR_CAST // explicit cast to bool // inline bool getAsBool() const; #else // implicit cast to bool // inline operator bool() const; #endif // get vector data // bool value is splatted across all word slots of vector as 0 (false) or -1 (true) // inline __m128 get128() const; // operators // inline const boolInVec operator ! () const; inline boolInVec& operator = (const boolInVec &vec); inline boolInVec& operator &= (const boolInVec &vec); inline boolInVec& operator ^= (const boolInVec &vec); inline boolInVec& operator |= (const boolInVec &vec); // friend functions // friend inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1); friend inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1); friend inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1); friend inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1); friend inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1); friend inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1); friend inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1); friend inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1); friend inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1); friend inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1); friend inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1); friend inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); } _VECTORMATH_ALIGNED_TYPE_2 ; //-------------------------------------------------------------------------------------------------- // boolInVec functions // // operators // inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1); inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1); inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1); inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1); inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1); // select between vec0 and vec1 using boolInVec. // false selects vec0, true selects vec1 // inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); } // namespace Vectormath //-------------------------------------------------------------------------------------------------- // boolInVec implementation // #include "floatInVec.h" namespace Vectormath { inline boolInVec::boolInVec(__m128 vec) { mData = vec; } inline boolInVec::boolInVec(const floatInVec &vec) { *this = (vec != floatInVec(0.0f)); } inline boolInVec::boolInVec(bool scalar) { unsigned int mask = -(int)scalar; mData = _mm_set1_ps(*(float *)&mask); // TODO: Union } #ifdef _VECTORMATH_NO_SCALAR_CAST inline bool boolInVec::getAsBool() const #else inline boolInVec::operator bool() const #endif { return *(bool *)&mData; } inline __m128 boolInVec::get128() const { return mData; } inline const boolInVec boolInVec::operator ! () const { return boolInVec(_mm_andnot_ps(mData, _mm_cmpneq_ps(_mm_setzero_ps(),_mm_setzero_ps()))); } inline boolInVec& boolInVec::operator = (const boolInVec &vec) { mData = vec.mData; return *this; } inline boolInVec& boolInVec::operator &= (const boolInVec &vec) { *this = *this & vec; return *this; } inline boolInVec& boolInVec::operator ^= (const boolInVec &vec) { *this = *this ^ vec; return *this; } inline boolInVec& boolInVec::operator |= (const boolInVec &vec) { *this = *this | vec; return *this; } inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); } inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); } inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_and_ps(vec0.get128(), vec1.get128())); } inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_or_ps(vec0.get128(), vec1.get128())); } inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_xor_ps(vec0.get128(), vec1.get128())); } inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1) { return boolInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); } } // namespace Vectormath #endif // boolInVec_h ================================================ FILE: samples/vectormath/SSE/cpp/defines.h ================================================ // ================================================================================================ // -*- C++ -*- // File: defines.h // Author: Guilherme R. Lampert // Created on: 22/03/13 // Brief: Added this header with some defines to make the SSE library Unix friendly. // ================================================================================================ #ifndef _VECTORMATH_DEFINES_H #define _VECTORMATH_DEFINES_H #if defined (_MSC_VER) // Visual Studio (MS compiler) #define _VECTORMATH_ALIGNED(type) __declspec(align(16)) type #define _VECTORMATH_ALIGNED_TYPE_1 __declspec(align(16)) #define _VECTORMATH_ALIGNED_TYPE_2 #elif defined (__GNUC__) // GCC #define _VECTORMATH_ALIGNED(type) type __attribute__((aligned(16))) #define _VECTORMATH_ALIGNED_TYPE_1 #define _VECTORMATH_ALIGNED_TYPE_2 __attribute__((aligned(16))) #else // Unknown #error "Define _VECTORMATH_ALIGNED for your compiler" #endif #endif // _VECTORMATH_DEFINES_H ================================================ FILE: samples/vectormath/SSE/cpp/floatInVec.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _FLOATINVEC_H #define _FLOATINVEC_H #include #include namespace Vectormath { class boolInVec; //-------------------------------------------------------------------------------------------------- // floatInVec class // _VECTORMATH_ALIGNED_TYPE_1 class floatInVec { private: __m128 mData; public: inline floatInVec(__m128 vec); inline floatInVec() {} // matches standard type conversions // inline floatInVec(const boolInVec &vec); // construct from a slot of __m128 // inline floatInVec(__m128 vec, int slot); // explicit cast from float // explicit inline floatInVec(float scalar); #ifdef _VECTORMATH_NO_SCALAR_CAST // explicit cast to float // inline float getAsFloat() const; #else // implicit cast to float // inline operator float() const; #endif // get vector data // float value is splatted across all word slots of vector // inline __m128 get128() const; // operators // inline const floatInVec operator ++ (int); inline const floatInVec operator -- (int); inline floatInVec& operator ++ (); inline floatInVec& operator -- (); inline const floatInVec operator - () const; inline floatInVec& operator = (const floatInVec &vec); inline floatInVec& operator *= (const floatInVec &vec); inline floatInVec& operator /= (const floatInVec &vec); inline floatInVec& operator += (const floatInVec &vec); inline floatInVec& operator -= (const floatInVec &vec); // friend functions // friend inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1); friend inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1); friend inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1); friend inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1); friend inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, boolInVec select_vec1); } _VECTORMATH_ALIGNED_TYPE_2 ; //-------------------------------------------------------------------------------------------------- // floatInVec functions // // operators // inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1); inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1); inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1); inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1); inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1); inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1); inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1); inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1); inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1); inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1); // select between vec0 and vec1 using boolInVec. // false selects vec0, true selects vec1 // inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1); } // namespace Vectormath //-------------------------------------------------------------------------------------------------- // floatInVec implementation // #include "boolInVec.h" namespace Vectormath { inline floatInVec::floatInVec(__m128 vec) { mData = vec; } inline floatInVec::floatInVec(const boolInVec &vec) { mData = vec_sel(_mm_setzero_ps(), _mm_set1_ps(1.0f), vec.get128()); } inline floatInVec::floatInVec(__m128 vec, int slot) { SSEFloat v; v.m128 = vec; mData = _mm_set1_ps(v.f[slot]); } inline floatInVec::floatInVec(float scalar) { mData = _mm_set1_ps(scalar); } #ifdef _VECTORMATH_NO_SCALAR_CAST inline float floatInVec::getAsFloat() const #else inline floatInVec::operator float() const #endif { return *((float *)&mData); } inline __m128 floatInVec::get128() const { return mData; } inline const floatInVec floatInVec::operator ++ (int) { __m128 olddata = mData; operator ++(); return floatInVec(olddata); } inline const floatInVec floatInVec::operator -- (int) { __m128 olddata = mData; operator --(); return floatInVec(olddata); } inline floatInVec& floatInVec::operator ++ () { *this += floatInVec(_mm_set1_ps(1.0f)); return *this; } inline floatInVec& floatInVec::operator -- () { *this -= floatInVec(_mm_set1_ps(1.0f)); return *this; } inline const floatInVec floatInVec::operator - () const { return floatInVec(_mm_sub_ps(_mm_setzero_ps(), mData)); } inline floatInVec& floatInVec::operator = (const floatInVec &vec) { mData = vec.mData; return *this; } inline floatInVec& floatInVec::operator *= (const floatInVec &vec) { *this = *this * vec; return *this; } inline floatInVec& floatInVec::operator /= (const floatInVec &vec) { *this = *this / vec; return *this; } inline floatInVec& floatInVec::operator += (const floatInVec &vec) { *this = *this + vec; return *this; } inline floatInVec& floatInVec::operator -= (const floatInVec &vec) { *this = *this - vec; return *this; } inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1) { return floatInVec(_mm_mul_ps(vec0.get128(), vec1.get128())); } inline const floatInVec operator / (const floatInVec &num, const floatInVec &den) { return floatInVec(_mm_div_ps(num.get128(), den.get128())); } inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1) { return floatInVec(_mm_add_ps(vec0.get128(), vec1.get128())); } inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1) { return floatInVec(_mm_sub_ps(vec0.get128(), vec1.get128())); } inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1) { return boolInVec(_mm_cmpgt_ps(vec1.get128(), vec0.get128())); } inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1) { return boolInVec(_mm_cmpge_ps(vec1.get128(), vec0.get128())); } inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1) { return boolInVec(_mm_cmpgt_ps(vec0.get128(), vec1.get128())); } inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1) { return boolInVec(_mm_cmpge_ps(vec0.get128(), vec1.get128())); } inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1) { return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); } inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1) { return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); } inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1) { return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); } } // namespace Vectormath #endif // floatInVec_h ================================================ FILE: samples/vectormath/SSE/cpp/mat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_CPP_H #define _VECTORMATH_MAT_AOS_CPP_H #include "defines.h" namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // Constants // for shuffles, words are labeled [x,y,z,w] [a,b,c,d] #define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z }) #define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y }) #define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PI_OVER_2 1.570796327f //----------------------------------------------------------------------------- // Definitions inline Matrix3::Matrix3( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; } inline Matrix3::Matrix3( float scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); } inline Matrix3::Matrix3( const floatInVec &scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); } inline Matrix3::Matrix3( const Quat &unitQuat ) { __m128 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; __m128 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; _VECTORMATH_ALIGNED(unsigned int sx[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int sz[4]) = {0, 0, 0xffffffff, 0}; __m128 select_x = _mm_load_ps((float *)sx); __m128 select_z = _mm_load_ps((float *)sz); xyzw_2 = _mm_add_ps( unitQuat.get128(), unitQuat.get128() ); wwww = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,3,3,3) ); yzxw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,0,2,1) ); zxyw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,1,0,2) ); yzxw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,0,2,1) ); zxyw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,1,0,2) ); tmp0 = _mm_mul_ps( yzxw_2, wwww ); // tmp0 = 2yw, 2zw, 2xw, 2w2 tmp1 = _mm_sub_ps( _mm_set1_ps(1.0f), _mm_mul_ps(yzxw, yzxw_2) ); // tmp1 = 1 - 2y2, 1 - 2z2, 1 - 2x2, 1 - 2w2 tmp2 = _mm_mul_ps( yzxw, xyzw_2 ); // tmp2 = 2xy, 2yz, 2xz, 2w2 tmp0 = _mm_add_ps( _mm_mul_ps(zxyw, xyzw_2), tmp0 ); // tmp0 = 2yw + 2zx, 2zw + 2xy, 2xw + 2yz, 2w2 + 2w2 tmp1 = _mm_sub_ps( tmp1, _mm_mul_ps(zxyw, zxyw_2) ); // tmp1 = 1 - 2y2 - 2z2, 1 - 2z2 - 2x2, 1 - 2x2 - 2y2, 1 - 2w2 - 2w2 tmp2 = _mm_sub_ps( tmp2, _mm_mul_ps(zxyw_2, wwww) ); // tmp2 = 2xy - 2zw, 2yz - 2xw, 2xz - 2yw, 2w2 -2w2 tmp3 = vec_sel( tmp0, tmp1, select_x ); tmp4 = vec_sel( tmp1, tmp2, select_x ); tmp5 = vec_sel( tmp2, tmp0, select_x ); mCol0 = Vector3( vec_sel( tmp3, tmp2, select_z ) ); mCol1 = Vector3( vec_sel( tmp4, tmp0, select_z ) ); mCol2 = Vector3( vec_sel( tmp5, tmp1, select_z ) ); } inline Matrix3::Matrix3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; } inline Matrix3 & Matrix3::setCol0( const Vector3 &_col0 ) { mCol0 = _col0; return *this; } inline Matrix3 & Matrix3::setCol1( const Vector3 &_col1 ) { mCol1 = _col1; return *this; } inline Matrix3 & Matrix3::setCol2( const Vector3 &_col2 ) { mCol2 = _col2; return *this; } inline Matrix3 & Matrix3::setCol( int col, const Vector3 &vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix3 & Matrix3::setRow( int row, const Vector3 &vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); return *this; } inline Matrix3 & Matrix3::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline Matrix3 & Matrix3::setElem( int col, int row, const floatInVec &val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline const floatInVec Matrix3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Matrix3::getCol0( ) const { return mCol0; } inline const Vector3 Matrix3::getCol1( ) const { return mCol1; } inline const Vector3 Matrix3::getCol2( ) const { return mCol2; } inline const Vector3 Matrix3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector3 Matrix3::getRow( int row ) const { return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); } inline Vector3 & Matrix3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Matrix3::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; return *this; } inline const Matrix3 transpose( const Matrix3 & mat ) { __m128 tmp0, tmp1, res0, res1, res2; tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); res0 = vec_mergeh( tmp0, mat.getCol1().get128() ); //res1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; res1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); res1 = vec_sel(res1, mat.getCol1().get128(), select_y); //res2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); res2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); res2 = vec_sel(res2, vec_splat(mat.getCol1().get128(), 2), select_y); return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 inverse( const Matrix3 & mat ) { __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() ); tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() ); tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() ); dot = _vmathVfDot3( tmp2, mat.getCol2().get128() ); dot = vec_splat( dot, 0 ); invdet = recipf4( dot ); tmp3 = vec_mergeh( tmp0, tmp2 ); tmp4 = vec_mergel( tmp0, tmp2 ); inv0 = vec_mergeh( tmp3, tmp1 ); //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; inv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2)); inv1 = vec_sel(inv1, tmp1, select_y); //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); inv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0)); inv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y); inv0 = vec_mul( inv0, invdet ); inv1 = vec_mul( inv1, invdet ); inv2 = vec_mul( inv2, invdet ); return Matrix3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ) ); } inline const floatInVec determinant( const Matrix3 & mat ) { return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); } inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const { return Matrix3( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ) ); } inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const { return Matrix3( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) { *this = *this + mat; return *this; } inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) { *this = *this - mat; return *this; } inline const Matrix3 Matrix3::operator -( ) const { return Matrix3( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ) ); } inline const Matrix3 absPerElem( const Matrix3 & mat ) { return Matrix3( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ) ); } inline const Matrix3 Matrix3::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Matrix3 Matrix3::operator *( const floatInVec &scalar ) const { return Matrix3( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ) ); } inline Matrix3 & Matrix3::operator *=( float scalar ) { return *this *= floatInVec(scalar); } inline Matrix3 & Matrix3::operator *=( const floatInVec &scalar ) { *this = *this * scalar; return *this; } inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) { return floatInVec(scalar) * mat; } inline const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat ) { return mat * scalar; } inline const Vector3 Matrix3::operator *( const Vector3 &vec ) const { __m128 res; __m128 xxxx, yyyy, zzzz; xxxx = vec_splat( vec.get128(), 0 ); yyyy = vec_splat( vec.get128(), 1 ); zzzz = vec_splat( vec.get128(), 2 ); res = vec_mul( mCol0.get128(), xxxx ); res = vec_madd( mCol1.get128(), yyyy, res ); res = vec_madd( mCol2.get128(), zzzz, res ); return Vector3( res ); } inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const { return Matrix3( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) { *this = *this * mat; return *this; } inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) { return Matrix3( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ) ); } inline const Matrix3 Matrix3::identity( ) { return Matrix3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationX( float radians ) { return rotationX( floatInVec(radians) ); } inline const Matrix3 Matrix3::rotationX( const floatInVec &radians ) { __m128 s, c, res1, res2; __m128 zero; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); return Matrix3( Vector3::xAxis( ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 Matrix3::rotationY( float radians ) { return rotationY( floatInVec(radians) ); } inline const Matrix3 Matrix3::rotationY( const floatInVec &radians ) { __m128 s, c, res0, res2; __m128 zero; _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); return Matrix3( Vector3( res0 ), Vector3::yAxis( ), Vector3( res2 ) ); } inline const Matrix3 Matrix3::rotationZ( float radians ) { return rotationZ( floatInVec(radians) ); } inline const Matrix3 Matrix3::rotationZ( const floatInVec &radians ) { __m128 s, c, res0, res1; __m128 zero; _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationZYX( const Vector3 &radiansXYZ ) { __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; angles = Vector4( radiansXYZ, 0.0f ).get128(); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); _VECTORMATH_ALIGNED(unsigned int select_xyz[4]) = {0xffffffff, 0xffffffff, 0xffffffff, 0}; Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_mul( Z0, Y1 ); return Matrix3( Vector3( vec_mul( Z0, Y0 ) ), Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ) ); } inline const Matrix3 Matrix3::rotation( float radians, const Vector3 &unitVec ) { return rotation( floatInVec(radians), unitVec ); } inline const Matrix3 Matrix3::rotation( const floatInVec &radians, const Vector3 &unitVec ) { __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; axis = unitVec.get128(); sincosf4( radians.get128(), &s, &c ); xxxx = vec_splat( axis, 0 ); yyyy = vec_splat( axis, 1 ); zzzz = vec_splat( axis, 2 ); oneMinusC = vec_sub( _mm_set1_ps(1.0f), c ); axisS = vec_mul( axis, s ); negAxisS = negatef4( axisS ); _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); tmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) ); tmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z); //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); tmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x ); //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); tmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) ); tmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y); tmp0 = vec_sel( tmp0, c, select_x ); tmp1 = vec_sel( tmp1, c, select_y ); tmp2 = vec_sel( tmp2, c, select_z ); return Matrix3( Vector3( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ), Vector3( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ), Vector3( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ) ); } inline const Matrix3 Matrix3::rotation( const Quat &unitQuat ) { return Matrix3( unitQuat ); } inline const Matrix3 Matrix3::scale( const Vector3 &scaleVec ) { __m128 zero = _mm_setzero_ps(); _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; return Matrix3( Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ), Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ), Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ) ); } inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec ) { return Matrix3( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ) ); } inline const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat ) { return Matrix3( mulPerElem( mat.getCol0(), scaleVec ), mulPerElem( mat.getCol1(), scaleVec ), mulPerElem( mat.getCol2(), scaleVec ) ); } inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) { return Matrix3( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ) ); } inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 ) { return Matrix3( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix3 & mat ) { print( mat.getRow( 0 ) ); print( mat.getRow( 1 ) ); print( mat.getRow( 2 ) ); } inline void print( const Matrix3 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Matrix4::Matrix4( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; } inline Matrix4::Matrix4( float scalar ) { mCol0 = Vector4( scalar ); mCol1 = Vector4( scalar ); mCol2 = Vector4( scalar ); mCol3 = Vector4( scalar ); } inline Matrix4::Matrix4( const floatInVec &scalar ) { mCol0 = Vector4( scalar ); mCol1 = Vector4( scalar ); mCol2 = Vector4( scalar ); mCol3 = Vector4( scalar ); } inline Matrix4::Matrix4( const Transform3 & mat ) { mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( mat.getCol3(), 1.0f ); } inline Matrix4::Matrix4( const Vector4 &_col0, const Vector4 &_col1, const Vector4 &_col2, const Vector4 &_col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 &translateVec ) { mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( translateVec, 1.0f ); } inline Matrix4::Matrix4( const Quat &unitQuat, const Vector3 &translateVec ) { Matrix3 mat; mat = Matrix3( unitQuat ); mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( translateVec, 1.0f ); } inline Matrix4 & Matrix4::setCol0( const Vector4 &_col0 ) { mCol0 = _col0; return *this; } inline Matrix4 & Matrix4::setCol1( const Vector4 &_col1 ) { mCol1 = _col1; return *this; } inline Matrix4 & Matrix4::setCol2( const Vector4 &_col2 ) { mCol2 = _col2; return *this; } inline Matrix4 & Matrix4::setCol3( const Vector4 &_col3 ) { mCol3 = _col3; return *this; } inline Matrix4 & Matrix4::setCol( int col, const Vector4 &vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix4 & Matrix4::setRow( int row, const Vector4 &vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Matrix4 & Matrix4::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline Matrix4 & Matrix4::setElem( int col, int row, const floatInVec &val ) { Vector4 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline const floatInVec Matrix4::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector4 Matrix4::getCol0( ) const { return mCol0; } inline const Vector4 Matrix4::getCol1( ) const { return mCol1; } inline const Vector4 Matrix4::getCol2( ) const { return mCol2; } inline const Vector4 Matrix4::getCol3( ) const { return mCol3; } inline const Vector4 Matrix4::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Matrix4::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector4 & Matrix4::operator []( int col ) { return *(&mCol0 + col); } inline const Vector4 Matrix4::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; return *this; } inline const Matrix4 transpose( const Matrix4 & mat ) { __m128 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); tmp1 = vec_mergeh( mat.getCol1().get128(), mat.getCol3().get128() ); tmp2 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); tmp3 = vec_mergel( mat.getCol1().get128(), mat.getCol3().get128() ); res0 = vec_mergeh( tmp0, tmp1 ); res1 = vec_mergel( tmp0, tmp1 ); res2 = vec_mergeh( tmp2, tmp3 ); res3 = vec_mergel( tmp2, tmp3 ); return Matrix4( Vector4( res0 ), Vector4( res1 ), Vector4( res2 ), Vector4( res3 ) ); } inline const Matrix4 inverse( const Matrix4 & mat ) { static _VECTORMATH_ALIGNED(const unsigned int _vmathPNPN[4]) = {0x00000000, 0x80000000, 0x00000000, 0x80000000}; static _VECTORMATH_ALIGNED(const unsigned int _vmathNPNP[4]) = {0x80000000, 0x00000000, 0x80000000, 0x00000000}; static _VECTORMATH_ALIGNED(const float _vmathZERONE[4]) = {1.0f, 0.0f, 0.0f, 1.0f}; __m128 Va,Vb,Vc; __m128 r1,r2,r3,tt,tt2; __m128 sum,Det,RDet; __m128 trns0,trns1,trns2,trns3; __m128 _L1 = mat.getCol0().get128(); __m128 _L2 = mat.getCol1().get128(); __m128 _L3 = mat.getCol2().get128(); __m128 _L4 = mat.getCol3().get128(); // Calculating the minterms for the first line. // _mm_ror_ps is just a macro using _mm_shuffle_ps(). tt = _L4; tt2 = _mm_ror_ps(_L3,1); Vc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0)); // V3'V4 Va = _mm_mul_ps(tt2,_mm_ror_ps(tt,2)); // V3'V4" Vb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3)); // V3'V4^ r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V3"V4^ - V3^V4" r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V3^V4' - V3'V4^ r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V3'V4" - V3"V4' tt = _L2; Va = _mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1); Vb = _mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2)); Vc = _mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3)); // Calculating the determinant. Det = _mm_mul_ps(sum,_L1); Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det)); const __m128 Sign_PNPN = _mm_load_ps((float *)_vmathPNPN); const __m128 Sign_NPNP = _mm_load_ps((float *)_vmathNPNP); __m128 mtL1 = _mm_xor_ps(sum,Sign_PNPN); // Calculating the minterms of the second line (using previous results). tt = _mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1); tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); __m128 mtL2 = _mm_xor_ps(sum,Sign_NPNP); // Testing the determinant. Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1)); // Calculating the minterms of the third line. tt = _mm_ror_ps(_L1,1); Va = _mm_mul_ps(tt,Vb); // V1'V2" Vb = _mm_mul_ps(tt,Vc); // V1'V2^ Vc = _mm_mul_ps(tt,_L2); // V1'V2 r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V1"V2^ - V1^V2" r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V1^V2' - V1'V2^ r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V1'V2" - V1"V2' tt = _mm_ror_ps(_L4,1); sum = _mm_mul_ps(tt,r1); tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); __m128 mtL3 = _mm_xor_ps(sum,Sign_PNPN); // Dividing is FASTER than rcp_nr! (Because rcp_nr causes many register-memory RWs). RDet = _mm_div_ss(_mm_load_ss((float *)&_vmathZERONE), Det); // TODO: just 1.0f? RDet = _mm_shuffle_ps(RDet,RDet,0x00); // Devide the first 12 minterms with the determinant. mtL1 = _mm_mul_ps(mtL1, RDet); mtL2 = _mm_mul_ps(mtL2, RDet); mtL3 = _mm_mul_ps(mtL3, RDet); // Calculate the minterms of the forth line and devide by the determinant. tt = _mm_ror_ps(_L3,1); sum = _mm_mul_ps(tt,r1); tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); __m128 mtL4 = _mm_xor_ps(sum,Sign_NPNP); mtL4 = _mm_mul_ps(mtL4, RDet); // Now we just have to transpose the minterms matrix. trns0 = _mm_unpacklo_ps(mtL1,mtL2); trns1 = _mm_unpacklo_ps(mtL3,mtL4); trns2 = _mm_unpackhi_ps(mtL1,mtL2); trns3 = _mm_unpackhi_ps(mtL3,mtL4); _L1 = _mm_movelh_ps(trns0,trns1); _L2 = _mm_movehl_ps(trns1,trns0); _L3 = _mm_movelh_ps(trns2,trns3); _L4 = _mm_movehl_ps(trns3,trns2); return Matrix4( Vector4( _L1 ), Vector4( _L2 ), Vector4( _L3 ), Vector4( _L4 ) ); } inline const Matrix4 affineInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( inverse( affineMat ) ); } inline const Matrix4 orthoInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( orthoInverse( affineMat ) ); } inline const floatInVec determinant( const Matrix4 & mat ) { __m128 Va,Vb,Vc; __m128 r1,r2,r3,tt,tt2; __m128 sum,Det; __m128 _L1 = mat.getCol0().get128(); __m128 _L2 = mat.getCol1().get128(); __m128 _L3 = mat.getCol2().get128(); __m128 _L4 = mat.getCol3().get128(); // Calculating the minterms for the first line. // _mm_ror_ps is just a macro using _mm_shuffle_ps(). tt = _L4; tt2 = _mm_ror_ps(_L3,1); Vc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0)); // V3'V4 Va = _mm_mul_ps(tt2,_mm_ror_ps(tt,2)); // V3'V4" Vb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3)); // V3'V4^ r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V3"V4^ - V3^V4" r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V3^V4' - V3'V4^ r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V3'V4" - V3"V4' tt = _L2; Va = _mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1); Vb = _mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2)); Vc = _mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3)); // Calculating the determinant. Det = _mm_mul_ps(sum,_L1); Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det)); // Calculating the minterms of the second line (using previous results). tt = _mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1); tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); // Testing the determinant. Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1)); return floatInVec(Det, 0); } inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const { return Matrix4( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ), ( mCol3 + mat.mCol3 ) ); } inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const { return Matrix4( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ), ( mCol3 - mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) { *this = *this + mat; return *this; } inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) { *this = *this - mat; return *this; } inline const Matrix4 Matrix4::operator -( ) const { return Matrix4( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ), ( -mCol3 ) ); } inline const Matrix4 absPerElem( const Matrix4 & mat ) { return Matrix4( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ), absPerElem( mat.getCol3() ) ); } inline const Matrix4 Matrix4::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Matrix4 Matrix4::operator *( const floatInVec &scalar ) const { return Matrix4( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ), ( mCol3 * scalar ) ); } inline Matrix4 & Matrix4::operator *=( float scalar ) { return *this *= floatInVec(scalar); } inline Matrix4 & Matrix4::operator *=( const floatInVec &scalar ) { *this = *this * scalar; return *this; } inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) { return floatInVec(scalar) * mat; } inline const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat ) { return mat * scalar; } inline const Vector4 Matrix4::operator *( const Vector4 &vec ) const { return Vector4( _mm_add_ps( _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)))), _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))))) ); } inline const Vector4 Matrix4::operator *( const Vector3 &vec ) const { return Vector4( _mm_add_ps( _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)))), _mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2)))) ); } inline const Vector4 Matrix4::operator *( const Point3 &pnt ) const { return Vector4( _mm_add_ps( _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)))), _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(2,2,2,2))), mCol3.get128())) ); } inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const { return Matrix4( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ), ( *this * mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) { *this = *this * mat; return *this; } inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const { return Matrix4( ( *this * tfrm.getCol0() ), ( *this * tfrm.getCol1() ), ( *this * tfrm.getCol2() ), ( *this * Point3( tfrm.getCol3() ) ) ); } inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) { return Matrix4( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ), mulPerElem( mat0.getCol3(), mat1.getCol3() ) ); } inline const Matrix4 Matrix4::identity( ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) { mCol0.setXYZ( mat3.getCol0() ); mCol1.setXYZ( mat3.getCol1() ); mCol2.setXYZ( mat3.getCol2() ); return *this; } inline const Matrix3 Matrix4::getUpper3x3( ) const { return Matrix3( mCol0.getXYZ( ), mCol1.getXYZ( ), mCol2.getXYZ( ) ); } inline Matrix4 & Matrix4::setTranslation( const Vector3 &translateVec ) { mCol3.setXYZ( translateVec ); return *this; } inline const Vector3 Matrix4::getTranslation( ) const { return mCol3.getXYZ( ); } inline const Matrix4 Matrix4::rotationX( float radians ) { return rotationX( floatInVec(radians) ); } inline const Matrix4 Matrix4::rotationX( const floatInVec &radians ) { __m128 s, c, res1, res2; __m128 zero; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); return Matrix4( Vector4::xAxis( ), Vector4( res1 ), Vector4( res2 ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationY( float radians ) { return rotationY( floatInVec(radians) ); } inline const Matrix4 Matrix4::rotationY( const floatInVec &radians ) { __m128 s, c, res0, res2; __m128 zero; _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); return Matrix4( Vector4( res0 ), Vector4::yAxis( ), Vector4( res2 ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZ( float radians ) { return rotationZ( floatInVec(radians) ); } inline const Matrix4 Matrix4::rotationZ( const floatInVec &radians ) { __m128 s, c, res0, res1; __m128 zero; _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); return Matrix4( Vector4( res0 ), Vector4( res1 ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZYX( const Vector3 &radiansXYZ ) { __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; angles = Vector4( radiansXYZ, 0.0f ).get128(); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); _VECTORMATH_ALIGNED(unsigned int select_xyz[4]) = {0xffffffff, 0xffffffff, 0xffffffff, 0}; Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_mul( Z0, Y1 ); return Matrix4( Vector4( vec_mul( Z0, Y0 ) ), Vector4( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), Vector4( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( float radians, const Vector3 &unitVec ) { return rotation( floatInVec(radians), unitVec ); } inline const Matrix4 Matrix4::rotation( const floatInVec &radians, const Vector3 &unitVec ) { __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; axis = unitVec.get128(); sincosf4( radians.get128(), &s, &c ); xxxx = vec_splat( axis, 0 ); yyyy = vec_splat( axis, 1 ); zzzz = vec_splat( axis, 2 ); oneMinusC = vec_sub( _mm_set1_ps(1.0f), c ); axisS = vec_mul( axis, s ); negAxisS = negatef4( axisS ); _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); tmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) ); tmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z); //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); tmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x ); //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); tmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) ); tmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y); tmp0 = vec_sel( tmp0, c, select_x ); tmp1 = vec_sel( tmp1, c, select_y ); tmp2 = vec_sel( tmp2, c, select_z ); _VECTORMATH_ALIGNED(unsigned int select_xyz[4]) = {0xffffffff, 0xffffffff, 0xffffffff, 0}; axis = vec_and( axis, _mm_load_ps( (float *)select_xyz ) ); tmp0 = vec_and( tmp0, _mm_load_ps( (float *)select_xyz ) ); tmp1 = vec_and( tmp1, _mm_load_ps( (float *)select_xyz ) ); tmp2 = vec_and( tmp2, _mm_load_ps( (float *)select_xyz ) ); return Matrix4( Vector4( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ), Vector4( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ), Vector4( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( const Quat &unitQuat ) { return Matrix4( Transform3::rotation( unitQuat ) ); } inline const Matrix4 Matrix4::scale( const Vector3 &scaleVec ) { __m128 zero = _mm_setzero_ps(); _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; return Matrix4( Vector4( vec_sel( zero, scaleVec.get128(), select_x ) ), Vector4( vec_sel( zero, scaleVec.get128(), select_y ) ), Vector4( vec_sel( zero, scaleVec.get128(), select_z ) ), Vector4::wAxis( ) ); } inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec ) { return Matrix4( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ), mat.getCol3() ); } inline const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat ) { Vector4 scale4; scale4 = Vector4( scaleVec, 1.0f ); return Matrix4( mulPerElem( mat.getCol0(), scale4 ), mulPerElem( mat.getCol1(), scale4 ), mulPerElem( mat.getCol2(), scale4 ), mulPerElem( mat.getCol3(), scale4 ) ); } inline const Matrix4 Matrix4::translation( const Vector3 &translateVec ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4( translateVec, 1.0f ) ); } inline const Matrix4 Matrix4::lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec ) { Matrix4 m4EyeFrame; Vector3 v3X, v3Y, v3Z; v3Y = normalize( upVec ); v3Z = normalize( ( eyePos - lookAtPos ) ); v3X = normalize( cross( v3Y, v3Z ) ); v3Y = cross( v3Z, v3X ); m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); return orthoInverse( m4EyeFrame ); } inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) { float f, rangeInv; __m128 zero, col0, col1, col2, col3; union { __m128 v; float s[4]; } tmp; f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f ); rangeInv = 1.0f / ( zNear - zFar ); zero = _mm_setzero_ps(); tmp.v = zero; tmp.s[0] = f / aspect; col0 = tmp.v; tmp.v = zero; tmp.s[1] = f; col1 = tmp.v; tmp.v = zero; tmp.s[2] = ( zNear + zFar ) * rangeInv; tmp.s[3] = -1.0f; col2 = tmp.v; tmp.v = zero; tmp.s[2] = zNear * zFar * rangeInv * 2.0f; col3 = tmp.v; return Matrix4( Vector4( col0 ), Vector4( col1 ), Vector4( col2 ), Vector4( col3 ) ); } inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ __m128 lbf, rtn; __m128 diff, sum, inv_diff; __m128 diagonal, column, near2; __m128 zero = _mm_setzero_ps(); union { __m128 v; float s[4]; } l, f, r, n, b, t; // TODO: Union? l.s[0] = left; f.s[0] = zFar; r.s[0] = right; n.s[0] = zNear; b.s[0] = bottom; t.s[0] = top; lbf = vec_mergeh( l.v, f.v ); rtn = vec_mergeh( r.v, n.v ); lbf = vec_mergeh( lbf, b.v ); rtn = vec_mergeh( rtn, t.v ); diff = vec_sub( rtn, lbf ); sum = vec_add( rtn, lbf ); inv_diff = recipf4( diff ); near2 = vec_splat( n.v, 0 ); near2 = vec_add( near2, near2 ); diagonal = vec_mul( near2, inv_diff ); column = vec_mul( sum, inv_diff ); _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; _VECTORMATH_ALIGNED(unsigned int select_w[4]) = {0, 0, 0, 0xffffffff}; return Matrix4( Vector4( vec_sel( zero, diagonal, select_x ) ), Vector4( vec_sel( zero, diagonal, select_y ) ), Vector4( vec_sel( column, _mm_set1_ps(-1.0f), select_w ) ), Vector4( vec_sel( zero, vec_mul( diagonal, vec_splat( f.v, 0 ) ), select_z ) ) ); } inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ __m128 lbf, rtn; __m128 diff, sum, inv_diff, neg_inv_diff; __m128 diagonal, column; __m128 zero = _mm_setzero_ps(); union { __m128 v; float s[4]; } l, f, r, n, b, t; l.s[0] = left; f.s[0] = zFar; r.s[0] = right; n.s[0] = zNear; b.s[0] = bottom; t.s[0] = top; lbf = vec_mergeh( l.v, f.v ); rtn = vec_mergeh( r.v, n.v ); lbf = vec_mergeh( lbf, b.v ); rtn = vec_mergeh( rtn, t.v ); diff = vec_sub( rtn, lbf ); sum = vec_add( rtn, lbf ); inv_diff = recipf4( diff ); neg_inv_diff = negatef4( inv_diff ); diagonal = vec_add( inv_diff, inv_diff ); _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; _VECTORMATH_ALIGNED(unsigned int select_w[4]) = {0, 0, 0, 0xffffffff}; column = vec_mul( sum, vec_sel( neg_inv_diff, inv_diff, select_z ) ); // TODO: no madds with zero return Matrix4( Vector4( vec_sel( zero, diagonal, select_x ) ), Vector4( vec_sel( zero, diagonal, select_y ) ), Vector4( vec_sel( zero, diagonal, select_z ) ), Vector4( vec_sel( column, _mm_set1_ps(1.0f), select_w ) ) ); } inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) { return Matrix4( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ), select( mat0.getCol3(), mat1.getCol3(), select1 ) ); } inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 ) { return Matrix4( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ), select( mat0.getCol3(), mat1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix4 & mat ) { print( mat.getRow( 0 ) ); print( mat.getRow( 1 ) ); print( mat.getRow( 2 ) ); print( mat.getRow( 3 ) ); } inline void print( const Matrix4 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Transform3::Transform3( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; } inline Transform3::Transform3( float scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); mCol3 = Vector3( scalar ); } inline Transform3::Transform3( const floatInVec &scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); mCol3 = Vector3( scalar ); } inline Transform3::Transform3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2, const Vector3 &_col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 &translateVec ) { this->setUpper3x3( tfrm ); this->setTranslation( translateVec ); } inline Transform3::Transform3( const Quat &unitQuat, const Vector3 &translateVec ) { this->setUpper3x3( Matrix3( unitQuat ) ); this->setTranslation( translateVec ); } inline Transform3 & Transform3::setCol0( const Vector3 &_col0 ) { mCol0 = _col0; return *this; } inline Transform3 & Transform3::setCol1( const Vector3 &_col1 ) { mCol1 = _col1; return *this; } inline Transform3 & Transform3::setCol2( const Vector3 &_col2 ) { mCol2 = _col2; return *this; } inline Transform3 & Transform3::setCol3( const Vector3 &_col3 ) { mCol3 = _col3; return *this; } inline Transform3 & Transform3::setCol( int col, const Vector3 &vec ) { *(&mCol0 + col) = vec; return *this; } inline Transform3 & Transform3::setRow( int row, const Vector4 &vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Transform3 & Transform3::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline Transform3 & Transform3::setElem( int col, int row, const floatInVec &val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline const floatInVec Transform3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Transform3::getCol0( ) const { return mCol0; } inline const Vector3 Transform3::getCol1( ) const { return mCol1; } inline const Vector3 Transform3::getCol2( ) const { return mCol2; } inline const Vector3 Transform3::getCol3( ) const { return mCol3; } inline const Vector3 Transform3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Transform3::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector3 & Transform3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Transform3::operator []( int col ) const { return *(&mCol0 + col); } inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; return *this; } inline const Transform3 inverse( const Transform3 & tfrm ) { __m128 inv0, inv1, inv2, inv3; __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; __m128 xxxx, yyyy, zzzz; tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() ); tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() ); tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() ); inv3 = negatef4( tfrm.getCol3().get128() ); dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() ); dot = vec_splat( dot, 0 ); invdet = recipf4( dot ); tmp3 = vec_mergeh( tmp0, tmp2 ); tmp4 = vec_mergel( tmp0, tmp2 ); inv0 = vec_mergeh( tmp3, tmp1 ); xxxx = vec_splat( inv3, 0 ); //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; inv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2)); inv1 = vec_sel(inv1, tmp1, select_y); //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); inv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0)); inv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y); yyyy = vec_splat( inv3, 1 ); zzzz = vec_splat( inv3, 2 ); inv3 = vec_mul( inv0, xxxx ); inv3 = vec_madd( inv1, yyyy, inv3 ); inv3 = vec_madd( inv2, zzzz, inv3 ); inv0 = vec_mul( inv0, invdet ); inv1 = vec_mul( inv1, invdet ); inv2 = vec_mul( inv2, invdet ); inv3 = vec_mul( inv3, invdet ); return Transform3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ), Vector3( inv3 ) ); } inline const Transform3 orthoInverse( const Transform3 & tfrm ) { __m128 inv0, inv1, inv2, inv3; __m128 tmp0, tmp1; __m128 xxxx, yyyy, zzzz; tmp0 = vec_mergeh( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); tmp1 = vec_mergel( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); inv3 = negatef4( tfrm.getCol3().get128() ); inv0 = vec_mergeh( tmp0, tfrm.getCol1().get128() ); xxxx = vec_splat( inv3, 0 ); //inv1 = vec_perm( tmp0, tfrm.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; inv1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); inv1 = vec_sel(inv1, tfrm.getCol1().get128(), select_y); //inv2 = vec_perm( tmp1, tfrm.getCol1().get128(), _VECTORMATH_PERM_XCYX ); inv2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); inv2 = vec_sel(inv2, vec_splat(tfrm.getCol1().get128(), 2), select_y); yyyy = vec_splat( inv3, 1 ); zzzz = vec_splat( inv3, 2 ); inv3 = vec_mul( inv0, xxxx ); inv3 = vec_madd( inv1, yyyy, inv3 ); inv3 = vec_madd( inv2, zzzz, inv3 ); return Transform3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ), Vector3( inv3 ) ); } inline const Transform3 absPerElem( const Transform3 & tfrm ) { return Transform3( absPerElem( tfrm.getCol0() ), absPerElem( tfrm.getCol1() ), absPerElem( tfrm.getCol2() ), absPerElem( tfrm.getCol3() ) ); } inline const Vector3 Transform3::operator *( const Vector3 &vec ) const { __m128 res; __m128 xxxx, yyyy, zzzz; xxxx = vec_splat( vec.get128(), 0 ); yyyy = vec_splat( vec.get128(), 1 ); zzzz = vec_splat( vec.get128(), 2 ); res = vec_mul( mCol0.get128(), xxxx ); res = vec_madd( mCol1.get128(), yyyy, res ); res = vec_madd( mCol2.get128(), zzzz, res ); return Vector3( res ); } inline const Point3 Transform3::operator *( const Point3 &pnt ) const { __m128 tmp0, tmp1, res; __m128 xxxx, yyyy, zzzz; xxxx = vec_splat( pnt.get128(), 0 ); yyyy = vec_splat( pnt.get128(), 1 ); zzzz = vec_splat( pnt.get128(), 2 ); tmp0 = vec_mul( mCol0.get128(), xxxx ); tmp1 = vec_mul( mCol1.get128(), yyyy ); tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 ); tmp1 = vec_add( mCol3.get128(), tmp1 ); res = vec_add( tmp0, tmp1 ); return Point3( res ); } inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const { return Transform3( ( *this * tfrm.mCol0 ), ( *this * tfrm.mCol1 ), ( *this * tfrm.mCol2 ), Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) ); } inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) { return Transform3( mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) ); } inline const Transform3 Transform3::identity( ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), Vector3( 0.0f ) ); } inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) { mCol0 = tfrm.getCol0(); mCol1 = tfrm.getCol1(); mCol2 = tfrm.getCol2(); return *this; } inline const Matrix3 Transform3::getUpper3x3( ) const { return Matrix3( mCol0, mCol1, mCol2 ); } inline Transform3 & Transform3::setTranslation( const Vector3 &translateVec ) { mCol3 = translateVec; return *this; } inline const Vector3 Transform3::getTranslation( ) const { return mCol3; } inline const Transform3 Transform3::rotationX( float radians ) { return rotationX( floatInVec(radians) ); } inline const Transform3 Transform3::rotationX( const floatInVec &radians ) { __m128 s, c, res1, res2; __m128 zero; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); return Transform3( Vector3::xAxis( ), Vector3( res1 ), Vector3( res2 ), Vector3( _mm_setzero_ps() ) ); } inline const Transform3 Transform3::rotationY( float radians ) { return rotationY( floatInVec(radians) ); } inline const Transform3 Transform3::rotationY( const floatInVec &radians ) { __m128 s, c, res0, res2; __m128 zero; _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); return Transform3( Vector3( res0 ), Vector3::yAxis( ), Vector3( res2 ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationZ( float radians ) { return rotationZ( floatInVec(radians) ); } inline const Transform3 Transform3::rotationZ( const floatInVec &radians ) { __m128 s, c, res0, res1; _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; __m128 zero = _mm_setzero_ps(); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); return Transform3( Vector3( res0 ), Vector3( res1 ), Vector3::zAxis( ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationZYX( const Vector3 &radiansXYZ ) { __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; angles = Vector4( radiansXYZ, 0.0f ).get128(); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); _VECTORMATH_ALIGNED(unsigned int select_xyz[4]) = {0xffffffff, 0xffffffff, 0xffffffff, 0}; Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_mul( Z0, Y1 ); return Transform3( Vector3( vec_mul( Z0, Y0 ) ), Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotation( float radians, const Vector3 &unitVec ) { return rotation( floatInVec(radians), unitVec ); } inline const Transform3 Transform3::rotation( const floatInVec &radians, const Vector3 &unitVec ) { return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotation( const Quat &unitQuat ) { return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::scale( const Vector3 &scaleVec ) { __m128 zero = _mm_setzero_ps(); _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; return Transform3( Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ), Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ), Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ), Vector3( 0.0f ) ); } inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec ) { return Transform3( ( tfrm.getCol0() * scaleVec.getX( ) ), ( tfrm.getCol1() * scaleVec.getY( ) ), ( tfrm.getCol2() * scaleVec.getZ( ) ), tfrm.getCol3() ); } inline const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm ) { return Transform3( mulPerElem( tfrm.getCol0(), scaleVec ), mulPerElem( tfrm.getCol1(), scaleVec ), mulPerElem( tfrm.getCol2(), scaleVec ), mulPerElem( tfrm.getCol3(), scaleVec ) ); } inline const Transform3 Transform3::translation( const Vector3 &translateVec ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), translateVec ); } inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) { return Transform3( select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) ); } inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 ) { return Transform3( select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Transform3 & tfrm ) { print( tfrm.getRow( 0 ) ); print( tfrm.getRow( 1 ) ); print( tfrm.getRow( 2 ) ); } inline void print( const Transform3 & tfrm, const char * name ) { printf("%s:\n", name); print( tfrm ); } #endif inline Quat::Quat( const Matrix3 & tfrm ) { __m128 res; __m128 col0, col1, col2; __m128 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; __m128 zy_xz_yx, yz_zx_xy, sum, diff; __m128 radicand, invSqrt, scale; __m128 res0, res1, res2, res3; __m128 xx, yy, zz; _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; _VECTORMATH_ALIGNED(unsigned int select_w[4]) = {0, 0, 0, 0xffffffff}; col0 = tfrm.getCol0().get128(); col1 = tfrm.getCol1().get128(); col2 = tfrm.getCol2().get128(); /* four cases: */ /* trace > 0 */ /* else */ /* xx largest diagonal element */ /* yy largest diagonal element */ /* zz largest diagonal element */ /* compute quaternion for each case */ xx_yy = vec_sel( col0, col1, select_y ); //xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX ); //yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY ); //zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC ); xx_yy_zz_xx = _mm_shuffle_ps( xx_yy, xx_yy, _MM_SHUFFLE(0,0,1,0) ); xx_yy_zz_xx = vec_sel( xx_yy_zz_xx, col2, select_z ); // TODO: Ck yy_zz_xx_yy = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(1,0,2,1) ); zz_xx_yy_zz = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(2,1,0,2) ); diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), _mm_set1_ps(1.0f) ); //invSqrt = rsqrtf4( radicand ); invSqrt = newtonrapson_rsqrt4( radicand ); zy_xz_yx = vec_sel( col0, col1, select_z ); // zy_xz_yx = 00 01 12 03 //zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX ); zy_xz_yx = _mm_shuffle_ps( zy_xz_yx, zy_xz_yx, _MM_SHUFFLE(0,1,2,2) ); // zy_xz_yx = 12 12 01 00 zy_xz_yx = vec_sel( zy_xz_yx, vec_splat(col2, 0), select_y ); // zy_xz_yx = 12 20 01 00 yz_zx_xy = vec_sel( col0, col1, select_x ); // yz_zx_xy = 10 01 02 03 //yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX ); yz_zx_xy = _mm_shuffle_ps( yz_zx_xy, yz_zx_xy, _MM_SHUFFLE(0,0,2,0) ); // yz_zx_xy = 10 02 10 10 yz_zx_xy = vec_sel( yz_zx_xy, vec_splat(col2, 1), select_x ); // yz_zx_xy = 21 02 10 10 sum = vec_add( zy_xz_yx, yz_zx_xy ); diff = vec_sub( zy_xz_yx, yz_zx_xy ); scale = vec_mul( invSqrt, _mm_set1_ps(0.5f) ); //res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA ); res0 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,1,2,0) ); res0 = vec_sel( res0, vec_splat(diff, 0), select_w ); // TODO: Ck //res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB ); res1 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,2) ); res1 = vec_sel( res1, vec_splat(diff, 1), select_w ); // TODO: Ck //res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC ); res2 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,1) ); res2 = vec_sel( res2, vec_splat(diff, 2), select_w ); // TODO: Ck res3 = diff; res0 = vec_sel( res0, radicand, select_x ); res1 = vec_sel( res1, radicand, select_y ); res2 = vec_sel( res2, radicand, select_z ); res3 = vec_sel( res3, radicand, select_w ); res0 = vec_mul( res0, vec_splat( scale, 0 ) ); res1 = vec_mul( res1, vec_splat( scale, 1 ) ); res2 = vec_mul( res2, vec_splat( scale, 2 ) ); res3 = vec_mul( res3, vec_splat( scale, 3 ) ); /* determine case and select answer */ xx = vec_splat( col0, 0 ); yy = vec_splat( col1, 1 ); zz = vec_splat( col2, 2 ); res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) ); res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) ); res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), _mm_setzero_ps() ) ); mVec128 = res; } inline const Matrix3 outer( const Vector3 &tfrm0, const Vector3 &tfrm1 ) { return Matrix3( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ) ); } inline const Matrix4 outer( const Vector4 &tfrm0, const Vector4 &tfrm1 ) { return Matrix4( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ), ( tfrm0 * tfrm1.getW( ) ) ); } inline const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat ) { __m128 tmp0, tmp1, mcol0, mcol1, mcol2, res; __m128 xxxx, yyyy, zzzz; tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); xxxx = vec_splat( vec.get128(), 0 ); mcol0 = vec_mergeh( tmp0, mat.getCol1().get128() ); //mcol1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; mcol1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); mcol1 = vec_sel(mcol1, mat.getCol1().get128(), select_y); //mcol2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); mcol2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); mcol2 = vec_sel(mcol2, vec_splat(mat.getCol1().get128(), 2), select_y); yyyy = vec_splat( vec.get128(), 1 ); res = vec_mul( mcol0, xxxx ); zzzz = vec_splat( vec.get128(), 2 ); res = vec_madd( mcol1, yyyy, res ); res = vec_madd( mcol2, zzzz, res ); return Vector3( res ); } inline const Matrix3 crossMatrix( const Vector3 &vec ) { __m128 neg, res0, res1, res2; neg = negatef4( vec.get128() ); _VECTORMATH_ALIGNED(unsigned int select_x[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_y[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int select_z[4]) = {0, 0, 0xffffffff, 0}; //res0 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_XZBX ); res0 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,2,2,0) ); res0 = vec_sel(res0, vec_splat(neg, 1), select_z); //res1 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_CXXX ); res1 = vec_sel(vec_splat(vec.get128(), 0), vec_splat(neg, 2), select_x); //res2 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_YAXX ); res2 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,1,1) ); res2 = vec_sel(res2, vec_splat(neg, 0), select_y); _VECTORMATH_ALIGNED(unsigned int filter_x[4]) = {0, 0xffffffff, 0xffffffff, 0xffffffff}; _VECTORMATH_ALIGNED(unsigned int filter_y[4]) = {0xffffffff, 0, 0xffffffff, 0xffffffff}; _VECTORMATH_ALIGNED(unsigned int filter_z[4]) = {0xffffffff, 0xffffffff, 0, 0xffffffff}; res0 = vec_and( res0, _mm_load_ps((float *)filter_x ) ); res1 = vec_and( res1, _mm_load_ps((float *)filter_y ) ); res2 = vec_and( res2, _mm_load_ps((float *)filter_z ) ); // TODO: Use selects? return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat ) { return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); } } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/SSE/cpp/quat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_CPP_H #define _VECTORMATH_QUAT_AOS_CPP_H #include "defines.h" //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Aos { inline Quat::Quat( float _x, float _y, float _z, float _w ) { mVec128 = _mm_setr_ps(_x, _y, _z, _w); } inline Quat::Quat( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w ) { mVec128 = _mm_unpacklo_ps( _mm_unpacklo_ps( _x.get128(), _z.get128() ), _mm_unpacklo_ps( _y.get128(), _w.get128() ) ); } inline Quat::Quat( const Vector3 &xyz, float _w ) { mVec128 = xyz.get128(); _vmathVfSetElement(mVec128, _w, 3); } inline Quat::Quat( const Vector3 &xyz, const floatInVec &_w ) { mVec128 = xyz.get128(); mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); } inline Quat::Quat( const Vector4 &vec ) { mVec128 = vec.get128(); } inline Quat::Quat( float scalar ) { mVec128 = floatInVec(scalar).get128(); } inline Quat::Quat( const floatInVec &scalar ) { mVec128 = scalar.get128(); } inline Quat::Quat( __m128 vf4 ) { mVec128 = vf4; } inline const Quat Quat::identity( ) { return Quat( _VECTORMATH_UNIT_0001 ); } inline const Quat lerp( float t, const Quat &quat0, const Quat &quat1 ) { return lerp( floatInVec(t), quat0, quat1 ); } inline const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 ) { return ( quat0 + ( ( quat1 - quat0 ) * t ) ); } inline const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 ) { return slerp( floatInVec(t), unitQuat0, unitQuat1 ); } inline const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 ) { Quat start; vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() ); selectMask = (vec_uint4)vec_cmpgt( _mm_setzero_ps(), cosAngle ); cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask ); start = Quat( vec_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) ); selectMask = (vec_uint4)vec_cmpgt( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = t.get128(); oneMinusT = vec_sub( _mm_set1_ps(1.0f), tttt ); angles = vec_mergeh( _mm_set1_ps(1.0f), tttt ); angles = vec_mergeh( angles, oneMinusT ); angles = vec_madd( angles, angle, _mm_setzero_ps() ); sines = sinf4( angles ); scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); return Quat( vec_madd( start.get128(), scale0, vec_mul( unitQuat1.get128(), scale1 ) ) ); } inline const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ) { return squad( floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3 ); } inline const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ) { return slerp( ( ( floatInVec(2.0f) * t ) * ( floatInVec(1.0f) - t ) ), slerp( t, unitQuat0, unitQuat3 ), slerp( t, unitQuat1, unitQuat2 ) ); } inline __m128 Quat::get128( ) const { return mVec128; } inline Quat & Quat::operator =( const Quat &quat ) { mVec128 = quat.mVec128; return *this; } inline Quat & Quat::setXYZ( const Vector3 &vec ) { _VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; mVec128 = vec_sel( vec.get128(), mVec128, sw ); return *this; } inline const Vector3 Quat::getXYZ( ) const { return Vector3( mVec128 ); } inline Quat & Quat::setX( float _x ) { _vmathVfSetElement(mVec128, _x, 0); return *this; } inline Quat & Quat::setX( const floatInVec &_x ) { mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); return *this; } inline const floatInVec Quat::getX( ) const { return floatInVec( mVec128, 0 ); } inline Quat & Quat::setY( float _y ) { _vmathVfSetElement(mVec128, _y, 1); return *this; } inline Quat & Quat::setY( const floatInVec &_y ) { mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); return *this; } inline const floatInVec Quat::getY( ) const { return floatInVec( mVec128, 1 ); } inline Quat & Quat::setZ( float _z ) { _vmathVfSetElement(mVec128, _z, 2); return *this; } inline Quat & Quat::setZ( const floatInVec &_z ) { mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); return *this; } inline const floatInVec Quat::getZ( ) const { return floatInVec( mVec128, 2 ); } inline Quat & Quat::setW( float _w ) { _vmathVfSetElement(mVec128, _w, 3); return *this; } inline Quat & Quat::setW( const floatInVec &_w ) { mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); return *this; } inline const floatInVec Quat::getW( ) const { return floatInVec( mVec128, 3 ); } inline Quat & Quat::setElem( int idx, float value ) { _vmathVfSetElement(mVec128, value, idx); return *this; } inline Quat & Quat::setElem( int idx, const floatInVec &value ) { mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); return *this; } inline const floatInVec Quat::getElem( int idx ) const { return floatInVec( mVec128, idx ); } inline VecIdx Quat::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline const floatInVec Quat::operator []( int idx ) const { return floatInVec( mVec128, idx ); } inline const Quat Quat::operator +( const Quat &quat ) const { return Quat( _mm_add_ps( mVec128, quat.mVec128 ) ); } inline const Quat Quat::operator -( const Quat &quat ) const { return Quat( _mm_sub_ps( mVec128, quat.mVec128 ) ); } inline const Quat Quat::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Quat Quat::operator *( const floatInVec &scalar ) const { return Quat( _mm_mul_ps( mVec128, scalar.get128() ) ); } inline Quat & Quat::operator +=( const Quat &quat ) { *this = *this + quat; return *this; } inline Quat & Quat::operator -=( const Quat &quat ) { *this = *this - quat; return *this; } inline Quat & Quat::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline Quat & Quat::operator *=( const floatInVec &scalar ) { *this = *this * scalar; return *this; } inline const Quat Quat::operator /( float scalar ) const { return *this / floatInVec(scalar); } inline const Quat Quat::operator /( const floatInVec &scalar ) const { return Quat( _mm_div_ps( mVec128, scalar.get128() ) ); } inline Quat & Quat::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline Quat & Quat::operator /=( const floatInVec &scalar ) { *this = *this / scalar; return *this; } inline const Quat Quat::operator -( ) const { return Quat(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); } inline const Quat operator *( float scalar, const Quat &quat ) { return floatInVec(scalar) * quat; } inline const Quat operator *( const floatInVec &scalar, const Quat &quat ) { return quat * scalar; } inline const floatInVec dot( const Quat &quat0, const Quat &quat1 ) { return floatInVec( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 ); } inline const floatInVec norm( const Quat &quat ) { return floatInVec( _vmathVfDot4( quat.get128(), quat.get128() ), 0 ); } inline const floatInVec length( const Quat &quat ) { return floatInVec( _mm_sqrt_ps(_vmathVfDot4( quat.get128(), quat.get128() )), 0 ); } inline const Quat normalize( const Quat &quat ) { return Quat( _mm_mul_ps( quat.get128(), _mm_rsqrt_ps( _vmathVfDot4( quat.get128(), quat.get128() ) ) ) ); } inline const Quat Quat::rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 ) { Vector3 crossVec; __m128 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); cosAngleX2Plus2 = vec_madd( cosAngle, _mm_set1_ps(2.0f), _mm_set1_ps(2.0f) ); recipCosHalfAngleX2 = _mm_rsqrt_ps( cosAngleX2Plus2 ); cosHalfAngleX2 = vec_mul( recipCosHalfAngleX2, cosAngleX2Plus2 ); crossVec = cross( unitVec0, unitVec1 ); res = vec_mul( crossVec.get128(), recipCosHalfAngleX2 ); _VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; res = vec_sel( res, vec_mul( cosHalfAngleX2, _mm_set1_ps(0.5f) ), sw ); return Quat( res ); } inline const Quat Quat::rotation( float radians, const Vector3 &unitVec ) { return rotation( floatInVec(radians), unitVec ); } inline const Quat Quat::rotation( const floatInVec &radians, const Vector3 &unitVec ) { __m128 s, c, angle, res; angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); sincosf4( angle, &s, &c ); _VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; res = vec_sel( vec_mul( unitVec.get128(), s ), c, sw ); return Quat( res ); } inline const Quat Quat::rotationX( float radians ) { return rotationX( floatInVec(radians) ); } inline const Quat Quat::rotationX( const floatInVec &radians ) { __m128 s, c, angle, res; angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); sincosf4( angle, &s, &c ); _VECTORMATH_ALIGNED(unsigned int xsw[4]) = {0xffffffff, 0, 0, 0}; _VECTORMATH_ALIGNED(unsigned int wsw[4]) = {0, 0, 0, 0xffffffff}; res = vec_sel( _mm_setzero_ps(), s, xsw ); res = vec_sel( res, c, wsw ); return Quat( res ); } inline const Quat Quat::rotationY( float radians ) { return rotationY( floatInVec(radians) ); } inline const Quat Quat::rotationY( const floatInVec &radians ) { __m128 s, c, angle, res; angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); sincosf4( angle, &s, &c ); _VECTORMATH_ALIGNED(unsigned int ysw[4]) = {0, 0xffffffff, 0, 0}; _VECTORMATH_ALIGNED(unsigned int wsw[4]) = {0, 0, 0, 0xffffffff}; res = vec_sel( _mm_setzero_ps(), s, ysw ); res = vec_sel( res, c, wsw ); return Quat( res ); } inline const Quat Quat::rotationZ( float radians ) { return rotationZ( floatInVec(radians) ); } inline const Quat Quat::rotationZ( const floatInVec &radians ) { __m128 s, c, angle, res; angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); sincosf4( angle, &s, &c ); _VECTORMATH_ALIGNED(unsigned int zsw[4]) = {0, 0, 0xffffffff, 0}; _VECTORMATH_ALIGNED(unsigned int wsw[4]) = {0, 0, 0, 0xffffffff}; res = vec_sel( _mm_setzero_ps(), s, zsw ); res = vec_sel( res, c, wsw ); return Quat( res ); } inline const Quat Quat::operator *( const Quat &quat ) const { __m128 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; __m128 product, l_wxyz, r_wxyz, xy, qw; ldata = mVec128; rdata = quat.mVec128; tmp0 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,0,2,1) ); tmp1 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,1,0,2) ); tmp2 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,1,0,2) ); tmp3 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,0,2,1) ); qv = vec_mul( vec_splat( ldata, 3 ), rdata ); qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv ); qv = vec_madd( tmp0, tmp1, qv ); qv = vec_nmsub( tmp2, tmp3, qv ); product = vec_mul( ldata, rdata ); l_wxyz = vec_sld( ldata, ldata, 12 ); r_wxyz = vec_sld( rdata, rdata, 12 ); qw = vec_nmsub( l_wxyz, r_wxyz, product ); xy = vec_madd( l_wxyz, r_wxyz, product ); qw = vec_sub( qw, vec_sld( xy, xy, 8 ) ); _VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; return Quat( vec_sel( qv, qw, sw ) ); } inline Quat & Quat::operator *=( const Quat &quat ) { *this = *this * quat; return *this; } inline const Vector3 rotate( const Quat &quat, const Vector3 &vec ) { __m128 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; qdata = quat.get128(); vdata = vec.get128(); tmp0 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,0,2,1) ); tmp1 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,1,0,2) ); tmp2 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,1,0,2) ); tmp3 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,0,2,1) ); wwww = vec_splat( qdata, 3 ); qv = vec_mul( wwww, vdata ); qv = vec_madd( tmp0, tmp1, qv ); qv = vec_nmsub( tmp2, tmp3, qv ); product = vec_mul( qdata, vdata ); qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product ); qw = vec_add( vec_sld( product, product, 8 ), qw ); tmp1 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,1,0,2) ); tmp3 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,0,2,1) ); res = vec_mul( vec_splat( qw, 0 ), qdata ); res = vec_madd( wwww, qv, res ); res = vec_madd( tmp0, tmp1, res ); res = vec_nmsub( tmp2, tmp3, res ); return Vector3( res ); } inline const Quat conj( const Quat &quat ) { _VECTORMATH_ALIGNED(unsigned int sw[4]) = {0x80000000,0x80000000,0x80000000,0}; return Quat( vec_xor( quat.get128(), _mm_load_ps((float *)sw) ) ); } inline const Quat select( const Quat &quat0, const Quat &quat1, bool select1 ) { return select( quat0, quat1, boolInVec(select1) ); } inline const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 ) { return Quat( vec_sel( quat0.get128(), quat1.get128(), select1.get128() ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Quat &quat ) { union { __m128 v; float s[4]; } tmp; tmp.v = quat.get128(); printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } inline void print( const Quat &quat, const char * name ) { union { __m128 v; float s[4]; } tmp; tmp.v = quat.get128(); printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/SSE/cpp/vec_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_CPP_H #define _VECTORMATH_VEC_AOS_CPP_H #include "defines.h" //----------------------------------------------------------------------------- // Constants // for permutes words are labeled [x,y,z,w] [a,b,c,d] #define _VECTORMATH_PERM_X 0x00010203 #define _VECTORMATH_PERM_Y 0x04050607 #define _VECTORMATH_PERM_Z 0x08090a0b #define _VECTORMATH_PERM_W 0x0c0d0e0f #define _VECTORMATH_PERM_A 0x10111213 #define _VECTORMATH_PERM_B 0x14151617 #define _VECTORMATH_PERM_C 0x18191a1b #define _VECTORMATH_PERM_D 0x1c1d1e1f #define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A } #define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B } #define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C } #define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W } #define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 } #define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 } #define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 } #define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff } #define _VECTORMATH_UNIT_1000 _mm_setr_ps(1.0f,0.0f,0.0f,0.0f) // (__m128){ 1.0f, 0.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0100 _mm_setr_ps(0.0f,1.0f,0.0f,0.0f) // (__m128){ 0.0f, 1.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0010 _mm_setr_ps(0.0f,0.0f,1.0f,0.0f) // (__m128){ 0.0f, 0.0f, 1.0f, 0.0f } #define _VECTORMATH_UNIT_0001 _mm_setr_ps(0.0f,0.0f,0.0f,1.0f) // (__m128){ 0.0f, 0.0f, 0.0f, 1.0f } #define _VECTORMATH_SLERP_TOL 0.999f //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS static inline __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 ) { __m128 result = _mm_mul_ps( vec0, vec1); return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) ); } static inline __m128 _vmathVfDot4( __m128 vec0, __m128 vec1 ) { __m128 result = _mm_mul_ps(vec0, vec1); return _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(0,0,0,0)), _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(1,1,1,1)), _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))))); } static inline __m128 _vmathVfCross( __m128 vec0, __m128 vec1 ) { __m128 tmp0, tmp1, tmp2, tmp3, result; tmp0 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,0,2,1) ); tmp1 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,1,0,2) ); tmp2 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,1,0,2) ); tmp3 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,0,2,1) ); result = vec_mul( tmp0, tmp1 ); result = vec_nmsub( tmp2, tmp3, result ); return result; } static inline __m128 _vmathVfInsert(__m128 dst, __m128 src, int slot) { SSEFloat s; s.m128 = src; SSEFloat d; d.m128 = dst; d.f[slot] = s.f[slot]; return d.m128; } #define _vmathVfSetElement(vec, scalar, slot) ((float *)&(vec))[slot] = scalar static inline __m128 _vmathVfSplatScalar(float scalar) { return _mm_set1_ps(scalar); } #endif namespace Vectormath { namespace Aos { #ifdef _VECTORMATH_NO_SCALAR_CAST inline VecIdx::operator floatInVec() const { return floatInVec(ref, i); } inline float VecIdx::getAsFloat() const #else inline VecIdx::operator float() const #endif { return ((float *)&ref)[i]; } inline float VecIdx::operator =( float scalar ) { _vmathVfSetElement(ref, scalar, i); return scalar; } inline floatInVec VecIdx::operator =( const floatInVec &scalar ) { ref = _vmathVfInsert(ref, scalar.get128(), i); return scalar; } inline floatInVec VecIdx::operator =( const VecIdx& scalar ) { return *this = floatInVec(scalar.ref, scalar.i); } inline floatInVec VecIdx::operator *=( float scalar ) { return *this *= floatInVec(scalar); } inline floatInVec VecIdx::operator *=( const floatInVec &scalar ) { return *this = floatInVec(ref, i) * scalar; } inline floatInVec VecIdx::operator /=( float scalar ) { return *this /= floatInVec(scalar); } inline floatInVec VecIdx::operator /=( const floatInVec &scalar ) { return *this = floatInVec(ref, i) / scalar; } inline floatInVec VecIdx::operator +=( float scalar ) { return *this += floatInVec(scalar); } inline floatInVec VecIdx::operator +=( const floatInVec &scalar ) { return *this = floatInVec(ref, i) + scalar; } inline floatInVec VecIdx::operator -=( float scalar ) { return *this -= floatInVec(scalar); } inline floatInVec VecIdx::operator -=( const floatInVec &scalar ) { return *this = floatInVec(ref, i) - scalar; } inline Vector3::Vector3( float _x, float _y, float _z ) { mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); } inline Vector3::Vector3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z ) { __m128 xz = _mm_unpacklo_ps( _x.get128(), _z.get128() ); mVec128 = _mm_unpacklo_ps( xz, _y.get128() ); } inline Vector3::Vector3( const Point3 &pnt ) { mVec128 = pnt.get128(); } inline Vector3::Vector3( float scalar ) { mVec128 = floatInVec(scalar).get128(); } inline Vector3::Vector3( const floatInVec &scalar ) { mVec128 = scalar.get128(); } inline Vector3::Vector3( __m128 vf4 ) { mVec128 = vf4; } inline const Vector3 Vector3::xAxis( ) { return Vector3( _VECTORMATH_UNIT_1000 ); } inline const Vector3 Vector3::yAxis( ) { return Vector3( _VECTORMATH_UNIT_0100 ); } inline const Vector3 Vector3::zAxis( ) { return Vector3( _VECTORMATH_UNIT_0010 ); } inline const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 ) { return lerp( floatInVec(t), vec0, vec1 ); } inline const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 ) { return slerp( floatInVec(t), unitVec0, unitVec1 ); } inline const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 ) { __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = t.get128(); oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt ); angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t angles = _mm_unpacklo_ps( angles, oneMinusT ); // angles = 1, 1-t, t, 1-t angles = _mm_mul_ps( angles, angle ); sines = sinf4( angles ); scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); return Vector3( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) ); } inline __m128 Vector3::get128( ) const { return mVec128; } inline void storeXYZ( const Vector3 &vec, __m128 * quad ) { __m128 dstVec = *quad; _VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; // TODO: Centralize dstVec = vec_sel(vec.get128(), dstVec, sw); *quad = dstVec; } inline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads ) { const float *quads = (float *)threeQuads; vec0 = Vector3( _mm_load_ps(quads) ); vec1 = Vector3( _mm_loadu_ps(quads + 3) ); vec2 = Vector3( _mm_loadu_ps(quads + 6) ); vec3 = Vector3( _mm_loadu_ps(quads + 9) ); } inline void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads ) { __m128 xxxx = _mm_shuffle_ps( vec1.get128(), vec1.get128(), _MM_SHUFFLE(0, 0, 0, 0) ); __m128 zzzz = _mm_shuffle_ps( vec2.get128(), vec2.get128(), _MM_SHUFFLE(2, 2, 2, 2) ); _VECTORMATH_ALIGNED(unsigned int xsw[4]) = {0, 0, 0, 0xffffffff}; _VECTORMATH_ALIGNED(unsigned int zsw[4]) = {0xffffffff, 0, 0, 0}; threeQuads[0] = vec_sel( vec0.get128(), xxxx, xsw ); threeQuads[1] = _mm_shuffle_ps( vec1.get128(), vec2.get128(), _MM_SHUFFLE(1, 0, 2, 1) ); threeQuads[2] = vec_sel( _mm_shuffle_ps( vec3.get128(), vec3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw ); } inline Vector3 & Vector3::operator =( const Vector3 &vec ) { mVec128 = vec.mVec128; return *this; } inline Vector3 & Vector3::setX( float _x ) { _vmathVfSetElement(mVec128, _x, 0); return *this; } inline Vector3 & Vector3::setX( const floatInVec &_x ) { mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); return *this; } inline const floatInVec Vector3::getX( ) const { return floatInVec( mVec128, 0 ); } inline Vector3 & Vector3::setY( float _y ) { _vmathVfSetElement(mVec128, _y, 1); return *this; } inline Vector3 & Vector3::setY( const floatInVec &_y ) { mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); return *this; } inline const floatInVec Vector3::getY( ) const { return floatInVec( mVec128, 1 ); } inline Vector3 & Vector3::setZ( float _z ) { _vmathVfSetElement(mVec128, _z, 2); return *this; } inline Vector3 & Vector3::setZ( const floatInVec &_z ) { mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); return *this; } inline const floatInVec Vector3::getZ( ) const { return floatInVec( mVec128, 2 ); } inline Vector3 & Vector3::setElem( int idx, float value ) { _vmathVfSetElement(mVec128, value, idx); return *this; } inline Vector3 & Vector3::setElem( int idx, const floatInVec &value ) { mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); return *this; } inline const floatInVec Vector3::getElem( int idx ) const { return floatInVec( mVec128, idx ); } inline VecIdx Vector3::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline const floatInVec Vector3::operator []( int idx ) const { return floatInVec( mVec128, idx ); } inline const Vector3 Vector3::operator +( const Vector3 &vec ) const { return Vector3( _mm_add_ps( mVec128, vec.mVec128 ) ); } inline const Vector3 Vector3::operator -( const Vector3 &vec ) const { return Vector3( _mm_sub_ps( mVec128, vec.mVec128 ) ); } inline const Point3 Vector3::operator +( const Point3 &pnt ) const { return Point3( _mm_add_ps( mVec128, pnt.get128() ) ); } inline const Vector3 Vector3::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Vector3 Vector3::operator *( const floatInVec &scalar ) const { return Vector3( _mm_mul_ps( mVec128, scalar.get128() ) ); } inline Vector3 & Vector3::operator +=( const Vector3 &vec ) { *this = *this + vec; return *this; } inline Vector3 & Vector3::operator -=( const Vector3 &vec ) { *this = *this - vec; return *this; } inline Vector3 & Vector3::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline Vector3 & Vector3::operator *=( const floatInVec &scalar ) { *this = *this * scalar; return *this; } inline const Vector3 Vector3::operator /( float scalar ) const { return *this / floatInVec(scalar); } inline const Vector3 Vector3::operator /( const floatInVec &scalar ) const { return Vector3( _mm_div_ps( mVec128, scalar.get128() ) ); } inline Vector3 & Vector3::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline Vector3 & Vector3::operator /=( const floatInVec &scalar ) { *this = *this / scalar; return *this; } inline const Vector3 Vector3::operator -( ) const { return Vector3(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); } inline const Vector3 operator *( float scalar, const Vector3 &vec ) { return floatInVec(scalar) * vec; } inline const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec ) { return vec * scalar; } inline const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 ) { return Vector3( _mm_mul_ps( vec0.get128(), vec1.get128() ) ); } inline const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 ) { return Vector3( _mm_div_ps( vec0.get128(), vec1.get128() ) ); } inline const Vector3 recipPerElem( const Vector3 &vec ) { return Vector3( _mm_rcp_ps( vec.get128() ) ); } inline const Vector3 absPerElem( const Vector3 &vec ) { return Vector3( fabsf4( vec.get128() ) ); } inline const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 ) { __m128 vmask = toM128(0x7fffffff); return Vector3( _mm_or_ps( _mm_and_ps ( vmask, vec0.get128() ), // Value _mm_andnot_ps( vmask, vec1.get128() ) ) ); // Signs } inline const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 ) { return Vector3( _mm_max_ps( vec0.get128(), vec1.get128() ) ); } inline const floatInVec maxElem( const Vector3 &vec ) { return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); } inline const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 ) { return Vector3( _mm_min_ps( vec0.get128(), vec1.get128() ) ); } inline const floatInVec minElem( const Vector3 &vec ) { return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); } inline const floatInVec sum( const Vector3 &vec ) { return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); } inline const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 ) { return floatInVec( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 ); } inline const floatInVec lengthSqr( const Vector3 &vec ) { return floatInVec( _vmathVfDot3( vec.get128(), vec.get128() ), 0 ); } inline const floatInVec length( const Vector3 &vec ) { return floatInVec( _mm_sqrt_ps(_vmathVfDot3( vec.get128(), vec.get128() )), 0 ); } inline const Vector3 normalizeApprox( const Vector3 &vec ) { return Vector3( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) ); } inline const Vector3 normalize( const Vector3 &vec ) { return Vector3( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) ); } inline const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 ) { return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) ); } inline const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 ) { return select( vec0, vec1, boolInVec(select1) ); } inline const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1 ) { return Vector3(vec_sel( vec0.get128(), vec1.get128(), select1.get128() )); } #ifdef _VECTORMATH_DEBUG inline void print( const Vector3 &vec ) { union { __m128 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } inline void print( const Vector3 &vec, const char * name ) { union { __m128 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif inline Vector4::Vector4( float _x, float _y, float _z, float _w ) { mVec128 = _mm_setr_ps(_x, _y, _z, _w); } inline Vector4::Vector4( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w ) { mVec128 = _mm_unpacklo_ps( _mm_unpacklo_ps( _x.get128(), _z.get128() ), _mm_unpacklo_ps( _y.get128(), _w.get128() ) ); } inline Vector4::Vector4( const Vector3 &xyz, float _w ) { mVec128 = xyz.get128(); _vmathVfSetElement(mVec128, _w, 3); } inline Vector4::Vector4( const Vector3 &xyz, const floatInVec &_w ) { mVec128 = xyz.get128(); mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); } inline Vector4::Vector4( const Vector3 &vec ) { mVec128 = vec.get128(); mVec128 = _vmathVfInsert(mVec128, _mm_setzero_ps(), 3); } inline Vector4::Vector4( const Point3 &pnt ) { mVec128 = pnt.get128(); mVec128 = _vmathVfInsert(mVec128, _mm_set1_ps(1.0f), 3); } inline Vector4::Vector4( const Quat &quat ) { mVec128 = quat.get128(); } inline Vector4::Vector4( float scalar ) { mVec128 = floatInVec(scalar).get128(); } inline Vector4::Vector4( const floatInVec &scalar ) { mVec128 = scalar.get128(); } inline Vector4::Vector4( __m128 vf4 ) { mVec128 = vf4; } inline const Vector4 Vector4::xAxis( ) { return Vector4( _VECTORMATH_UNIT_1000 ); } inline const Vector4 Vector4::yAxis( ) { return Vector4( _VECTORMATH_UNIT_0100 ); } inline const Vector4 Vector4::zAxis( ) { return Vector4( _VECTORMATH_UNIT_0010 ); } inline const Vector4 Vector4::wAxis( ) { return Vector4( _VECTORMATH_UNIT_0001 ); } inline const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 ) { return lerp( floatInVec(t), vec0, vec1 ); } inline const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 ) { return slerp( floatInVec(t), unitVec0, unitVec1 ); } inline const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 ) { __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() ); __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = t.get128(); oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt ); angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t angles = _mm_unpacklo_ps( angles, oneMinusT ); // angles = 1, 1-t, t, 1-t angles = _mm_mul_ps( angles, angle ); sines = sinf4( angles ); scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); return Vector4( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) ); } inline __m128 Vector4::get128( ) const { return mVec128; } inline Vector4 & Vector4::operator =( const Vector4 &vec ) { mVec128 = vec.mVec128; return *this; } inline Vector4 & Vector4::setXYZ( const Vector3 &vec ) { _VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; mVec128 = vec_sel( vec.get128(), mVec128, sw ); return *this; } inline const Vector3 Vector4::getXYZ( ) const { return Vector3( mVec128 ); } inline Vector4 & Vector4::setX( float _x ) { _vmathVfSetElement(mVec128, _x, 0); return *this; } inline Vector4 & Vector4::setX( const floatInVec &_x ) { mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); return *this; } inline const floatInVec Vector4::getX( ) const { return floatInVec( mVec128, 0 ); } inline Vector4 & Vector4::setY( float _y ) { _vmathVfSetElement(mVec128, _y, 1); return *this; } inline Vector4 & Vector4::setY( const floatInVec &_y ) { mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); return *this; } inline const floatInVec Vector4::getY( ) const { return floatInVec( mVec128, 1 ); } inline Vector4 & Vector4::setZ( float _z ) { _vmathVfSetElement(mVec128, _z, 2); return *this; } inline Vector4 & Vector4::setZ( const floatInVec &_z ) { mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); return *this; } inline const floatInVec Vector4::getZ( ) const { return floatInVec( mVec128, 2 ); } inline Vector4 & Vector4::setW( float _w ) { _vmathVfSetElement(mVec128, _w, 3); return *this; } inline Vector4 & Vector4::setW( const floatInVec &_w ) { mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); return *this; } inline const floatInVec Vector4::getW( ) const { return floatInVec( mVec128, 3 ); } inline Vector4 & Vector4::setElem( int idx, float value ) { _vmathVfSetElement(mVec128, value, idx); return *this; } inline Vector4 & Vector4::setElem( int idx, const floatInVec &value ) { mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); return *this; } inline const floatInVec Vector4::getElem( int idx ) const { return floatInVec( mVec128, idx ); } inline VecIdx Vector4::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline const floatInVec Vector4::operator []( int idx ) const { return floatInVec( mVec128, idx ); } inline const Vector4 Vector4::operator +( const Vector4 &vec ) const { return Vector4( _mm_add_ps( mVec128, vec.mVec128 ) ); } inline const Vector4 Vector4::operator -( const Vector4 &vec ) const { return Vector4( _mm_sub_ps( mVec128, vec.mVec128 ) ); } inline const Vector4 Vector4::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Vector4 Vector4::operator *( const floatInVec &scalar ) const { return Vector4( _mm_mul_ps( mVec128, scalar.get128() ) ); } inline Vector4 & Vector4::operator +=( const Vector4 &vec ) { *this = *this + vec; return *this; } inline Vector4 & Vector4::operator -=( const Vector4 &vec ) { *this = *this - vec; return *this; } inline Vector4 & Vector4::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline Vector4 & Vector4::operator *=( const floatInVec &scalar ) { *this = *this * scalar; return *this; } inline const Vector4 Vector4::operator /( float scalar ) const { return *this / floatInVec(scalar); } inline const Vector4 Vector4::operator /( const floatInVec &scalar ) const { return Vector4( _mm_div_ps( mVec128, scalar.get128() ) ); } inline Vector4 & Vector4::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline Vector4 & Vector4::operator /=( const floatInVec &scalar ) { *this = *this / scalar; return *this; } inline const Vector4 Vector4::operator -( ) const { return Vector4(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); } inline const Vector4 operator *( float scalar, const Vector4 &vec ) { return floatInVec(scalar) * vec; } inline const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec ) { return vec * scalar; } inline const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 ) { return Vector4( _mm_mul_ps( vec0.get128(), vec1.get128() ) ); } inline const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 ) { return Vector4( _mm_div_ps( vec0.get128(), vec1.get128() ) ); } inline const Vector4 recipPerElem( const Vector4 &vec ) { return Vector4( _mm_rcp_ps( vec.get128() ) ); } inline const Vector4 absPerElem( const Vector4 &vec ) { return Vector4( fabsf4( vec.get128() ) ); } inline const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 ) { __m128 vmask = toM128(0x7fffffff); return Vector4( _mm_or_ps( _mm_and_ps ( vmask, vec0.get128() ), // Value _mm_andnot_ps( vmask, vec1.get128() ) ) ); // Signs } inline const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 ) { return Vector4( _mm_max_ps( vec0.get128(), vec1.get128() ) ); } inline const floatInVec maxElem( const Vector4 &vec ) { return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), _mm_max_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); } inline const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 ) { return Vector4( _mm_min_ps( vec0.get128(), vec1.get128() ) ); } inline const floatInVec minElem( const Vector4 &vec ) { return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), _mm_min_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); } inline const floatInVec sum( const Vector4 &vec ) { return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), _mm_add_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); } inline const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 ) { return floatInVec( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 ); } inline const floatInVec lengthSqr( const Vector4 &vec ) { return floatInVec( _vmathVfDot4( vec.get128(), vec.get128() ), 0 ); } inline const floatInVec length( const Vector4 &vec ) { return floatInVec( _mm_sqrt_ps(_vmathVfDot4( vec.get128(), vec.get128() )), 0 ); } inline const Vector4 normalizeApprox( const Vector4 &vec ) { return Vector4( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) ); } inline const Vector4 normalize( const Vector4 &vec ) { return Vector4( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) ); } inline const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 ) { return select( vec0, vec1, boolInVec(select1) ); } inline const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1 ) { return Vector4( vec_sel( vec0.get128(), vec1.get128(), select1.get128() ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Vector4 &vec ) { union { __m128 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } inline void print( const Vector4 &vec, const char * name ) { union { __m128 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif inline Point3::Point3( float _x, float _y, float _z ) { mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); } inline Point3::Point3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z ) { mVec128 = _mm_unpacklo_ps( _mm_unpacklo_ps( _x.get128(), _z.get128() ), _y.get128() ); } inline Point3::Point3( const Vector3 &vec ) { mVec128 = vec.get128(); } inline Point3::Point3( float scalar ) { mVec128 = floatInVec(scalar).get128(); } inline Point3::Point3( const floatInVec &scalar ) { mVec128 = scalar.get128(); } inline Point3::Point3( __m128 vf4 ) { mVec128 = vf4; } inline const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 ) { return lerp( floatInVec(t), pnt0, pnt1 ); } inline const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 ) { return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); } inline __m128 Point3::get128( ) const { return mVec128; } inline void storeXYZ( const Point3 &pnt, __m128 * quad ) { __m128 dstVec = *quad; _VECTORMATH_ALIGNED(unsigned int sw[4]) = {0, 0, 0, 0xffffffff}; // TODO: Centralize dstVec = vec_sel(pnt.get128(), dstVec, sw); *quad = dstVec; } inline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads ) { const float *quads = (float *)threeQuads; pnt0 = Point3( _mm_load_ps(quads) ); pnt1 = Point3( _mm_loadu_ps(quads + 3) ); pnt2 = Point3( _mm_loadu_ps(quads + 6) ); pnt3 = Point3( _mm_loadu_ps(quads + 9) ); } inline void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads ) { __m128 xxxx = _mm_shuffle_ps( pnt1.get128(), pnt1.get128(), _MM_SHUFFLE(0, 0, 0, 0) ); __m128 zzzz = _mm_shuffle_ps( pnt2.get128(), pnt2.get128(), _MM_SHUFFLE(2, 2, 2, 2) ); _VECTORMATH_ALIGNED(unsigned int xsw[4]) = {0, 0, 0, 0xffffffff}; _VECTORMATH_ALIGNED(unsigned int zsw[4]) = {0xffffffff, 0, 0, 0}; threeQuads[0] = vec_sel( pnt0.get128(), xxxx, xsw ); threeQuads[1] = _mm_shuffle_ps( pnt1.get128(), pnt2.get128(), _MM_SHUFFLE(1, 0, 2, 1) ); threeQuads[2] = vec_sel( _mm_shuffle_ps( pnt3.get128(), pnt3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw ); } inline Point3 & Point3::operator =( const Point3 &pnt ) { mVec128 = pnt.mVec128; return *this; } inline Point3 & Point3::setX( float _x ) { _vmathVfSetElement(mVec128, _x, 0); return *this; } inline Point3 & Point3::setX( const floatInVec &_x ) { mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); return *this; } inline const floatInVec Point3::getX( ) const { return floatInVec( mVec128, 0 ); } inline Point3 & Point3::setY( float _y ) { _vmathVfSetElement(mVec128, _y, 1); return *this; } inline Point3 & Point3::setY( const floatInVec &_y ) { mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); return *this; } inline const floatInVec Point3::getY( ) const { return floatInVec( mVec128, 1 ); } inline Point3 & Point3::setZ( float _z ) { _vmathVfSetElement(mVec128, _z, 2); return *this; } inline Point3 & Point3::setZ( const floatInVec &_z ) { mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); return *this; } inline const floatInVec Point3::getZ( ) const { return floatInVec( mVec128, 2 ); } inline Point3 & Point3::setElem( int idx, float value ) { _vmathVfSetElement(mVec128, value, idx); return *this; } inline Point3 & Point3::setElem( int idx, const floatInVec &value ) { mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); return *this; } inline const floatInVec Point3::getElem( int idx ) const { return floatInVec( mVec128, idx ); } inline VecIdx Point3::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline const floatInVec Point3::operator []( int idx ) const { return floatInVec( mVec128, idx ); } inline const Vector3 Point3::operator -( const Point3 &pnt ) const { return Vector3( _mm_sub_ps( mVec128, pnt.mVec128 ) ); } inline const Point3 Point3::operator +( const Vector3 &vec ) const { return Point3( _mm_add_ps( mVec128, vec.get128() ) ); } inline const Point3 Point3::operator -( const Vector3 &vec ) const { return Point3( _mm_sub_ps( mVec128, vec.get128() ) ); } inline Point3 & Point3::operator +=( const Vector3 &vec ) { *this = *this + vec; return *this; } inline Point3 & Point3::operator -=( const Vector3 &vec ) { *this = *this - vec; return *this; } inline const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 ) { return Point3( _mm_mul_ps( pnt0.get128(), pnt1.get128() ) ); } inline const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 ) { return Point3( _mm_div_ps( pnt0.get128(), pnt1.get128() ) ); } inline const Point3 recipPerElem( const Point3 &pnt ) { return Point3( _mm_rcp_ps( pnt.get128() ) ); } inline const Point3 absPerElem( const Point3 &pnt ) { return Point3( fabsf4( pnt.get128() ) ); } inline const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 ) { __m128 vmask = toM128(0x7fffffff); return Point3( _mm_or_ps( _mm_and_ps ( vmask, pnt0.get128() ), // Value _mm_andnot_ps( vmask, pnt1.get128() ) ) ); // Signs } inline const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 ) { return Point3( _mm_max_ps( pnt0.get128(), pnt1.get128() ) ); } inline const floatInVec maxElem( const Point3 &pnt ) { return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); } inline const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 ) { return Point3( _mm_min_ps( pnt0.get128(), pnt1.get128() ) ); } inline const floatInVec minElem( const Point3 &pnt ) { return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); } inline const floatInVec sum( const Point3 &pnt ) { return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); } inline const Point3 scale( const Point3 &pnt, float scaleVal ) { return scale( pnt, floatInVec( scaleVal ) ); } inline const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal ) { return mulPerElem( pnt, Point3( scaleVal ) ); } inline const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec ) { return mulPerElem( pnt, Point3( scaleVec ) ); } inline const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec ) { return floatInVec( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 ); } inline const floatInVec distSqrFromOrigin( const Point3 &pnt ) { return lengthSqr( Vector3( pnt ) ); } inline const floatInVec distFromOrigin( const Point3 &pnt ) { return length( Vector3( pnt ) ); } inline const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 ) { return lengthSqr( ( pnt1 - pnt0 ) ); } inline const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 ) { return length( ( pnt1 - pnt0 ) ); } inline const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 ) { return select( pnt0, pnt1, boolInVec(select1) ); } inline const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 ) { return Point3( vec_sel( pnt0.get128(), pnt1.get128(), select1.get128() ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Point3 &pnt ) { union { __m128 v; float s[4]; } tmp; tmp.v = pnt.get128(); printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } inline void print( const Point3 &pnt, const char * name ) { union { __m128 v; float s[4]; } tmp; tmp.v = pnt.get128(); printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/SSE/cpp/vecidx_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VECIDX_AOS_H #define _VECTORMATH_VECIDX_AOS_H #include "defines.h" #include "floatInVec.h" namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // VecIdx // Used in setting elements of Vector3, Vector4, Point3, or Quat with the // subscripting operator. // _VECTORMATH_ALIGNED_TYPE_1 class VecIdx { private: __m128 &ref; int i; public: inline VecIdx( __m128& vec, int idx ): ref(vec) { i = idx; } // implicitly casts to float unless _VECTORMATH_NO_SCALAR_CAST defined // in which case, implicitly casts to floatInVec, and one must call // getAsFloat to convert to float. // #ifdef _VECTORMATH_NO_SCALAR_CAST inline operator floatInVec() const; inline float getAsFloat() const; #else inline operator float() const; #endif inline float operator =( float scalar ); inline floatInVec operator =( const floatInVec &scalar ); inline floatInVec operator =( const VecIdx& scalar ); inline floatInVec operator *=( float scalar ); inline floatInVec operator *=( const floatInVec &scalar ); inline floatInVec operator /=( float scalar ); inline floatInVec operator /=( const floatInVec &scalar ); inline floatInVec operator +=( float scalar ); inline floatInVec operator +=( const floatInVec &scalar ); inline floatInVec operator -=( float scalar ); inline floatInVec operator -=( const floatInVec &scalar ); } _VECTORMATH_ALIGNED_TYPE_2 ; } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/SSE/cpp/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_CPP_SSE_H #define _VECTORMATH_AOS_CPP_SSE_H #include "defines.h" #include #include #include #include typedef __m128 vec_float4; typedef __m128 vec_uint4; typedef __m128 vec_int4; typedef __m128i vec_uchar16; typedef __m128i vec_ushort8; #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)) #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)) #define _mm_abs_ps(vec) _mm_andnot_ps(_MASKSIGN_,vec) #define _mm_neg_ps(vec) _mm_xor_ps(_MASKSIGN_,vec) #define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e, e, e, e)) #define vec_madd(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b) ) #define vec_sld(vec, vec2, x) _mm_ror_ps(vec, ((x)/4)) union SSEFloat { __m128 m128; float f[4]; }; static inline __m128 vec_sel(__m128 a, __m128 b, __m128 mask) { return _mm_or_ps(_mm_and_ps(mask, b), _mm_andnot_ps(mask, a)); } static inline __m128 vec_sel(__m128 a, __m128 b, const unsigned int *_mask) { return vec_sel(a, b, _mm_load_ps((float *)_mask)); } static inline __m128 vec_sel(__m128 a, __m128 b, unsigned int _mask) { return vec_sel(a, b, _mm_set1_ps(*(float *)&_mask)); } static inline __m128 toM128(unsigned int x) { return _mm_set1_ps( *(float *)&x ); } static inline __m128 fabsf4(__m128 x) { return _mm_and_ps(x, toM128(0x7fffffff)); } /* union SSE64 { __m128 m128; struct { __m64 m01; __m64 m23; } m64; }; static inline __m128 vec_cts(__m128 x, int a) { assert(a == 0); // Only 2^0 supported (void)a; SSE64 sse64; sse64.m64.m01 = _mm_cvttps_pi32(x); sse64.m64.m23 = _mm_cvttps_pi32(_mm_ror_ps(x,2)); _mm_empty(); return sse64.m128; } static inline __m128 vec_ctf(__m128 x, int a) { assert(a == 0); // Only 2^0 supported (void)a; SSE64 sse64; sse64.m128 = x; __m128 result =_mm_movelh_ps( _mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m01), _mm_cvt_pi2ps(_mm_setzero_ps(), sse64.m64.m23)); _mm_empty(); return result; } */ static inline __m128 vec_cts(__m128 x, int a) { assert(a == 0); // Only 2^0 supported (void)a; __m128i result = _mm_cvtps_epi32(x); return (__m128 &)result; } static inline __m128 vec_ctf(__m128 x, int a) { assert(a == 0); // Only 2^0 supported (void)a; return _mm_cvtepi32_ps((__m128i &)x); } #define vec_nmsub(a, b, c) _mm_sub_ps( c, _mm_mul_ps( a, b ) ) #define vec_sub(a, b) _mm_sub_ps( a, b ) #define vec_add(a, b) _mm_add_ps( a, b ) #define vec_mul(a, b) _mm_mul_ps( a, b ) #define vec_xor(a, b) _mm_xor_ps( a, b ) #define vec_and(a, b) _mm_and_ps( a, b ) #define vec_cmpeq(a, b) _mm_cmpeq_ps( a, b ) #define vec_cmpgt(a, b) _mm_cmpgt_ps( a, b ) #define vec_mergeh(a, b) _mm_unpacklo_ps( a, b ) #define vec_mergel(a, b) _mm_unpackhi_ps( a, b ) #define vec_andc(a, b) _mm_andnot_ps( b, a ) #define sqrtf4(x) _mm_sqrt_ps( x ) #define rsqrtf4(x) _mm_rsqrt_ps( x ) #define recipf4(x) _mm_rcp_ps( x ) #define negatef4(x) _mm_sub_ps( _mm_setzero_ps(), x ) static inline __m128 newtonrapson_rsqrt4( const __m128 v ) { #define _half4 _mm_setr_ps(0.5f, 0.5f, 0.5f, 0.5f) #define _three _mm_setr_ps(3.0f, 3.0f, 3.0f, 3.0f) const __m128 approx = _mm_rsqrt_ps(v); const __m128 muls = _mm_mul_ps(_mm_mul_ps(v, approx), approx); return _mm_mul_ps(_mm_mul_ps(_half4, approx), _mm_sub_ps(_three, muls) ); } static inline __m128 acosf4(__m128 x) { __m128 xabs = fabsf4(x); __m128 select = _mm_cmplt_ps( x, _mm_setzero_ps() ); __m128 t1 = sqrtf4(vec_sub(_mm_set1_ps(1.0f), xabs)); /* Instruction counts can be reduced if the polynomial was * computed entirely from nested (dependent) fma's. However, * to reduce the number of pipeline stalls, the polygon is evaluated * in two halves (hi and lo). */ __m128 xabs2 = _mm_mul_ps(xabs, xabs); __m128 xabs4 = _mm_mul_ps(xabs2, xabs2); __m128 hi = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0012624911f), xabs, _mm_set1_ps(0.0066700901f)), xabs, _mm_set1_ps(-0.0170881256f)), xabs, _mm_set1_ps( 0.0308918810f)); __m128 lo = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0501743046f), xabs, _mm_set1_ps(0.0889789874f)), xabs, _mm_set1_ps(-0.2145988016f)), xabs, _mm_set1_ps( 1.5707963050f)); __m128 result = vec_madd(hi, xabs4, lo); // Adjust the result if x is negative. return vec_sel( vec_mul(t1, result), // Positive vec_nmsub(t1, result, _mm_set1_ps(3.1415926535898f)), // Negative select); } static inline __m128 sinf4(vec_float4 x) { // // Common constants used to evaluate sinf4/cosf4/tanf4 // #define _SINCOS_CC0 -0.0013602249f #define _SINCOS_CC1 0.0416566950f #define _SINCOS_CC2 -0.4999990225f #define _SINCOS_SC0 -0.0001950727f #define _SINCOS_SC1 0.0083320758f #define _SINCOS_SC2 -0.1666665247f #define _SINCOS_KC1 1.57079625129f #define _SINCOS_KC2 7.54978995489e-8f vec_float4 xl,xl2,xl3,res; // Range reduction using : xl = angle * TwoOverPi; // xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); // Find the quadrant the angle falls in // using: q = (int) (ceil(abs(xl))*sign(xl)) // vec_int4 q = vec_cts(xl,0); // Compute an offset based on the quadrant that the angle falls in // vec_int4 offset = _mm_and_ps(q,toM128(0x3)); // Remainder in range [-pi/4..pi/4] // vec_float4 qf = vec_ctf(q,0); xl = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x)); // Compute x^2 and x^3 // xl2 = vec_mul(xl,xl); xl3 = vec_mul(xl2,xl); // Compute both the sin and cos of the angles // using a polynomial expression: // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) // vec_float4 cx = vec_madd( vec_madd( vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f)); vec_float4 sx = vec_madd( vec_madd( vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl); // Use the cosine when the offset is odd and the sin // when the offset is even // res = vec_sel(cx,sx,vec_cmpeq(vec_and(offset, toM128(0x1)), _mm_setzero_ps())); // Flip the sign of the result when (offset mod 4) = 1 or 2 // return vec_sel( vec_xor(toM128(0x80000000U), res), // Negative res, // Positive vec_cmpeq(vec_and(offset,toM128(0x2)),_mm_setzero_ps())); } static inline void sincosf4(vec_float4 x, vec_float4* s, vec_float4* c) { vec_float4 xl,xl2,xl3; vec_int4 offsetSin, offsetCos; // Range reduction using : xl = angle * TwoOverPi; // xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); // Find the quadrant the angle falls in // using: q = (int) (ceil(abs(xl))*sign(xl)) // //vec_int4 q = vec_cts(vec_add(xl,vec_sel(_mm_set1_ps(0.5f),xl,(0x80000000))),0); vec_int4 q = vec_cts(xl,0); // Compute the offset based on the quadrant that the angle falls in. // Add 1 to the offset for the cosine. // offsetSin = vec_and(q,toM128((int)0x3)); __m128i temp = _mm_add_epi32(_mm_set1_epi32(1),(__m128i &)offsetSin); offsetCos = (__m128 &)temp; // Remainder in range [-pi/4..pi/4] // vec_float4 qf = vec_ctf(q,0); xl = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x)); // Compute x^2 and x^3 // xl2 = vec_mul(xl,xl); xl3 = vec_mul(xl2,xl); // Compute both the sin and cos of the angles // using a polynomial expression: // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) // vec_float4 cx = vec_madd( vec_madd( vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f)); vec_float4 sx = vec_madd( vec_madd( vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl); // Use the cosine when the offset is odd and the sin // when the offset is even // vec_uint4 sinMask = (vec_uint4)vec_cmpeq(vec_and(offsetSin,toM128(0x1)),_mm_setzero_ps()); vec_uint4 cosMask = (vec_uint4)vec_cmpeq(vec_and(offsetCos,toM128(0x1)),_mm_setzero_ps()); *s = vec_sel(cx,sx,sinMask); *c = vec_sel(cx,sx,cosMask); // Flip the sign of the result when (offset mod 4) = 1 or 2 // sinMask = vec_cmpeq(vec_and(offsetSin,toM128(0x2)),_mm_setzero_ps()); cosMask = vec_cmpeq(vec_and(offsetCos,toM128(0x2)),_mm_setzero_ps()); *s = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*s),*s,sinMask); *c = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*c),*c,cosMask); } #include "vecidx_aos.h" #include "floatInVec.h" #include "boolInVec.h" #ifdef _VECTORMATH_DEBUG #include #endif namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // Forward Declarations // class Vector3; class Vector4; class Point3; class Quat; class Matrix3; class Matrix4; class Transform3; // A 3-D vector in array-of-structures format // _VECTORMATH_ALIGNED_TYPE_1 class Vector3 { private: __m128 mVec128; public: // Default constructor; does no initialization // inline Vector3( ) { }; // Construct a 3-D vector from x, y, and z elements // inline Vector3( float x, float y, float z ); // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type) // inline Vector3( const floatInVec &x, const floatInVec &y, const floatInVec &z ); // Copy elements from a 3-D point into a 3-D vector // explicit inline Vector3( const Point3 &pnt ); // Set all elements of a 3-D vector to the same scalar value // explicit inline Vector3( float scalar ); // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type) // explicit inline Vector3( const floatInVec &scalar ); // Set vector float data in a 3-D vector // explicit inline Vector3( __m128 vf4 ); // Get vector float data from a 3-D vector // inline __m128 get128( ) const; // Assign one 3-D vector to another // inline Vector3 & operator =( const Vector3 &vec ); // Set the x element of a 3-D vector // inline Vector3 & setX( float x ); // Set the y element of a 3-D vector // inline Vector3 & setY( float y ); // Set the z element of a 3-D vector // inline Vector3 & setZ( float z ); // Set the x element of a 3-D vector (scalar data contained in vector data type) // inline Vector3 & setX( const floatInVec &x ); // Set the y element of a 3-D vector (scalar data contained in vector data type) // inline Vector3 & setY( const floatInVec &y ); // Set the z element of a 3-D vector (scalar data contained in vector data type) // inline Vector3 & setZ( const floatInVec &z ); // Get the x element of a 3-D vector // inline const floatInVec getX( ) const; // Get the y element of a 3-D vector // inline const floatInVec getY( ) const; // Get the z element of a 3-D vector // inline const floatInVec getZ( ) const; // Set an x, y, or z element of a 3-D vector by index // inline Vector3 & setElem( int idx, float value ); // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type) // inline Vector3 & setElem( int idx, const floatInVec &value ); // Get an x, y, or z element of a 3-D vector by index // inline const floatInVec getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline const floatInVec operator []( int idx ) const; // Add two 3-D vectors // inline const Vector3 operator +( const Vector3 &vec ) const; // Subtract a 3-D vector from another 3-D vector // inline const Vector3 operator -( const Vector3 &vec ) const; // Add a 3-D vector to a 3-D point // inline const Point3 operator +( const Point3 &pnt ) const; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( float scalar ) const; // Divide a 3-D vector by a scalar // inline const Vector3 operator /( float scalar ) const; // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) // inline const Vector3 operator *( const floatInVec &scalar ) const; // Divide a 3-D vector by a scalar (scalar data contained in vector data type) // inline const Vector3 operator /( const floatInVec &scalar ) const; // Perform compound assignment and addition with a 3-D vector // inline Vector3 & operator +=( const Vector3 &vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Vector3 & operator -=( const Vector3 &vec ); // Perform compound assignment and multiplication by a scalar // inline Vector3 & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Vector3 & operator /=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Vector3 & operator *=( const floatInVec &scalar ); // Perform compound assignment and division by a scalar (scalar data contained in vector data type) // inline Vector3 & operator /=( const floatInVec &scalar ); // Negate all elements of a 3-D vector // inline const Vector3 operator -( ) const; // Construct x axis // static inline const Vector3 xAxis( ); // Construct y axis // static inline const Vector3 yAxis( ); // Construct z axis // static inline const Vector3 zAxis( ); } _VECTORMATH_ALIGNED_TYPE_2 ; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( float scalar, const Vector3 &vec ); // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) // inline const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec ); // Multiply two 3-D vectors per element // inline const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 ); // Divide two 3-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 ); // Compute the reciprocal of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector3 recipPerElem( const Vector3 &vec ); // Compute the absolute value of a 3-D vector per element // inline const Vector3 absPerElem( const Vector3 &vec ); // Copy sign from one 3-D vector to another, per element // inline const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 ); // Maximum of two 3-D vectors per element // inline const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 ); // Minimum of two 3-D vectors per element // inline const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 ); // Maximum element of a 3-D vector // inline const floatInVec maxElem( const Vector3 &vec ); // Minimum element of a 3-D vector // inline const floatInVec minElem( const Vector3 &vec ); // Compute the sum of all elements of a 3-D vector // inline const floatInVec sum( const Vector3 &vec ); // Compute the dot product of two 3-D vectors // inline const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 ); // Compute the square of the length of a 3-D vector // inline const floatInVec lengthSqr( const Vector3 &vec ); // Compute the length of a 3-D vector // inline const floatInVec length( const Vector3 &vec ); // Normalize a 3-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector3 normalize( const Vector3 &vec ); // Compute cross product of two 3-D vectors // inline const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 ); // Outer product of two 3-D vectors // inline const Matrix3 outer( const Vector3 &vec0, const Vector3 &vec1 ); // Pre-multiply a row vector by a 3x3 matrix // NOTE: // Slower than column post-multiply. // inline const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat ); // Cross-product matrix of a 3-D vector // inline const Matrix3 crossMatrix( const Vector3 &vec ); // Create cross-product matrix and multiply // NOTE: // Faster than separately creating a cross-product matrix and multiplying. // inline const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat ); // Linear interpolation between two 3-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 ); // Linear interpolation between two 3-D vectors (scalar data contained in vector data type) // NOTE: // Does not clamp t between 0 and 1. // inline const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 ); // Spherical linear interpolation between two 3-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 ); // Spherical linear interpolation between two 3-D vectors (scalar data contained in vector data type) // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 ); // Conditionally select between two 3-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 ); // Conditionally select between two 3-D vectors (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1 ); // Store x, y, and z elements of 3-D vector in first three words of a quadword, preserving fourth word // inline void storeXYZ( const Vector3 &vec, __m128 * quad ); // Load four three-float 3-D vectors, stored in three quadwords // inline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads ); // Store four 3-D vectors in three quadwords // inline void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads ); // Store eight 3-D vectors as half-floats // inline 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 ); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector3 &vec ); // Print a 3-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector3 &vec, const char * name ); #endif // A 4-D vector in array-of-structures format // _VECTORMATH_ALIGNED_TYPE_1 class Vector4 { private: __m128 mVec128; public: // Default constructor; does no initialization // inline Vector4( ) { }; // Construct a 4-D vector from x, y, z, and w elements // inline Vector4( float x, float y, float z, float w ); // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type) // inline Vector4( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w ); // Construct a 4-D vector from a 3-D vector and a scalar // inline Vector4( const Vector3 &xyz, float w ); // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type) // inline Vector4( const Vector3 &xyz, const floatInVec &w ); // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 // explicit inline Vector4( const Vector3 &vec ); // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 // explicit inline Vector4( const Point3 &pnt ); // Copy elements from a quaternion into a 4-D vector // explicit inline Vector4( const Quat &quat ); // Set all elements of a 4-D vector to the same scalar value // explicit inline Vector4( float scalar ); // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type) // explicit inline Vector4( const floatInVec &scalar ); // Set vector float data in a 4-D vector // explicit inline Vector4( __m128 vf4 ); // Get vector float data from a 4-D vector // inline __m128 get128( ) const; // Assign one 4-D vector to another // inline Vector4 & operator =( const Vector4 &vec ); // Set the x, y, and z elements of a 4-D vector // NOTE: // This function does not change the w element. // inline Vector4 & setXYZ( const Vector3 &vec ); // Get the x, y, and z elements of a 4-D vector // inline const Vector3 getXYZ( ) const; // Set the x element of a 4-D vector // inline Vector4 & setX( float x ); // Set the y element of a 4-D vector // inline Vector4 & setY( float y ); // Set the z element of a 4-D vector // inline Vector4 & setZ( float z ); // Set the w element of a 4-D vector // inline Vector4 & setW( float w ); // Set the x element of a 4-D vector (scalar data contained in vector data type) // inline Vector4 & setX( const floatInVec &x ); // Set the y element of a 4-D vector (scalar data contained in vector data type) // inline Vector4 & setY( const floatInVec &y ); // Set the z element of a 4-D vector (scalar data contained in vector data type) // inline Vector4 & setZ( const floatInVec &z ); // Set the w element of a 4-D vector (scalar data contained in vector data type) // inline Vector4 & setW( const floatInVec &w ); // Get the x element of a 4-D vector // inline const floatInVec getX( ) const; // Get the y element of a 4-D vector // inline const floatInVec getY( ) const; // Get the z element of a 4-D vector // inline const floatInVec getZ( ) const; // Get the w element of a 4-D vector // inline const floatInVec getW( ) const; // Set an x, y, z, or w element of a 4-D vector by index // inline Vector4 & setElem( int idx, float value ); // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type) // inline Vector4 & setElem( int idx, const floatInVec &value ); // Get an x, y, z, or w element of a 4-D vector by index // inline const floatInVec getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline const floatInVec operator []( int idx ) const; // Add two 4-D vectors // inline const Vector4 operator +( const Vector4 &vec ) const; // Subtract a 4-D vector from another 4-D vector // inline const Vector4 operator -( const Vector4 &vec ) const; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( float scalar ) const; // Divide a 4-D vector by a scalar // inline const Vector4 operator /( float scalar ) const; // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) // inline const Vector4 operator *( const floatInVec &scalar ) const; // Divide a 4-D vector by a scalar (scalar data contained in vector data type) // inline const Vector4 operator /( const floatInVec &scalar ) const; // Perform compound assignment and addition with a 4-D vector // inline Vector4 & operator +=( const Vector4 &vec ); // Perform compound assignment and subtraction by a 4-D vector // inline Vector4 & operator -=( const Vector4 &vec ); // Perform compound assignment and multiplication by a scalar // inline Vector4 & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Vector4 & operator /=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Vector4 & operator *=( const floatInVec &scalar ); // Perform compound assignment and division by a scalar (scalar data contained in vector data type) // inline Vector4 & operator /=( const floatInVec &scalar ); // Negate all elements of a 4-D vector // inline const Vector4 operator -( ) const; // Construct x axis // static inline const Vector4 xAxis( ); // Construct y axis // static inline const Vector4 yAxis( ); // Construct z axis // static inline const Vector4 zAxis( ); // Construct w axis // static inline const Vector4 wAxis( ); } _VECTORMATH_ALIGNED_TYPE_2 ; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( float scalar, const Vector4 &vec ); // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) // inline const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec ); // Multiply two 4-D vectors per element // inline const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 ); // Divide two 4-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 ); // Compute the reciprocal of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector4 recipPerElem( const Vector4 &vec ); // Compute the absolute value of a 4-D vector per element // inline const Vector4 absPerElem( const Vector4 &vec ); // Copy sign from one 4-D vector to another, per element // inline const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 ); // Maximum of two 4-D vectors per element // inline const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 ); // Minimum of two 4-D vectors per element // inline const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 ); // Maximum element of a 4-D vector // inline const floatInVec maxElem( const Vector4 &vec ); // Minimum element of a 4-D vector // inline const floatInVec minElem( const Vector4 &vec ); // Compute the sum of all elements of a 4-D vector // inline const floatInVec sum( const Vector4 &vec ); // Compute the dot product of two 4-D vectors // inline const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 ); // Compute the square of the length of a 4-D vector // inline const floatInVec lengthSqr( const Vector4 &vec ); // Compute the length of a 4-D vector // inline const floatInVec length( const Vector4 &vec ); // Normalize a 4-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector4 normalize( const Vector4 &vec ); // Outer product of two 4-D vectors // inline const Matrix4 outer( const Vector4 &vec0, const Vector4 &vec1 ); // Linear interpolation between two 4-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 ); // Linear interpolation between two 4-D vectors (scalar data contained in vector data type) // NOTE: // Does not clamp t between 0 and 1. // inline const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 ); // Spherical linear interpolation between two 4-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 ); // Spherical linear interpolation between two 4-D vectors (scalar data contained in vector data type) // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 ); // Conditionally select between two 4-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 ); // Conditionally select between two 4-D vectors (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1 ); // Store four 4-D vectors as half-floats // inline void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads ); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector4 &vec ); // Print a 4-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector4 &vec, const char * name ); #endif // A 3-D point in array-of-structures format // _VECTORMATH_ALIGNED_TYPE_1 class Point3 { private: __m128 mVec128; public: // Default constructor; does no initialization // inline Point3( ) { }; // Construct a 3-D point from x, y, and z elements // inline Point3( float x, float y, float z ); // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type) // inline Point3( const floatInVec &x, const floatInVec &y, const floatInVec &z ); // Copy elements from a 3-D vector into a 3-D point // explicit inline Point3( const Vector3 &vec ); // Set all elements of a 3-D point to the same scalar value // explicit inline Point3( float scalar ); // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type) // explicit inline Point3( const floatInVec &scalar ); // Set vector float data in a 3-D point // explicit inline Point3( __m128 vf4 ); // Get vector float data from a 3-D point // inline __m128 get128( ) const; // Assign one 3-D point to another // inline Point3 & operator =( const Point3 &pnt ); // Set the x element of a 3-D point // inline Point3 & setX( float x ); // Set the y element of a 3-D point // inline Point3 & setY( float y ); // Set the z element of a 3-D point // inline Point3 & setZ( float z ); // Set the x element of a 3-D point (scalar data contained in vector data type) // inline Point3 & setX( const floatInVec &x ); // Set the y element of a 3-D point (scalar data contained in vector data type) // inline Point3 & setY( const floatInVec &y ); // Set the z element of a 3-D point (scalar data contained in vector data type) // inline Point3 & setZ( const floatInVec &z ); // Get the x element of a 3-D point // inline const floatInVec getX( ) const; // Get the y element of a 3-D point // inline const floatInVec getY( ) const; // Get the z element of a 3-D point // inline const floatInVec getZ( ) const; // Set an x, y, or z element of a 3-D point by index // inline Point3 & setElem( int idx, float value ); // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type) // inline Point3 & setElem( int idx, const floatInVec &value ); // Get an x, y, or z element of a 3-D point by index // inline const floatInVec getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline const floatInVec operator []( int idx ) const; // Subtract a 3-D point from another 3-D point // inline const Vector3 operator -( const Point3 &pnt ) const; // Add a 3-D point to a 3-D vector // inline const Point3 operator +( const Vector3 &vec ) const; // Subtract a 3-D vector from a 3-D point // inline const Point3 operator -( const Vector3 &vec ) const; // Perform compound assignment and addition with a 3-D vector // inline Point3 & operator +=( const Vector3 &vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Point3 & operator -=( const Vector3 &vec ); } _VECTORMATH_ALIGNED_TYPE_2 ; // Multiply two 3-D points per element // inline const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 ); // Divide two 3-D points per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 ); // Compute the reciprocal of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Point3 recipPerElem( const Point3 &pnt ); // Compute the absolute value of a 3-D point per element // inline const Point3 absPerElem( const Point3 &pnt ); // Copy sign from one 3-D point to another, per element // inline const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 ); // Maximum of two 3-D points per element // inline const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 ); // Minimum of two 3-D points per element // inline const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 ); // Maximum element of a 3-D point // inline const floatInVec maxElem( const Point3 &pnt ); // Minimum element of a 3-D point // inline const floatInVec minElem( const Point3 &pnt ); // Compute the sum of all elements of a 3-D point // inline const floatInVec sum( const Point3 &pnt ); // Apply uniform scale to a 3-D point // inline const Point3 scale( const Point3 &pnt, float scaleVal ); // Apply uniform scale to a 3-D point (scalar data contained in vector data type) // inline const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal ); // Apply non-uniform scale to a 3-D point // inline const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec ); // Scalar projection of a 3-D point on a unit-length 3-D vector // inline const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec ); // Compute the square of the distance of a 3-D point from the coordinate-system origin // inline const floatInVec distSqrFromOrigin( const Point3 &pnt ); // Compute the distance of a 3-D point from the coordinate-system origin // inline const floatInVec distFromOrigin( const Point3 &pnt ); // Compute the square of the distance between two 3-D points // inline const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 ); // Compute the distance between two 3-D points // inline const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 ); // Linear interpolation between two 3-D points // NOTE: // Does not clamp t between 0 and 1. // inline const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 ); // Linear interpolation between two 3-D points (scalar data contained in vector data type) // NOTE: // Does not clamp t between 0 and 1. // inline const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 ); // Conditionally select between two 3-D points // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 ); // Conditionally select between two 3-D points (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 ); // Store x, y, and z elements of 3-D point in first three words of a quadword, preserving fourth word // inline void storeXYZ( const Point3 &pnt, __m128 * quad ); // Load four three-float 3-D points, stored in three quadwords // inline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads ); // Store four 3-D points in three quadwords // inline void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads ); // Store eight 3-D points as half-floats // inline 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 ); #ifdef _VECTORMATH_DEBUG // Print a 3-D point // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Point3 &pnt ); // Print a 3-D point and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Point3 &pnt, const char * name ); #endif // A quaternion in array-of-structures format // _VECTORMATH_ALIGNED_TYPE_1 class Quat { private: __m128 mVec128; public: // Default constructor; does no initialization // inline Quat( ) { }; // Construct a quaternion from x, y, z, and w elements // inline Quat( float x, float y, float z, float w ); // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type) // inline Quat( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w ); // Construct a quaternion from a 3-D vector and a scalar // inline Quat( const Vector3 &xyz, float w ); // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type) // inline Quat( const Vector3 &xyz, const floatInVec &w ); // Copy elements from a 4-D vector into a quaternion // explicit inline Quat( const Vector4 &vec ); // Convert a rotation matrix to a unit-length quaternion // explicit inline Quat( const Matrix3 & rotMat ); // Set all elements of a quaternion to the same scalar value // explicit inline Quat( float scalar ); // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type) // explicit inline Quat( const floatInVec &scalar ); // Set vector float data in a quaternion // explicit inline Quat( __m128 vf4 ); // Get vector float data from a quaternion // inline __m128 get128( ) const; // Assign one quaternion to another // inline Quat & operator =( const Quat &quat ); // Set the x, y, and z elements of a quaternion // NOTE: // This function does not change the w element. // inline Quat & setXYZ( const Vector3 &vec ); // Get the x, y, and z elements of a quaternion // inline const Vector3 getXYZ( ) const; // Set the x element of a quaternion // inline Quat & setX( float x ); // Set the y element of a quaternion // inline Quat & setY( float y ); // Set the z element of a quaternion // inline Quat & setZ( float z ); // Set the w element of a quaternion // inline Quat & setW( float w ); // Set the x element of a quaternion (scalar data contained in vector data type) // inline Quat & setX( const floatInVec &x ); // Set the y element of a quaternion (scalar data contained in vector data type) // inline Quat & setY( const floatInVec &y ); // Set the z element of a quaternion (scalar data contained in vector data type) // inline Quat & setZ( const floatInVec &z ); // Set the w element of a quaternion (scalar data contained in vector data type) // inline Quat & setW( const floatInVec &w ); // Get the x element of a quaternion // inline const floatInVec getX( ) const; // Get the y element of a quaternion // inline const floatInVec getY( ) const; // Get the z element of a quaternion // inline const floatInVec getZ( ) const; // Get the w element of a quaternion // inline const floatInVec getW( ) const; // Set an x, y, z, or w element of a quaternion by index // inline Quat & setElem( int idx, float value ); // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type) // inline Quat & setElem( int idx, const floatInVec &value ); // Get an x, y, z, or w element of a quaternion by index // inline const floatInVec getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline const floatInVec operator []( int idx ) const; // Add two quaternions // inline const Quat operator +( const Quat &quat ) const; // Subtract a quaternion from another quaternion // inline const Quat operator -( const Quat &quat ) const; // Multiply two quaternions // inline const Quat operator *( const Quat &quat ) const; // Multiply a quaternion by a scalar // inline const Quat operator *( float scalar ) const; // Divide a quaternion by a scalar // inline const Quat operator /( float scalar ) const; // Multiply a quaternion by a scalar (scalar data contained in vector data type) // inline const Quat operator *( const floatInVec &scalar ) const; // Divide a quaternion by a scalar (scalar data contained in vector data type) // inline const Quat operator /( const floatInVec &scalar ) const; // Perform compound assignment and addition with a quaternion // inline Quat & operator +=( const Quat &quat ); // Perform compound assignment and subtraction by a quaternion // inline Quat & operator -=( const Quat &quat ); // Perform compound assignment and multiplication by a quaternion // inline Quat & operator *=( const Quat &quat ); // Perform compound assignment and multiplication by a scalar // inline Quat & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Quat & operator /=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Quat & operator *=( const floatInVec &scalar ); // Perform compound assignment and division by a scalar (scalar data contained in vector data type) // inline Quat & operator /=( const floatInVec &scalar ); // Negate all elements of a quaternion // inline const Quat operator -( ) const; // Construct an identity quaternion // static inline const Quat identity( ); // Construct a quaternion to rotate between two unit-length 3-D vectors // NOTE: // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. // static inline const Quat rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 ); // Construct a quaternion to rotate around a unit-length 3-D vector // static inline const Quat rotation( float radians, const Vector3 &unitVec ); // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type) // static inline const Quat rotation( const floatInVec &radians, const Vector3 &unitVec ); // Construct a quaternion to rotate around the x axis // static inline const Quat rotationX( float radians ); // Construct a quaternion to rotate around the y axis // static inline const Quat rotationY( float radians ); // Construct a quaternion to rotate around the z axis // static inline const Quat rotationZ( float radians ); // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type) // static inline const Quat rotationX( const floatInVec &radians ); // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type) // static inline const Quat rotationY( const floatInVec &radians ); // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type) // static inline const Quat rotationZ( const floatInVec &radians ); } _VECTORMATH_ALIGNED_TYPE_2 ; // Multiply a quaternion by a scalar // inline const Quat operator *( float scalar, const Quat &quat ); // Multiply a quaternion by a scalar (scalar data contained in vector data type) // inline const Quat operator *( const floatInVec &scalar, const Quat &quat ); // Compute the conjugate of a quaternion // inline const Quat conj( const Quat &quat ); // Use a unit-length quaternion to rotate a 3-D vector // inline const Vector3 rotate( const Quat &unitQuat, const Vector3 &vec ); // Compute the dot product of two quaternions // inline const floatInVec dot( const Quat &quat0, const Quat &quat1 ); // Compute the norm of a quaternion // inline const floatInVec norm( const Quat &quat ); // Compute the length of a quaternion // inline const floatInVec length( const Quat &quat ); // Normalize a quaternion // NOTE: // The result is unpredictable when all elements of quat are at or near zero. // inline const Quat normalize( const Quat &quat ); // Linear interpolation between two quaternions // NOTE: // Does not clamp t between 0 and 1. // inline const Quat lerp( float t, const Quat &quat0, const Quat &quat1 ); // Linear interpolation between two quaternions (scalar data contained in vector data type) // NOTE: // Does not clamp t between 0 and 1. // inline const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 ); // Spherical linear interpolation between two quaternions // NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. // inline const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 ); // Spherical linear interpolation between two quaternions (scalar data contained in vector data type) // NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. // inline const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 ); // Spherical quadrangle interpolation // inline const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ); // Spherical quadrangle interpolation (scalar data contained in vector data type) // inline const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ); // Conditionally select between two quaternions // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Quat select( const Quat &quat0, const Quat &quat1, bool select1 ); // Conditionally select between two quaternions (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 ); #ifdef _VECTORMATH_DEBUG // Print a quaternion // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Quat &quat ); // Print a quaternion and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Quat &quat, const char * name ); #endif // A 3x3 matrix in array-of-structures format // _VECTORMATH_ALIGNED_TYPE_1 class Matrix3 { private: Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; public: // Default constructor; does no initialization // inline Matrix3( ) { }; // Copy a 3x3 matrix // inline Matrix3( const Matrix3 & mat ); // Construct a 3x3 matrix containing the specified columns // inline Matrix3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2 ); // Construct a 3x3 rotation matrix from a unit-length quaternion // explicit inline Matrix3( const Quat &unitQuat ); // Set all elements of a 3x3 matrix to the same scalar value // explicit inline Matrix3( float scalar ); // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type) // explicit inline Matrix3( const floatInVec &scalar ); // Assign one 3x3 matrix to another // inline Matrix3 & operator =( const Matrix3 & mat ); // Set column 0 of a 3x3 matrix // inline Matrix3 & setCol0( const Vector3 &col0 ); // Set column 1 of a 3x3 matrix // inline Matrix3 & setCol1( const Vector3 &col1 ); // Set column 2 of a 3x3 matrix // inline Matrix3 & setCol2( const Vector3 &col2 ); // Get column 0 of a 3x3 matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x3 matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x3 matrix // inline const Vector3 getCol2( ) const; // Set the column of a 3x3 matrix referred to by the specified index // inline Matrix3 & setCol( int col, const Vector3 &vec ); // Set the row of a 3x3 matrix referred to by the specified index // inline Matrix3 & setRow( int row, const Vector3 &vec ); // Get the column of a 3x3 matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x3 matrix referred to by the specified index // inline const Vector3 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x3 matrix referred to by column and row indices // inline Matrix3 & setElem( int col, int row, float val ); // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type) // inline Matrix3 & setElem( int col, int row, const floatInVec &val ); // Get the element of a 3x3 matrix referred to by column and row indices // inline const floatInVec getElem( int col, int row ) const; // Add two 3x3 matrices // inline const Matrix3 operator +( const Matrix3 & mat ) const; // Subtract a 3x3 matrix from another 3x3 matrix // inline const Matrix3 operator -( const Matrix3 & mat ) const; // Negate all elements of a 3x3 matrix // inline const Matrix3 operator -( ) const; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( float scalar ) const; // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) // inline const Matrix3 operator *( const floatInVec &scalar ) const; // Multiply a 3x3 matrix by a 3-D vector // inline const Vector3 operator *( const Vector3 &vec ) const; // Multiply two 3x3 matrices // inline const Matrix3 operator *( const Matrix3 & mat ) const; // Perform compound assignment and addition with a 3x3 matrix // inline Matrix3 & operator +=( const Matrix3 & mat ); // Perform compound assignment and subtraction by a 3x3 matrix // inline Matrix3 & operator -=( const Matrix3 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix3 & operator *=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Matrix3 & operator *=( const floatInVec &scalar ); // Perform compound assignment and multiplication by a 3x3 matrix // inline Matrix3 & operator *=( const Matrix3 & mat ); // Construct an identity 3x3 matrix // static inline const Matrix3 identity( ); // Construct a 3x3 matrix to rotate around the x axis // static inline const Matrix3 rotationX( float radians ); // Construct a 3x3 matrix to rotate around the y axis // static inline const Matrix3 rotationY( float radians ); // Construct a 3x3 matrix to rotate around the z axis // static inline const Matrix3 rotationZ( float radians ); // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type) // static inline const Matrix3 rotationX( const floatInVec &radians ); // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type) // static inline const Matrix3 rotationY( const floatInVec &radians ); // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type) // static inline const Matrix3 rotationZ( const floatInVec &radians ); // Construct a 3x3 matrix to rotate around the x, y, and z axes // static inline const Matrix3 rotationZYX( const Vector3 &radiansXYZ ); // Construct a 3x3 matrix to rotate around a unit-length 3-D vector // static inline const Matrix3 rotation( float radians, const Vector3 &unitVec ); // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) // static inline const Matrix3 rotation( const floatInVec &radians, const Vector3 &unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix3 rotation( const Quat &unitQuat ); // Construct a 3x3 matrix to perform scaling // static inline const Matrix3 scale( const Vector3 &scaleVec ); } _VECTORMATH_ALIGNED_TYPE_2 ; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) // inline const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat ); // Append (post-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat ); // Multiply two 3x3 matrices per element // inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); // Compute the absolute value of a 3x3 matrix per element // inline const Matrix3 absPerElem( const Matrix3 & mat ); // Transpose of a 3x3 matrix // inline const Matrix3 transpose( const Matrix3 & mat ); // Compute the inverse of a 3x3 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix3 inverse( const Matrix3 & mat ); // Determinant of a 3x3 matrix // inline const floatInVec determinant( const Matrix3 & mat ); // Conditionally select between two 3x3 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); // Conditionally select between two 3x3 matrices (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat ); // Print a 3x3 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat, const char * name ); #endif // A 4x4 matrix in array-of-structures format // _VECTORMATH_ALIGNED_TYPE_1 class Matrix4 { private: Vector4 mCol0; Vector4 mCol1; Vector4 mCol2; Vector4 mCol3; public: // Default constructor; does no initialization // inline Matrix4( ) { }; // Copy a 4x4 matrix // inline Matrix4( const Matrix4 & mat ); // Construct a 4x4 matrix containing the specified columns // inline Matrix4( const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3 ); // Construct a 4x4 matrix from a 3x4 transformation matrix // explicit inline Matrix4( const Transform3 & mat ); // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector // inline Matrix4( const Matrix3 & mat, const Vector3 &translateVec ); // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector // inline Matrix4( const Quat &unitQuat, const Vector3 &translateVec ); // Set all elements of a 4x4 matrix to the same scalar value // explicit inline Matrix4( float scalar ); // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type) // explicit inline Matrix4( const floatInVec &scalar ); // Assign one 4x4 matrix to another // inline Matrix4 & operator =( const Matrix4 & mat ); // Set the upper-left 3x3 submatrix // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 4x4 matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setTranslation( const Vector3 &translateVec ); // Get the translation component of a 4x4 matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 4x4 matrix // inline Matrix4 & setCol0( const Vector4 &col0 ); // Set column 1 of a 4x4 matrix // inline Matrix4 & setCol1( const Vector4 &col1 ); // Set column 2 of a 4x4 matrix // inline Matrix4 & setCol2( const Vector4 &col2 ); // Set column 3 of a 4x4 matrix // inline Matrix4 & setCol3( const Vector4 &col3 ); // Get column 0 of a 4x4 matrix // inline const Vector4 getCol0( ) const; // Get column 1 of a 4x4 matrix // inline const Vector4 getCol1( ) const; // Get column 2 of a 4x4 matrix // inline const Vector4 getCol2( ) const; // Get column 3 of a 4x4 matrix // inline const Vector4 getCol3( ) const; // Set the column of a 4x4 matrix referred to by the specified index // inline Matrix4 & setCol( int col, const Vector4 &vec ); // Set the row of a 4x4 matrix referred to by the specified index // inline Matrix4 & setRow( int row, const Vector4 &vec ); // Get the column of a 4x4 matrix referred to by the specified index // inline const Vector4 getCol( int col ) const; // Get the row of a 4x4 matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector4 & operator []( int col ); // Subscripting operator to get a column // inline const Vector4 operator []( int col ) const; // Set the element of a 4x4 matrix referred to by column and row indices // inline Matrix4 & setElem( int col, int row, float val ); // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type) // inline Matrix4 & setElem( int col, int row, const floatInVec &val ); // Get the element of a 4x4 matrix referred to by column and row indices // inline const floatInVec getElem( int col, int row ) const; // Add two 4x4 matrices // inline const Matrix4 operator +( const Matrix4 & mat ) const; // Subtract a 4x4 matrix from another 4x4 matrix // inline const Matrix4 operator -( const Matrix4 & mat ) const; // Negate all elements of a 4x4 matrix // inline const Matrix4 operator -( ) const; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( float scalar ) const; // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) // inline const Matrix4 operator *( const floatInVec &scalar ) const; // Multiply a 4x4 matrix by a 4-D vector // inline const Vector4 operator *( const Vector4 &vec ) const; // Multiply a 4x4 matrix by a 3-D vector // inline const Vector4 operator *( const Vector3 &vec ) const; // Multiply a 4x4 matrix by a 3-D point // inline const Vector4 operator *( const Point3 &pnt ) const; // Multiply two 4x4 matrices // inline const Matrix4 operator *( const Matrix4 & mat ) const; // Multiply a 4x4 matrix by a 3x4 transformation matrix // inline const Matrix4 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and addition with a 4x4 matrix // inline Matrix4 & operator +=( const Matrix4 & mat ); // Perform compound assignment and subtraction by a 4x4 matrix // inline Matrix4 & operator -=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix4 & operator *=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Matrix4 & operator *=( const floatInVec &scalar ); // Perform compound assignment and multiplication by a 4x4 matrix // inline Matrix4 & operator *=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Matrix4 & operator *=( const Transform3 & tfrm ); // Construct an identity 4x4 matrix // static inline const Matrix4 identity( ); // Construct a 4x4 matrix to rotate around the x axis // static inline const Matrix4 rotationX( float radians ); // Construct a 4x4 matrix to rotate around the y axis // static inline const Matrix4 rotationY( float radians ); // Construct a 4x4 matrix to rotate around the z axis // static inline const Matrix4 rotationZ( float radians ); // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type) // static inline const Matrix4 rotationX( const floatInVec &radians ); // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type) // static inline const Matrix4 rotationY( const floatInVec &radians ); // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type) // static inline const Matrix4 rotationZ( const floatInVec &radians ); // Construct a 4x4 matrix to rotate around the x, y, and z axes // static inline const Matrix4 rotationZYX( const Vector3 &radiansXYZ ); // Construct a 4x4 matrix to rotate around a unit-length 3-D vector // static inline const Matrix4 rotation( float radians, const Vector3 &unitVec ); // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) // static inline const Matrix4 rotation( const floatInVec &radians, const Vector3 &unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix4 rotation( const Quat &unitQuat ); // Construct a 4x4 matrix to perform scaling // static inline const Matrix4 scale( const Vector3 &scaleVec ); // Construct a 4x4 matrix to perform translation // static inline const Matrix4 translation( const Vector3 &translateVec ); // Construct viewing matrix based on eye, position looked at, and up direction // static inline const Matrix4 lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec ); // Construct a perspective projection matrix // static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); // Construct a perspective projection matrix based on frustum // static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); // Construct an orthographic projection matrix // static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); } _VECTORMATH_ALIGNED_TYPE_2 ; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) // inline const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat ); // Append (post-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec ); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat ); // Multiply two 4x4 matrices per element // inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); // Compute the absolute value of a 4x4 matrix per element // inline const Matrix4 absPerElem( const Matrix4 & mat ); // Transpose of a 4x4 matrix // inline const Matrix4 transpose( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix4 inverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix // NOTE: // 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. // inline const Matrix4 affineInverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. // inline const Matrix4 orthoInverse( const Matrix4 & mat ); // Determinant of a 4x4 matrix // inline const floatInVec determinant( const Matrix4 & mat ); // Conditionally select between two 4x4 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); // Conditionally select between two 4x4 matrices (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 ); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat ); // Print a 4x4 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat, const char * name ); #endif // A 3x4 transformation matrix in array-of-structures format // _VECTORMATH_ALIGNED_TYPE_1 class Transform3 { private: Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; Vector3 mCol3; public: // Default constructor; does no initialization // inline Transform3( ) { }; // Copy a 3x4 transformation matrix // inline Transform3( const Transform3 & tfrm ); // Construct a 3x4 transformation matrix containing the specified columns // inline Transform3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3 ); // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector // inline Transform3( const Matrix3 & tfrm, const Vector3 &translateVec ); // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector // inline Transform3( const Quat &unitQuat, const Vector3 &translateVec ); // Set all elements of a 3x4 transformation matrix to the same scalar value // explicit inline Transform3( float scalar ); // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type) // explicit inline Transform3( const floatInVec &scalar ); // Assign one 3x4 transformation matrix to another // inline Transform3 & operator =( const Transform3 & tfrm ); // Set the upper-left 3x3 submatrix // inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // inline Transform3 & setTranslation( const Vector3 &translateVec ); // Get the translation component of a 3x4 transformation matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 3x4 transformation matrix // inline Transform3 & setCol0( const Vector3 &col0 ); // Set column 1 of a 3x4 transformation matrix // inline Transform3 & setCol1( const Vector3 &col1 ); // Set column 2 of a 3x4 transformation matrix // inline Transform3 & setCol2( const Vector3 &col2 ); // Set column 3 of a 3x4 transformation matrix // inline Transform3 & setCol3( const Vector3 &col3 ); // Get column 0 of a 3x4 transformation matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x4 transformation matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x4 transformation matrix // inline const Vector3 getCol2( ) const; // Get column 3 of a 3x4 transformation matrix // inline const Vector3 getCol3( ) const; // Set the column of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setCol( int col, const Vector3 &vec ); // Set the row of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setRow( int row, const Vector4 &vec ); // Get the column of a 3x4 transformation matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x4 transformation matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x4 transformation matrix referred to by column and row indices // inline Transform3 & setElem( int col, int row, float val ); // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type) // inline Transform3 & setElem( int col, int row, const floatInVec &val ); // Get the element of a 3x4 transformation matrix referred to by column and row indices // inline const floatInVec getElem( int col, int row ) const; // Multiply a 3x4 transformation matrix by a 3-D vector // inline const Vector3 operator *( const Vector3 &vec ) const; // Multiply a 3x4 transformation matrix by a 3-D point // inline const Point3 operator *( const Point3 &pnt ) const; // Multiply two 3x4 transformation matrices // inline const Transform3 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Transform3 & operator *=( const Transform3 & tfrm ); // Construct an identity 3x4 transformation matrix // static inline const Transform3 identity( ); // Construct a 3x4 transformation matrix to rotate around the x axis // static inline const Transform3 rotationX( float radians ); // Construct a 3x4 transformation matrix to rotate around the y axis // static inline const Transform3 rotationY( float radians ); // Construct a 3x4 transformation matrix to rotate around the z axis // static inline const Transform3 rotationZ( float radians ); // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type) // static inline const Transform3 rotationX( const floatInVec &radians ); // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type) // static inline const Transform3 rotationY( const floatInVec &radians ); // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type) // static inline const Transform3 rotationZ( const floatInVec &radians ); // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes // static inline const Transform3 rotationZYX( const Vector3 &radiansXYZ ); // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector // static inline const Transform3 rotation( float radians, const Vector3 &unitVec ); // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) // static inline const Transform3 rotation( const floatInVec &radians, const Vector3 &unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Transform3 rotation( const Quat &unitQuat ); // Construct a 3x4 transformation matrix to perform scaling // static inline const Transform3 scale( const Vector3 &scaleVec ); // Construct a 3x4 transformation matrix to perform translation // static inline const Transform3 translation( const Vector3 &translateVec ); } _VECTORMATH_ALIGNED_TYPE_2 ; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm ); // Multiply two 3x4 transformation matrices per element // inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); // Compute the absolute value of a 3x4 transformation matrix per element // inline const Transform3 absPerElem( const Transform3 & tfrm ); // Inverse of a 3x4 transformation matrix // NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. // inline const Transform3 inverse( const Transform3 & tfrm ); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. // inline const Transform3 orthoInverse( const Transform3 & tfrm ); // Conditionally select between two 3x4 transformation matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); // Conditionally select between two 3x4 transformation matrices (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm ); // Print a 3x4 transformation matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm, const char * name ); #endif } // namespace Aos } // namespace Vectormath #include "vec_aos.h" #include "quat_aos.h" #include "mat_aos.h" #endif ================================================ FILE: samples/vectormath/c/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_C_H #define _VECTORMATH_AOS_C_H #if defined(__SPU__) #include "../spu/c/vectormath_aos.h" #define VMATH_SPU 1 #elif defined(__ALTIVEC__) #include "../ppu/c/vectormath_aos.h" #define VMATH_ALTIVEC 1 #else #include "../scalar/c/vectormath_aos.h" #define VMATH_SCALAR 1 #endif #endif ================================================ FILE: samples/vectormath/c/vectormath_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_C_V_H #define _VECTORMATH_AOS_C_V_H #if defined(__SPU__) #include "../spu/c/vectormath_aos_v.h" #define VMATH_SPU 1 #elif defined(__ALTIVEC__) #include "../ppu/c/vectormath_aos_v.h" #define VMATH_ALTIVEC 1 #else #include "../scalar/c/vectormath_aos_v.h" #define VMATH_SCALAR 1 #endif #endif ================================================ FILE: samples/vectormath/c/vectormath_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_C_H #define _VECTORMATH_SOA_C_H #if defined(__SPU__) #include "../spu/c/vectormath_soa.h" #define VMATH_SPU 1 #elif defined(__ALTIVEC__) #include "../ppu/c/vectormath_soa.h" #define VMATH_ALTIVEC 1 #else #error "Vectormath library not implemented!" #endif #endif ================================================ FILE: samples/vectormath/c/vectormath_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_C_V_H #define _VECTORMATH_SOA_C_V_H #if defined(__SPU__) #include "../spu/c/vectormath_soa_v.h" #define VMATH_SPU 1 #elif defined(__ALTIVEC__) #include "../ppu/c/vectormath_soa_v.h" #define VMATH_ALTIVEC 1 #else #error "Vectormath library not implemented!" #endif #endif ================================================ FILE: samples/vectormath/cpp/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_CPP_H #define _VECTORMATH_AOS_CPP_H #if defined(__SPU__) #include "../spu/cpp/vectormath_aos.h" #define VMATH_SPU 1 #elif defined(__ALTIVEC__) #include "../ppu/cpp/vectormath_aos.h" #define VMATH_ALTIVEC 1 #elif defined(__SSE__) #include "../SSE/cpp/vectormath_aos.h" #define VMATH_SSE 1 #else #include "../scalar/cpp/vectormath_aos.h" #define VMATH_SCALAR 1 #endif #endif ================================================ FILE: samples/vectormath/cpp/vectormath_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_CPP_H #define _VECTORMATH_SOA_CPP_H #if defined(__SPU__) #include "../spu/cpp/vectormath_soa.h" #define VMATH_SPU 1 #elif defined(__ALTIVEC__) #include "../ppu/cpp/vectormath_soa.h" #define VMATH_ALTIVEC 1 #else #error "Vectormath library not implemented!" #endif #endif ================================================ FILE: samples/vectormath/ppu/c/mat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_C_H #define _VECTORMATH_MAT_AOS_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for shuffles, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z }) #define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y }) #define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( &result->col0, &mat->col0 ); vmathV3Copy( &result->col1, &mat->col1 ); vmathV3Copy( &result->col2, &mat->col2 ); } static inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar ) { vmathV3MakeFromScalar( &result->col0, scalar ); vmathV3MakeFromScalar( &result->col1, scalar ); vmathV3MakeFromScalar( &result->col2, scalar ); } static inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat ) { vec_float4 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; vec_uint4 select_x = _VECTORMATH_MASK_0xF000; vec_uint4 select_z = _VECTORMATH_MASK_0x00F0; xyzw_2 = vec_add( unitQuat->vec128, unitQuat->vec128 ); wwww = vec_splat( unitQuat->vec128, 3 ); yzxw = vec_perm( unitQuat->vec128, unitQuat->vec128, _VECTORMATH_PERM_YZXW ); zxyw = vec_perm( unitQuat->vec128, unitQuat->vec128, _VECTORMATH_PERM_ZXYW ); yzxw_2 = vec_perm( xyzw_2, xyzw_2, _VECTORMATH_PERM_YZXW ); zxyw_2 = vec_perm( xyzw_2, xyzw_2, _VECTORMATH_PERM_ZXYW ); tmp0 = vec_madd( yzxw_2, wwww, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp1 = vec_nmsub( yzxw, yzxw_2, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); tmp2 = vec_madd( yzxw, xyzw_2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp0 = vec_madd( zxyw, xyzw_2, tmp0 ); tmp1 = vec_nmsub( zxyw, zxyw_2, tmp1 ); tmp2 = vec_nmsub( zxyw_2, wwww, tmp2 ); tmp3 = vec_sel( tmp0, tmp1, select_x ); tmp4 = vec_sel( tmp1, tmp2, select_x ); tmp5 = vec_sel( tmp2, tmp0, select_x ); result->col0.vec128 = vec_sel( tmp3, tmp2, select_z ); result->col1.vec128 = vec_sel( tmp4, tmp0, select_z ); result->col2.vec128 = vec_sel( tmp5, tmp1, select_z ); } static inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col0, _col0 ); vmathV3Copy( &result->col1, _col1 ); vmathV3Copy( &result->col2, _col2 ); } static inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *_col0 ) { vmathV3Copy( &result->col0, _col0 ); } static inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *_col1 ) { vmathV3Copy( &result->col1, _col1 ); } static inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col2, _col2 ); } static inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec ) { vmathV3Copy( (&result->col0 + col), vec ); } static inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec ) { vmathV3SetElem( &result->col0, row, vmathV3GetElem( vec, 0 ) ); vmathV3SetElem( &result->col1, row, vmathV3GetElem( vec, 1 ) ); vmathV3SetElem( &result->col2, row, vmathV3GetElem( vec, 2 ) ); } static inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val ) { VmathVector3 tmpV3_0; vmathM3GetCol( &tmpV3_0, result, col ); vmathV3SetElem( &tmpV3_0, row, val ); vmathM3SetCol( result, col, &tmpV3_0 ); } static inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row ) { VmathVector3 tmpV3_0; vmathM3GetCol( &tmpV3_0, mat, col ); return vmathV3GetElem( &tmpV3_0, row ); } static inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col0 ); } static inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col1 ); } static inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col2 ); } static inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col ) { vmathV3Copy( result, (&mat->col0 + col) ); } static inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row ) { vmathV3MakeFromElems( result, vmathV3GetElem( &mat->col0, row ), vmathV3GetElem( &mat->col1, row ), vmathV3GetElem( &mat->col2, row ) ); } static inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vec_float4 tmp0, tmp1, res0, res1, res2; tmp0 = vec_mergeh( mat->col0.vec128, mat->col2.vec128 ); tmp1 = vec_mergel( mat->col0.vec128, mat->col2.vec128 ); res0 = vec_mergeh( tmp0, mat->col1.vec128 ); res1 = vec_perm( tmp0, mat->col1.vec128, _VECTORMATH_PERM_ZBWX ); res2 = vec_perm( tmp1, mat->col1.vec128, _VECTORMATH_PERM_XCYX ); result->col0.vec128 = res0; result->col1.vec128 = res1; result->col2.vec128 = res2; } static inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); tmp2 = _vmathVfCross( mat->col0.vec128, mat->col1.vec128 ); tmp0 = _vmathVfCross( mat->col1.vec128, mat->col2.vec128 ); tmp1 = _vmathVfCross( mat->col2.vec128, mat->col0.vec128 ); dot = _vmathVfDot3( tmp2, mat->col2.vec128 ); dot = vec_splat( dot, 0 ); invdet = recipf4( dot ); tmp3 = vec_mergeh( tmp0, tmp2 ); tmp4 = vec_mergel( tmp0, tmp2 ); inv0 = vec_mergeh( tmp3, tmp1 ); inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); inv0 = vec_madd( inv0, invdet, zero ); inv1 = vec_madd( inv1, invdet, zero ); inv2 = vec_madd( inv2, invdet, zero ); result->col0.vec128 = inv0; result->col1.vec128 = inv1; result->col2.vec128 = inv2; } static inline float vmathM3Determinant( const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0; vmathV3Cross( &tmpV3_0, &mat->col0, &mat->col1 ); return vmathV3Dot( &mat->col2, &tmpV3_0 ); } static inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3Add( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3Sub( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3Neg( &result->col0, &mat->col0 ); vmathV3Neg( &result->col1, &mat->col1 ); vmathV3Neg( &result->col2, &mat->col2 ); } static inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3AbsPerElem( &result->col0, &mat->col0 ); vmathV3AbsPerElem( &result->col1, &mat->col1 ); vmathV3AbsPerElem( &result->col2, &mat->col2 ); } static inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar ) { vmathV3ScalarMul( &result->col0, &mat->col0, scalar ); vmathV3ScalarMul( &result->col1, &mat->col1, scalar ); vmathV3ScalarMul( &result->col2, &mat->col2, scalar ); } static inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec ) { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; xxxx = vec_splat( vec->vec128, 0 ); yyyy = vec_splat( vec->vec128, 1 ); zzzz = vec_splat( vec->vec128, 2 ); res = vec_madd( mat->col0.vec128, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); res = vec_madd( mat->col1.vec128, yyyy, res ); res = vec_madd( mat->col2.vec128, zzzz, res ); result->vec128 = res; } static inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { VmathMatrix3 tmpResult; vmathM3MulV3( &tmpResult.col0, mat0, &mat1->col0 ); vmathM3MulV3( &tmpResult.col1, mat0, &mat1->col1 ); vmathM3MulV3( &tmpResult.col2, mat0, &mat1->col2 ); vmathM3Copy( result, &tmpResult ); } static inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3MakeIdentity( VmathMatrix3 *result ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); } static inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = _VECTORMATH_MASK_0x0F00; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); vmathV3MakeXAxis( &result->col0 ); result->col1.vec128 = res1; result->col2.vec128 = res2; } static inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); result->col0.vec128 = res0; vmathV3MakeYAxis( &result->col1 ); result->col2.vec128 = res2; } static inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_y = _VECTORMATH_MASK_0x0F00; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); result->col0.vec128 = res0; result->col1.vec128 = res1; vmathV3MakeZAxis( &result->col2 ); } static inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ ) { VmathVector4 tmpV4_0; vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); vmathV4MakeFromV3Scalar( &tmpV4_0, radiansXYZ, 0.0f ); angles = tmpV4_0.vec128; sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F ); Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX ); Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_madd( Z0, Y1, zero ); result->col0.vec128 = vec_madd( Z0, Y0, zero ); result->col1.vec128 = vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ); result->col2.vec128 = vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ); } static inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec ) { vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); axis = unitVec->vec128; sincosf4( (vec_float4){radians,radians,radians,radians}, &s, &c ); xxxx = vec_splat( axis, 0 ); yyyy = vec_splat( axis, 1 ); zzzz = vec_splat( axis, 2 ); oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c ); axisS = vec_madd( axis, s, zero ); negAxisS = negatef4( axisS ); tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); tmp0 = vec_sel( tmp0, c, _VECTORMATH_MASK_0xF000 ); tmp1 = vec_sel( tmp1, c, _VECTORMATH_MASK_0x0F00 ); tmp2 = vec_sel( tmp2, c, _VECTORMATH_MASK_0x00F0 ); result->col0.vec128 = vec_madd( vec_madd( axis, xxxx, zero ), oneMinusC, tmp0 ); result->col1.vec128 = vec_madd( vec_madd( axis, yyyy, zero ), oneMinusC, tmp1 ); result->col2.vec128 = vec_madd( vec_madd( axis, zzzz, zero ), oneMinusC, tmp2 ); } static inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat ) { vmathM3MakeFromQ( result, unitQuat ); } static inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec ) { vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); result->col0.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0xF000 ); result->col1.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x0F00 ); result->col2.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x00F0 ); } static inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec ) { vmathV3ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) ); vmathV3ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) ); vmathV3ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) ); } static inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat ) { vmathV3MulPerElem( &result->col0, &mat->col0, scaleVec ); vmathV3MulPerElem( &result->col1, &mat->col1, scaleVec ); vmathV3MulPerElem( &result->col2, &mat->col2, scaleVec ); } static inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 ) { vmathV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathM3Print( const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2; vmathM3GetRow( &tmpV3_0, mat, 0 ); vmathV3Print( &tmpV3_0 ); vmathM3GetRow( &tmpV3_1, mat, 1 ); vmathV3Print( &tmpV3_1 ); vmathM3GetRow( &tmpV3_2, mat, 2 ); vmathV3Print( &tmpV3_2 ); } static inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name ) { printf("%s:\n", name); vmathM3Print( mat ); } #endif static inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( &result->col0, &mat->col0 ); vmathV4Copy( &result->col1, &mat->col1 ); vmathV4Copy( &result->col2, &mat->col2 ); vmathV4Copy( &result->col3, &mat->col3 ); } static inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar ) { vmathV4MakeFromScalar( &result->col0, scalar ); vmathV4MakeFromScalar( &result->col1, scalar ); vmathV4MakeFromScalar( &result->col2, scalar ); vmathV4MakeFromScalar( &result->col3, scalar ); } static inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat ) { vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, &mat->col3, 1.0f ); } static inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *_col0, const VmathVector4 *_col1, const VmathVector4 *_col2, const VmathVector4 *_col3 ) { vmathV4Copy( &result->col0, _col0 ); vmathV4Copy( &result->col1, _col1 ); vmathV4Copy( &result->col2, _col2 ); vmathV4Copy( &result->col3, _col3 ); } static inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec ) { vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ) { VmathMatrix3 mat; vmathM3MakeFromQ( &mat, unitQuat ); vmathV4MakeFromV3Scalar( &result->col0, &mat.col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat.col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat.col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *_col0 ) { vmathV4Copy( &result->col0, _col0 ); } static inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *_col1 ) { vmathV4Copy( &result->col1, _col1 ); } static inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *_col2 ) { vmathV4Copy( &result->col2, _col2 ); } static inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *_col3 ) { vmathV4Copy( &result->col3, _col3 ); } static inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec ) { vmathV4Copy( (&result->col0 + col), vec ); } static inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec ) { vmathV4SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) ); vmathV4SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) ); vmathV4SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) ); vmathV4SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) ); } static inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val ) { VmathVector4 tmpV3_0; vmathM4GetCol( &tmpV3_0, result, col ); vmathV4SetElem( &tmpV3_0, row, val ); vmathM4SetCol( result, col, &tmpV3_0 ); } static inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row ) { VmathVector4 tmpV4_0; vmathM4GetCol( &tmpV4_0, mat, col ); return vmathV4GetElem( &tmpV4_0, row ); } static inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col0 ); } static inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col1 ); } static inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col2 ); } static inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col3 ); } static inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col ) { vmathV4Copy( result, (&mat->col0 + col) ); } static inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row ) { vmathV4MakeFromElems( result, vmathV4GetElem( &mat->col0, row ), vmathV4GetElem( &mat->col1, row ), vmathV4GetElem( &mat->col2, row ), vmathV4GetElem( &mat->col3, row ) ); } static inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vec_float4 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; tmp0 = vec_mergeh( mat->col0.vec128, mat->col2.vec128 ); tmp1 = vec_mergeh( mat->col1.vec128, mat->col3.vec128 ); tmp2 = vec_mergel( mat->col0.vec128, mat->col2.vec128 ); tmp3 = vec_mergel( mat->col1.vec128, mat->col3.vec128 ); res0 = vec_mergeh( tmp0, tmp1 ); res1 = vec_mergel( tmp0, tmp1 ); res2 = vec_mergeh( tmp2, tmp3 ); res3 = vec_mergel( tmp2, tmp3 ); result->col0.vec128 = res0; result->col1.vec128 = res1; result->col2.vec128 = res2; result->col3.vec128 = res3; } static inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vector float in0, in1, in2, in3; vector float tmp0, tmp1, tmp2, tmp3; vector float cof0, cof1, cof2, cof3; vector float t0, t1, t2, t3; vector float t01, t02, t03, t12, t23; vector float t1r, t2r; vector float t01r, t02r, t03r, t12r, t23r; vector float t1r3, t1r3r; vector float det, det0, det1, det2, det3, invdet; vector float vzero = (vector float){0.0}; in0 = mat->col0.vec128; in1 = mat->col1.vec128; in2 = mat->col2.vec128; in3 = mat->col3.vec128; /* Perform transform of the input matrix of the form: * A B C D * E F G H * I J K L * M N O P * * The pseudo transpose of the input matrix is trans: * A E I M * J N B F * C G K O * L P D H */ tmp0 = vec_perm(in0, in1, _VECTORMATH_PERM_XAZC); /* A E C G */ tmp1 = vec_perm(in2, in3, _VECTORMATH_PERM_XAZC); /* I M K O */ tmp2 = vec_perm(in0, in1, _VECTORMATH_PERM_YBWD); /* B F D H */ tmp3 = vec_perm(in2, in3, _VECTORMATH_PERM_YBWD); /* J N L P */ t0 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_XYAB); /* A E I M */ t1 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_XYAB); /* J N B F */ t2 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_ZWCD); /* C G K O */ t3 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_ZWCD); /* L P D H */ /* Generate a cofactor matrix. The computed cofactors reside in * cof0, cof1, cof2, cof3. */ t23 = vec_madd(t2, t3, vzero); /* CL GP KD OH */ t23 = vec_perm(t23, t23, _VECTORMATH_PERM_YXWZ); /* GP CL OH KD */ cof0 = vec_nmsub(t1, t23, vzero); /* -(JGP NCL FOH BKD) */ cof1 = vec_nmsub(t0, t23, vzero); /* -(AGP ECL IOH MKD) */ t23r = vec_sld(t23, t23, 8); /* OH KD GP CL */ cof0 = vec_madd(t1, t23r, cof0); /* JOH NKD BGP FCL + cof0 */ cof1 = vec_madd(t0, t23r, cof1); /* AOH EKD IGP MCL + cof1 */ cof1 = vec_sld(cof1, cof1, 8); /* IGP MCL AOH EKD - IOH MKD AGP ECL */ t12 = vec_madd(t1, t2, vzero); /* JC NG BK FO */ t12 = vec_perm(t12, t12, _VECTORMATH_PERM_YXWZ); /* NG JC FO BK */ cof0 = vec_madd(t3, t12, cof0); /* LNG PJC DFO HBK + cof0 */ cof3 = vec_madd(t0, t12, vzero); /* ANG EJC IFO MBK */ t12r = vec_sld(t12, t12, 8); /* FO BK NG JC */ cof0 = vec_nmsub(t3, t12r, cof0); /* cof0 - LFO PBK DNG HJC */ cof3 = vec_nmsub(t0, t12r, cof3); /* cof3 - AFO EBK ING MJC */ cof3 = vec_sld(cof3, cof3, 8); /* ING MJC AFO EBK - IFO MBK ANG EJC */ t1r = vec_sld(t1, t1, 8); /* B F J N */ t2r = vec_sld(t2, t2, 8); /* K O C G */ t1r3 = vec_madd(t1r, t3, vzero); /* BL FP JD NH */ t1r3 = vec_perm(t1r3, t1r3, _VECTORMATH_PERM_YXWZ); /* FP BL NH JD */ cof0 = vec_madd(t2r, t1r3, cof0); /* KFP OBL CNH GJD + cof0 */ cof2 = vec_madd(t0, t1r3, vzero); /* AFP EBL INH MJD */ t1r3r = vec_sld(t1r3, t1r3, 8); /* NH JD FP BL */ cof0 = vec_nmsub(t2r, t1r3r, cof0); /* cof0 - KNH OJD CFP GBL */ cof2 = vec_nmsub(t0, t1r3r, cof2); /* cof2 - ANH EJD IFP MBL */ cof2 = vec_sld(cof2, cof2, 8); /* IFP MBL ANH EJD - INH MJD AFP EBL */ t01 = vec_madd(t0, t1, vzero); /* AJ EN IB MF */ t01 = vec_perm(t01, t01, _VECTORMATH_PERM_YXWZ); /* EN AJ MF IB */ cof2 = vec_nmsub(t3, t01, cof2); /* cof2 - LEN PAJ DMF HIB */ cof3 = vec_madd(t2r, t01, cof3); /* KEN OAJ CMF GIB + cof3 */ t01r = vec_sld(t01, t01, 8); /* MF IB EN AJ */ cof2 = vec_madd(t3, t01r, cof2); /* LMF PIB DEN HAJ + cof2 */ cof3 = vec_nmsub(t2r, t01r, cof3); /* cof3 - KMF OIB CEN GAJ */ t03 = vec_madd(t0, t3, vzero); /* AL EP ID MH */ t03 = vec_perm(t03, t03, _VECTORMATH_PERM_YXWZ); /* EP AL MH ID */ cof1 = vec_nmsub(t2r, t03, cof1); /* cof1 - KEP OAL CMH GID */ cof2 = vec_madd(t1, t03, cof2); /* JEP NAL BMH FID + cof2 */ t03r = vec_sld(t03, t03, 8); /* MH ID EP AL */ cof1 = vec_madd(t2r, t03r, cof1); /* KMH OID CEP GAL + cof1 */ cof2 = vec_nmsub(t1, t03r, cof2); /* cof2 - JMH NID BEP FAL */ t02 = vec_madd(t0, t2r, vzero); /* AK EO IC MG */ t02 = vec_perm(t02, t02, _VECTORMATH_PERM_YXWZ); /* E0 AK MG IC */ cof1 = vec_madd(t3, t02, cof1); /* LEO PAK DMG HIC + cof1 */ cof3 = vec_nmsub(t1, t02, cof3); /* cof3 - JEO NAK BMG FIC */ t02r = vec_sld(t02, t02, 8); /* MG IC EO AK */ cof1 = vec_nmsub(t3, t02r, cof1); /* cof1 - LMG PIC DEO HAK */ cof3 = vec_madd(t1, t02r, cof3); /* JMG NIC BEO FAK + cof3 */ /* Compute the determinant of the matrix * * det = sum_across(t0 * cof0); * * We perform a sum across the entire vector so that * we don't have to splat the result when multiplying the * cofactors by the inverse of the determinant. */ det = vec_madd(t0, cof0, vzero); det0 = vec_splat(det, 0); det1 = vec_splat(det, 1); det2 = vec_splat(det, 2); det3 = vec_splat(det, 3); det = vec_add(det0, det1); det2 = vec_add(det2, det3); det = vec_add(det, det2); /* Compute the reciprocal of the determinant. */ invdet = recipf4(det); /* Multiply the cofactors by the reciprocal of the determinant. */ result->col0.vec128 = vec_madd(cof0, invdet, vzero); result->col1.vec128 = vec_madd(cof1, invdet, vzero); result->col2.vec128 = vec_madd(cof2, invdet, vzero); result->col3.vec128 = vec_madd(cof3, invdet, vzero); } static inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { VmathTransform3 affineMat, tmpT3_0; VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathT3SetCol0( &affineMat, &tmpV3_0 ); vmathV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathT3SetCol1( &affineMat, &tmpV3_1 ); vmathV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathT3SetCol2( &affineMat, &tmpV3_2 ); vmathV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathT3SetCol3( &affineMat, &tmpV3_3 ); vmathT3Inverse( &tmpT3_0, &affineMat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { VmathTransform3 affineMat, tmpT3_0; VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathT3SetCol0( &affineMat, &tmpV3_0 ); vmathV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathT3SetCol1( &affineMat, &tmpV3_1 ); vmathV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathT3SetCol2( &affineMat, &tmpV3_2 ); vmathV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathT3SetCol3( &affineMat, &tmpV3_3 ); vmathT3OrthoInverse( &tmpT3_0, &affineMat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline float vmathM4Determinant( const VmathMatrix4 *mat ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vector float in0, in1, in2, in3; vector float tmp0, tmp1, tmp2, tmp3; vector float cof0; vector float t0, t1, t2, t3; vector float t12, t23; vector float t1r, t2r; vector float t12r, t23r; vector float t1r3, t1r3r; vector float vzero = (vector float){0.0}; union { vec_float4 v; float s[4]; } tmp; in0 = mat->col0.vec128; in1 = mat->col1.vec128; in2 = mat->col2.vec128; in3 = mat->col3.vec128; /* Perform transform of the input matrix of the form: * A B C D * E F G H * I J K L * M N O P * * The pseudo transpose of the input matrix is trans: * A E I M * J N B F * C G K O * L P D H */ tmp0 = vec_perm(in0, in1, _VECTORMATH_PERM_XAZC); /* A E C G */ tmp1 = vec_perm(in2, in3, _VECTORMATH_PERM_XAZC); /* I M K O */ tmp2 = vec_perm(in0, in1, _VECTORMATH_PERM_YBWD); /* B F D H */ tmp3 = vec_perm(in2, in3, _VECTORMATH_PERM_YBWD); /* J N L P */ t0 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_XYAB); /* A E I M */ t1 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_XYAB); /* J N B F */ t2 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_ZWCD); /* C G K O */ t3 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_ZWCD); /* L P D H */ /* Generate a cofactor matrix. The computed cofactors reside in * cof0, cof1, cof2, cof3. */ t23 = vec_madd(t2, t3, vzero); /* CL GP KD OH */ t23 = vec_perm(t23, t23, _VECTORMATH_PERM_YXWZ); /* GP CL OH KD */ cof0 = vec_nmsub(t1, t23, vzero); /* -(JGP NCL FOH BKD) */ t23r = vec_sld(t23, t23, 8); /* OH KD GP CL */ cof0 = vec_madd(t1, t23r, cof0); /* JOH NKD BGP FCL + cof0 */ t12 = vec_madd(t1, t2, vzero); /* JC NG BK FO */ t12 = vec_perm(t12, t12, _VECTORMATH_PERM_YXWZ); /* NG JC FO BK */ cof0 = vec_madd(t3, t12, cof0); /* LNG PJC DFO HBK + cof0 */ t12r = vec_sld(t12, t12, 8); /* FO BK NG JC */ cof0 = vec_nmsub(t3, t12r, cof0); /* cof0 - LFO PBK DNG HJC */ t1r = vec_sld(t1, t1, 8); /* B F J N */ t2r = vec_sld(t2, t2, 8); /* K O C G */ t1r3 = vec_madd(t1r, t3, vzero); /* BL FP JD NH */ t1r3 = vec_perm(t1r3, t1r3, _VECTORMATH_PERM_YXWZ); /* FP BL NH JD */ cof0 = vec_madd(t2r, t1r3, cof0); /* KFP OBL CNH GJD + cof0 */ t1r3r = vec_sld(t1r3, t1r3, 8); /* NH JD FP BL */ cof0 = vec_nmsub(t2r, t1r3r, cof0); /* cof0 - KNH OJD CFP GBL */ tmp.v = _vmathVfDot4(t0,cof0); return tmp.s[0]; } static inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4Add( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4Add( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4Sub( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4Sub( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4Neg( &result->col0, &mat->col0 ); vmathV4Neg( &result->col1, &mat->col1 ); vmathV4Neg( &result->col2, &mat->col2 ); vmathV4Neg( &result->col3, &mat->col3 ); } static inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4AbsPerElem( &result->col0, &mat->col0 ); vmathV4AbsPerElem( &result->col1, &mat->col1 ); vmathV4AbsPerElem( &result->col2, &mat->col2 ); vmathV4AbsPerElem( &result->col3, &mat->col3 ); } static inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar ) { vmathV4ScalarMul( &result->col0, &mat->col0, scalar ); vmathV4ScalarMul( &result->col1, &mat->col1, scalar ); vmathV4ScalarMul( &result->col2, &mat->col2, scalar ); vmathV4ScalarMul( &result->col3, &mat->col3, scalar ); } static inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec ) { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz, wwww; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); xxxx = vec_splat( vec->vec128, 0 ); yyyy = vec_splat( vec->vec128, 1 ); zzzz = vec_splat( vec->vec128, 2 ); wwww = vec_splat( vec->vec128, 3 ); tmp0 = vec_madd( mat->col0.vec128, xxxx, zero ); tmp1 = vec_madd( mat->col1.vec128, yyyy, zero ); tmp0 = vec_madd( mat->col2.vec128, zzzz, tmp0 ); tmp1 = vec_madd( mat->col3.vec128, wwww, tmp1 ); res = vec_add( tmp0, tmp1 ); result->vec128 = res; } static inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec ) { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; xxxx = vec_splat( vec->vec128, 0 ); yyyy = vec_splat( vec->vec128, 1 ); zzzz = vec_splat( vec->vec128, 2 ); res = vec_madd( mat->col0.vec128, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); res = vec_madd( mat->col1.vec128, yyyy, res ); res = vec_madd( mat->col2.vec128, zzzz, res ); result->vec128 = res; } static inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt ) { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); xxxx = vec_splat( pnt->vec128, 0 ); yyyy = vec_splat( pnt->vec128, 1 ); zzzz = vec_splat( pnt->vec128, 2 ); tmp0 = vec_madd( mat->col0.vec128, xxxx, zero ); tmp1 = vec_madd( mat->col1.vec128, yyyy, zero ); tmp0 = vec_madd( mat->col2.vec128, zzzz, tmp0 ); tmp1 = vec_add( mat->col3.vec128, tmp1 ); res = vec_add( tmp0, tmp1 ); result->vec128 = res; } static inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { VmathMatrix4 tmpResult; vmathM4MulV4( &tmpResult.col0, mat0, &mat1->col0 ); vmathM4MulV4( &tmpResult.col1, mat0, &mat1->col1 ); vmathM4MulV4( &tmpResult.col2, mat0, &mat1->col2 ); vmathM4MulV4( &tmpResult.col3, mat0, &mat1->col3 ); vmathM4Copy( result, &tmpResult ); } static inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm1 ) { VmathMatrix4 tmpResult; VmathPoint3 tmpP3_0; vmathM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 ); vmathM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 ); vmathM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 ); vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathM4MulP3( &tmpResult.col3, mat, &tmpP3_0 ); vmathM4Copy( result, &tmpResult ); } static inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4MakeIdentity( VmathMatrix4 *result ) { vmathV4MakeXAxis( &result->col0 ); vmathV4MakeYAxis( &result->col1 ); vmathV4MakeZAxis( &result->col2 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 ) { vmathV4SetXYZ( &result->col0, &mat3->col0 ); vmathV4SetXYZ( &result->col1, &mat3->col1 ); vmathV4SetXYZ( &result->col2, &mat3->col2 ); } static inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat ) { vmathV4GetXYZ( &result->col0, &mat->col0 ); vmathV4GetXYZ( &result->col1, &mat->col1 ); vmathV4GetXYZ( &result->col2, &mat->col2 ); } static inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ) { vmathV4SetXYZ( &result->col3, translateVec ); } static inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat ) { vmathV4GetXYZ( result, &mat->col3 ); } static inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = _VECTORMATH_MASK_0x0F00; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); vmathV4MakeXAxis( &result->col0 ); result->col1.vec128 = res1; result->col2.vec128 = res2; vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); result->col0.vec128 = res0; vmathV4MakeYAxis( &result->col1 ); result->col2.vec128 = res2; vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_y = _VECTORMATH_MASK_0x0F00; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); result->col0.vec128 = res0; result->col1.vec128 = res1; vmathV4MakeZAxis( &result->col2 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ ) { VmathVector4 tmpV4_0; vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); vmathV4MakeFromV3Scalar( &tmpV4_0, radiansXYZ, 0.0f ); angles = tmpV4_0.vec128; sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F ); Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX ); Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_madd( Z0, Y1, zero ); result->col0.vec128 = vec_madd( Z0, Y0, zero ); result->col1.vec128 = vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ); result->col2.vec128 = vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec ) { vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2, zeroW; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); axis = unitVec->vec128; sincosf4( (vec_float4){radians,radians,radians,radians}, &s, &c ); xxxx = vec_splat( axis, 0 ); yyyy = vec_splat( axis, 1 ); zzzz = vec_splat( axis, 2 ); oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c ); axisS = vec_madd( axis, s, zero ); negAxisS = negatef4( axisS ); tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); tmp0 = vec_sel( tmp0, c, _VECTORMATH_MASK_0xF000 ); tmp1 = vec_sel( tmp1, c, _VECTORMATH_MASK_0x0F00 ); tmp2 = vec_sel( tmp2, c, _VECTORMATH_MASK_0x00F0 ); zeroW = (vec_float4)_VECTORMATH_MASK_0x000F; axis = vec_andc( axis, zeroW ); tmp0 = vec_andc( tmp0, zeroW ); tmp1 = vec_andc( tmp1, zeroW ); tmp2 = vec_andc( tmp2, zeroW ); result->col0.vec128 = vec_madd( vec_madd( axis, xxxx, zero ), oneMinusC, tmp0 ); result->col1.vec128 = vec_madd( vec_madd( axis, yyyy, zero ), oneMinusC, tmp1 ); result->col2.vec128 = vec_madd( vec_madd( axis, zzzz, zero ), oneMinusC, tmp2 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat ) { VmathTransform3 tmpT3_0; vmathT3MakeRotationQ( &tmpT3_0, unitQuat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec ) { vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); result->col0.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0xF000 ); result->col1.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x0F00 ); result->col2.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x00F0 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec ) { vmathV4ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) ); vmathV4ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) ); vmathV4ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) ); vmathV4Copy( &result->col3, &mat->col3 ); } static inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat ) { VmathVector4 scale4; vmathV4MakeFromV3Scalar( &scale4, scaleVec, 1.0f ); vmathV4MulPerElem( &result->col0, &mat->col0, &scale4 ); vmathV4MulPerElem( &result->col1, &mat->col1, &scale4 ); vmathV4MulPerElem( &result->col2, &mat->col2, &scale4 ); vmathV4MulPerElem( &result->col3, &mat->col3, &scale4 ); } static inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ) { vmathV4MakeXAxis( &result->col0 ); vmathV4MakeYAxis( &result->col1 ); vmathV4MakeZAxis( &result->col2 ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec ) { VmathMatrix4 m4EyeFrame; VmathVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1; VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; vmathV3Normalize( &v3Y, upVec ); vmathP3Sub( &tmpV3_0, eyePos, lookAtPos ); vmathV3Normalize( &v3Z, &tmpV3_0 ); vmathV3Cross( &tmpV3_1, &v3Y, &v3Z ); vmathV3Normalize( &v3X, &tmpV3_1 ); vmathV3Cross( &v3Y, &v3Z, &v3X ); vmathV4MakeFromV3( &tmpV4_0, &v3X ); vmathV4MakeFromV3( &tmpV4_1, &v3Y ); vmathV4MakeFromV3( &tmpV4_2, &v3Z ); vmathV4MakeFromP3( &tmpV4_3, eyePos ); vmathM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 ); vmathM4OrthoInverse( result, &m4EyeFrame ); } static inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar ) { float f, rangeInv; vec_float4 zero, col0, col1, col2, col3; union { vec_float4 v; float s[4]; } tmp; f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f ); rangeInv = 1.0f / ( zNear - zFar ); zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); tmp.v = zero; tmp.s[0] = f / aspect; col0 = tmp.v; tmp.v = zero; tmp.s[1] = f; col1 = tmp.v; tmp.v = zero; tmp.s[2] = ( zNear + zFar ) * rangeInv; tmp.s[3] = -1.0f; col2 = tmp.v; tmp.v = zero; tmp.s[2] = zNear * zFar * rangeInv * 2.0f; col3 = tmp.v; result->col0.vec128 = col0; result->col1.vec128 = col1; result->col2.vec128 = col2; result->col3.vec128 = col3; } static inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 lbf, rtn; vec_float4 diff, sum, inv_diff; vec_float4 diagonal, column, near2; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); union { vec_float4 v; float s[4]; } l, f, r, n, b, t; l.s[0] = left; f.s[0] = zFar; r.s[0] = right; n.s[0] = zNear; b.s[0] = bottom; t.s[0] = top; lbf = vec_mergeh( l.v, f.v ); rtn = vec_mergeh( r.v, n.v ); lbf = vec_mergeh( lbf, b.v ); rtn = vec_mergeh( rtn, t.v ); diff = vec_sub( rtn, lbf ); sum = vec_add( rtn, lbf ); inv_diff = recipf4( diff ); near2 = vec_splat( n.v, 0 ); near2 = vec_add( near2, near2 ); diagonal = vec_madd( near2, inv_diff, zero ); column = vec_madd( sum, inv_diff, zero ); result->col0.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0xF000 ); result->col1.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0x0F00 ); result->col2.vec128 = vec_sel( column, ((vec_float4){-1.0f,-1.0f,-1.0f,-1.0f}), _VECTORMATH_MASK_0x000F ); result->col3.vec128 = vec_sel( zero, vec_madd( diagonal, vec_splat( f.v, 0 ), zero ), _VECTORMATH_MASK_0x00F0 ); } static inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 lbf, rtn; vec_float4 diff, sum, inv_diff, neg_inv_diff; vec_float4 diagonal, column; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); union { vec_float4 v; float s[4]; } l, f, r, n, b, t; l.s[0] = left; f.s[0] = zFar; r.s[0] = right; n.s[0] = zNear; b.s[0] = bottom; t.s[0] = top; lbf = vec_mergeh( l.v, f.v ); rtn = vec_mergeh( r.v, n.v ); lbf = vec_mergeh( lbf, b.v ); rtn = vec_mergeh( rtn, t.v ); diff = vec_sub( rtn, lbf ); sum = vec_add( rtn, lbf ); inv_diff = recipf4( diff ); neg_inv_diff = negatef4( inv_diff ); diagonal = vec_add( inv_diff, inv_diff ); column = vec_madd( sum, vec_sel( neg_inv_diff, inv_diff, _VECTORMATH_MASK_0x00F0 ), zero ); result->col0.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0xF000 ); result->col1.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0x0F00 ); result->col2.vec128 = vec_sel( zero, diagonal, _VECTORMATH_MASK_0x00F0 ); result->col3.vec128 = vec_sel( column, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), _VECTORMATH_MASK_0x000F ); } static inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 ) { vmathV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); vmathV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathM4Print( const VmathMatrix4 *mat ) { VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; vmathM4GetRow( &tmpV4_0, mat, 0 ); vmathV4Print( &tmpV4_0 ); vmathM4GetRow( &tmpV4_1, mat, 1 ); vmathV4Print( &tmpV4_1 ); vmathM4GetRow( &tmpV4_2, mat, 2 ); vmathV4Print( &tmpV4_2 ); vmathM4GetRow( &tmpV4_3, mat, 3 ); vmathV4Print( &tmpV4_3 ); } static inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name ) { printf("%s:\n", name); vmathM4Print( mat ); } #endif static inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( &result->col0, &tfrm->col0 ); vmathV3Copy( &result->col1, &tfrm->col1 ); vmathV3Copy( &result->col2, &tfrm->col2 ); vmathV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar ) { vmathV3MakeFromScalar( &result->col0, scalar ); vmathV3MakeFromScalar( &result->col1, scalar ); vmathV3MakeFromScalar( &result->col2, scalar ); vmathV3MakeFromScalar( &result->col3, scalar ); } static inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2, const VmathVector3 *_col3 ) { vmathV3Copy( &result->col0, _col0 ); vmathV3Copy( &result->col1, _col1 ); vmathV3Copy( &result->col2, _col2 ); vmathV3Copy( &result->col3, _col3 ); } static inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec ) { vmathT3SetUpper3x3( result, tfrm ); vmathT3SetTranslation( result, translateVec ); } static inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ) { VmathMatrix3 tmpM3_0; vmathM3MakeFromQ( &tmpM3_0, unitQuat ); vmathT3SetUpper3x3( result, &tmpM3_0 ); vmathT3SetTranslation( result, translateVec ); } static inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *_col0 ) { vmathV3Copy( &result->col0, _col0 ); } static inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *_col1 ) { vmathV3Copy( &result->col1, _col1 ); } static inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col2, _col2 ); } static inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *_col3 ) { vmathV3Copy( &result->col3, _col3 ); } static inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec ) { vmathV3Copy( (&result->col0 + col), vec ); } static inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec ) { vmathV3SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) ); vmathV3SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) ); vmathV3SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) ); vmathV3SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) ); } static inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val ) { VmathVector3 tmpV3_0; vmathT3GetCol( &tmpV3_0, result, col ); vmathV3SetElem( &tmpV3_0, row, val ); vmathT3SetCol( result, col, &tmpV3_0 ); } static inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row ) { VmathVector3 tmpV3_0; vmathT3GetCol( &tmpV3_0, tfrm, col ); return vmathV3GetElem( &tmpV3_0, row ); } static inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col0 ); } static inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col1 ); } static inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col2 ); } static inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col3 ); } static inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col ) { vmathV3Copy( result, (&tfrm->col0 + col) ); } static inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row ) { vmathV4MakeFromElems( result, vmathV3GetElem( &tfrm->col0, row ), vmathV3GetElem( &tfrm->col1, row ), vmathV3GetElem( &tfrm->col2, row ), vmathV3GetElem( &tfrm->col3, row ) ); } static inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vec_float4 inv0, inv1, inv2, inv3; vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; vec_float4 xxxx, yyyy, zzzz; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); tmp2 = _vmathVfCross( tfrm->col0.vec128, tfrm->col1.vec128 ); tmp0 = _vmathVfCross( tfrm->col1.vec128, tfrm->col2.vec128 ); tmp1 = _vmathVfCross( tfrm->col2.vec128, tfrm->col0.vec128 ); inv3 = negatef4( tfrm->col3.vec128 ); dot = _vmathVfDot3( tmp2, tfrm->col2.vec128 ); dot = vec_splat( dot, 0 ); invdet = recipf4( dot ); tmp3 = vec_mergeh( tmp0, tmp2 ); tmp4 = vec_mergel( tmp0, tmp2 ); inv0 = vec_mergeh( tmp3, tmp1 ); xxxx = vec_splat( inv3, 0 ); inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); yyyy = vec_splat( inv3, 1 ); zzzz = vec_splat( inv3, 2 ); inv3 = vec_madd( inv0, xxxx, zero ); inv3 = vec_madd( inv1, yyyy, inv3 ); inv3 = vec_madd( inv2, zzzz, inv3 ); inv0 = vec_madd( inv0, invdet, zero ); inv1 = vec_madd( inv1, invdet, zero ); inv2 = vec_madd( inv2, invdet, zero ); inv3 = vec_madd( inv3, invdet, zero ); result->col0.vec128 = inv0; result->col1.vec128 = inv1; result->col2.vec128 = inv2; result->col3.vec128 = inv3; } static inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vec_float4 inv0, inv1, inv2, inv3; vec_float4 tmp0, tmp1; vec_float4 xxxx, yyyy, zzzz; tmp0 = vec_mergeh( tfrm->col0.vec128, tfrm->col2.vec128 ); tmp1 = vec_mergel( tfrm->col0.vec128, tfrm->col2.vec128 ); inv3 = negatef4( tfrm->col3.vec128 ); inv0 = vec_mergeh( tmp0, tfrm->col1.vec128 ); xxxx = vec_splat( inv3, 0 ); inv1 = vec_perm( tmp0, tfrm->col1.vec128, _VECTORMATH_PERM_ZBWX ); inv2 = vec_perm( tmp1, tfrm->col1.vec128, _VECTORMATH_PERM_XCYX ); yyyy = vec_splat( inv3, 1 ); zzzz = vec_splat( inv3, 2 ); inv3 = vec_madd( inv0, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); inv3 = vec_madd( inv1, yyyy, inv3 ); inv3 = vec_madd( inv2, zzzz, inv3 ); result->col0.vec128 = inv0; result->col1.vec128 = inv1; result->col2.vec128 = inv2; result->col3.vec128 = inv3; } static inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vmathV3AbsPerElem( &result->col0, &tfrm->col0 ); vmathV3AbsPerElem( &result->col1, &tfrm->col1 ); vmathV3AbsPerElem( &result->col2, &tfrm->col2 ); vmathV3AbsPerElem( &result->col3, &tfrm->col3 ); } static inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec ) { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; xxxx = vec_splat( vec->vec128, 0 ); yyyy = vec_splat( vec->vec128, 1 ); zzzz = vec_splat( vec->vec128, 2 ); res = vec_madd( tfrm->col0.vec128, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); res = vec_madd( tfrm->col1.vec128, yyyy, res ); res = vec_madd( tfrm->col2.vec128, zzzz, res ); result->vec128 = res; } static inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt ) { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); xxxx = vec_splat( pnt->vec128, 0 ); yyyy = vec_splat( pnt->vec128, 1 ); zzzz = vec_splat( pnt->vec128, 2 ); tmp0 = vec_madd( tfrm->col0.vec128, xxxx, zero ); tmp1 = vec_madd( tfrm->col1.vec128, yyyy, zero ); tmp0 = vec_madd( tfrm->col2.vec128, zzzz, tmp0 ); tmp1 = vec_add( tfrm->col3.vec128, tmp1 ); res = vec_add( tmp0, tmp1 ); result->vec128 = res; } static inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ) { VmathTransform3 tmpResult; VmathPoint3 tmpP3_0, tmpP3_1; vmathT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 ); vmathT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 ); vmathT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 ); vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 ); vmathV3MakeFromP3( &tmpResult.col3, &tmpP3_1 ); vmathT3Copy( result, &tmpResult ); } static inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ) { vmathV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 ); vmathV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 ); vmathV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 ); vmathV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 ); } static inline void vmathT3MakeIdentity( VmathTransform3 *result ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *tfrm ) { vmathV3Copy( &result->col0, &tfrm->col0 ); vmathV3Copy( &result->col1, &tfrm->col1 ); vmathV3Copy( &result->col2, &tfrm->col2 ); } static inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm ) { vmathM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 ); } static inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ) { vmathV3Copy( &result->col3, translateVec ); } static inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col3 ); } static inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = _VECTORMATH_MASK_0x0F00; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); vmathV3MakeXAxis( &result->col0 ); result->col1.vec128 = res1; result->col2.vec128 = res2; vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); result->col0.vec128 = res0; vmathV3MakeYAxis( &result->col1 ); result->col2.vec128 = res2; vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_y = _VECTORMATH_MASK_0x0F00; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( _vmathVfSplatScalar(radians), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); result->col0.vec128 = res0; result->col1.vec128 = res1; vmathV3MakeZAxis( &result->col2 ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ ) { VmathVector4 tmpV4_0; vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); vmathV4MakeFromV3Scalar( &tmpV4_0, radiansXYZ, 0.0f ); angles = tmpV4_0.vec128; sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F ); Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX ); Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_madd( Z0, Y1, zero ); result->col0.vec128 = vec_madd( Z0, Y0, zero ); result->col1.vec128 = vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ); result->col2.vec128 = vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec ) { VmathMatrix3 tmpM3_0; VmathVector3 tmpV3_0; vmathM3MakeRotationAxis( &tmpM3_0, radians, unitVec ); vmathV3MakeFromScalar( &tmpV3_0, 0.0f ); vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat ) { VmathMatrix3 tmpM3_0; VmathVector3 tmpV3_0; vmathM3MakeFromQ( &tmpM3_0, unitQuat ); vmathV3MakeFromScalar( &tmpV3_0, 0.0f ); vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec ) { vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); result->col0.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0xF000 ); result->col1.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x0F00 ); result->col2.vec128 = vec_sel( zero, scaleVec->vec128, _VECTORMATH_MASK_0x00F0 ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec ) { vmathV3ScalarMul( &result->col0, &tfrm->col0, vmathV3GetX( scaleVec ) ); vmathV3ScalarMul( &result->col1, &tfrm->col1, vmathV3GetY( scaleVec ) ); vmathV3ScalarMul( &result->col2, &tfrm->col2, vmathV3GetZ( scaleVec ) ); vmathV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm ) { vmathV3MulPerElem( &result->col0, &tfrm->col0, scaleVec ); vmathV3MulPerElem( &result->col1, &tfrm->col1, scaleVec ); vmathV3MulPerElem( &result->col2, &tfrm->col2, scaleVec ); vmathV3MulPerElem( &result->col3, &tfrm->col3, scaleVec ); } static inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); vmathV3Copy( &result->col3, translateVec ); } static inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 ) { vmathV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 ); vmathV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 ); vmathV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 ); vmathV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathT3Print( const VmathTransform3 *tfrm ) { VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2; vmathT3GetRow( &tmpV4_0, tfrm, 0 ); vmathV4Print( &tmpV4_0 ); vmathT3GetRow( &tmpV4_1, tfrm, 1 ); vmathV4Print( &tmpV4_1 ); vmathT3GetRow( &tmpV4_2, tfrm, 2 ); vmathV4Print( &tmpV4_2 ); } static inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name ) { printf("%s:\n", name); vmathT3Print( tfrm ); } #endif static inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *tfrm ) { vec_float4 res; vec_float4 col0, col1, col2; vec_float4 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; vec_float4 zy_xz_yx, yz_zx_xy, sum, diff; vec_float4 radicand, invSqrt, scale; vec_float4 res0, res1, res2, res3; vec_float4 xx, yy, zz; vec_uint4 select_x = _VECTORMATH_MASK_0xF000; vec_uint4 select_y = _VECTORMATH_MASK_0x0F00; vec_uint4 select_z = _VECTORMATH_MASK_0x00F0; vec_uint4 select_w = _VECTORMATH_MASK_0x000F; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); col0 = tfrm->col0.vec128; col1 = tfrm->col1.vec128; col2 = tfrm->col2.vec128; /* four cases: */ /* trace > 0 */ /* else */ /* xx largest diagonal element */ /* yy largest diagonal element */ /* zz largest diagonal element */ /* compute quaternion for each case */ xx_yy = vec_sel( col0, col1, select_y ); xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX ); yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY ); zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC ); diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); invSqrt = rsqrtf4( radicand ); zy_xz_yx = vec_sel( col0, col1, select_z ); zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX ); yz_zx_xy = vec_sel( col0, col1, select_x ); yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX ); sum = vec_add( zy_xz_yx, yz_zx_xy ); diff = vec_sub( zy_xz_yx, yz_zx_xy ); scale = vec_madd( invSqrt, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), zero ); res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA ); res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB ); res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC ); res3 = diff; res0 = vec_sel( res0, radicand, select_x ); res1 = vec_sel( res1, radicand, select_y ); res2 = vec_sel( res2, radicand, select_z ); res3 = vec_sel( res3, radicand, select_w ); res0 = vec_madd( res0, vec_splat( scale, 0 ), zero ); res1 = vec_madd( res1, vec_splat( scale, 1 ), zero ); res2 = vec_madd( res2, vec_splat( scale, 2 ), zero ); res3 = vec_madd( res3, vec_splat( scale, 3 ), zero ); /* determine case and select answer */ xx = vec_splat( col0, 0 ); yy = vec_splat( col1, 1 ); zz = vec_splat( col2, 2 ); res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) ); res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) ); res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), zero ) ); result->vec128 = res; } static inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *tfrm0, const VmathVector3 *tfrm1 ) { vmathV3ScalarMul( &result->col0, tfrm0, vmathV3GetX( tfrm1 ) ); vmathV3ScalarMul( &result->col1, tfrm0, vmathV3GetY( tfrm1 ) ); vmathV3ScalarMul( &result->col2, tfrm0, vmathV3GetZ( tfrm1 ) ); } static inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *tfrm0, const VmathVector4 *tfrm1 ) { vmathV4ScalarMul( &result->col0, tfrm0, vmathV4GetX( tfrm1 ) ); vmathV4ScalarMul( &result->col1, tfrm0, vmathV4GetY( tfrm1 ) ); vmathV4ScalarMul( &result->col2, tfrm0, vmathV4GetZ( tfrm1 ) ); vmathV4ScalarMul( &result->col3, tfrm0, vmathV4GetW( tfrm1 ) ); } static inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ) { vec_float4 tmp0, tmp1, mcol0, mcol1, mcol2, res; vec_float4 xxxx, yyyy, zzzz; tmp0 = vec_mergeh( mat->col0.vec128, mat->col2.vec128 ); tmp1 = vec_mergel( mat->col0.vec128, mat->col2.vec128 ); xxxx = vec_splat( vec->vec128, 0 ); mcol0 = vec_mergeh( tmp0, mat->col1.vec128 ); mcol1 = vec_perm( tmp0, mat->col1.vec128, _VECTORMATH_PERM_ZBWX ); mcol2 = vec_perm( tmp1, mat->col1.vec128, _VECTORMATH_PERM_XCYX ); yyyy = vec_splat( vec->vec128, 1 ); res = vec_madd( mcol0, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); zzzz = vec_splat( vec->vec128, 2 ); res = vec_madd( mcol1, yyyy, res ); res = vec_madd( mcol2, zzzz, res ); result->vec128 = res; } static inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec ) { vec_float4 neg, res0, res1, res2; neg = negatef4( vec->vec128 ); res0 = vec_perm( vec->vec128, neg, _VECTORMATH_PERM_XZBX ); res1 = vec_perm( vec->vec128, neg, _VECTORMATH_PERM_CXXX ); res2 = vec_perm( vec->vec128, neg, _VECTORMATH_PERM_YAXX ); res0 = vec_andc( res0, (vec_float4)_VECTORMATH_MASK_0xF000 ); res1 = vec_andc( res1, (vec_float4)_VECTORMATH_MASK_0x0F00 ); res2 = vec_andc( res2, (vec_float4)_VECTORMATH_MASK_0x00F0 ); result->col0.vec128 = res0; result->col1.vec128 = res1; result->col2.vec128 = res2; } static inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2; vmathV3Cross( &tmpV3_0, vec, &mat->col0 ); vmathV3Cross( &tmpV3_1, vec, &mat->col1 ); vmathV3Cross( &tmpV3_2, vec, &mat->col2 ); vmathM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 ); } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/mat_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_V_C_H #define _VECTORMATH_MAT_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for shuffles, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z }) #define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y }) #define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar ) { VmathMatrix3 result; vmathM3MakeFromScalar(&result, scalar); return result; } static inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat ) { VmathMatrix3 result; vmathM3MakeFromQ(&result, &unitQuat); return result; } static inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2 ) { VmathMatrix3 result; vmathM3MakeFromCols(&result, &_col0, &_col1, &_col2); return result; } static inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 _col0 ) { vmathM3SetCol0(result, &_col0); } static inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 _col1 ) { vmathM3SetCol1(result, &_col1); } static inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 _col2 ) { vmathM3SetCol2(result, &_col2); } static inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec ) { vmathM3SetCol(result, col, &vec); } static inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec ) { vmathM3SetRow(result, row, &vec); } static inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val ) { vmathM3SetElem(result, col, row, val); } static inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row ) { return vmathM3GetElem(&mat, col, row); } static inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol0(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol1(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol2(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col ) { VmathVector3 result; vmathM3GetCol(&result, &mat, col); return result; } static inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row ) { VmathVector3 result; vmathM3GetRow(&result, &mat, row); return result; } static inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Transpose(&result, &mat); return result; } static inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Inverse(&result, &mat); return result; } static inline float vmathM3Determinant_V( VmathMatrix3 mat ) { return vmathM3Determinant(&mat); } static inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Add(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Sub(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Neg(&result, &mat); return result; } static inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3AbsPerElem(&result, &mat); return result; } static inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar ) { VmathMatrix3 result; vmathM3ScalarMul(&result, &mat, scalar); return result; } static inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec ) { VmathVector3 result; vmathM3MulV3(&result, &mat, &vec); return result; } static inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Mul(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3MakeIdentity_V( ) { VmathMatrix3 result; vmathM3MakeIdentity(&result); return result; } static inline VmathMatrix3 vmathM3MakeRotationX_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationX(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationY_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationY(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationZ(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathMatrix3 result; vmathM3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathMatrix3 result; vmathM3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat ) { VmathMatrix3 result; vmathM3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec ) { VmathMatrix3 result; vmathM3MakeScale(&result, &scaleVec); return result; } static inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec ) { VmathMatrix3 result; vmathM3AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 ) { VmathMatrix3 result; vmathM3Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathM3Print_V( VmathMatrix3 mat ) { vmathM3Print(&mat); } static inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name ) { vmathM3Prints(&mat, name); } #endif static inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar ) { VmathMatrix4 result; vmathM4MakeFromScalar(&result, scalar); return result; } static inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat ) { VmathMatrix4 result; vmathM4MakeFromT3(&result, &mat); return result; } static inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 _col0, VmathVector4 _col1, VmathVector4 _col2, VmathVector4 _col3 ) { VmathMatrix4 result; vmathM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeFromM3V3(&result, &mat, &translateVec); return result; } static inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 _col0 ) { vmathM4SetCol0(result, &_col0); } static inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 _col1 ) { vmathM4SetCol1(result, &_col1); } static inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 _col2 ) { vmathM4SetCol2(result, &_col2); } static inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 _col3 ) { vmathM4SetCol3(result, &_col3); } static inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec ) { vmathM4SetCol(result, col, &vec); } static inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec ) { vmathM4SetRow(result, row, &vec); } static inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val ) { vmathM4SetElem(result, col, row, val); } static inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row ) { return vmathM4GetElem(&mat, col, row); } static inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol0(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol1(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol2(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol3(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col ) { VmathVector4 result; vmathM4GetCol(&result, &mat, col); return result; } static inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row ) { VmathVector4 result; vmathM4GetRow(&result, &mat, row); return result; } static inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Transpose(&result, &mat); return result; } static inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Inverse(&result, &mat); return result; } static inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4AffineInverse(&result, &mat); return result; } static inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4OrthoInverse(&result, &mat); return result; } static inline float vmathM4Determinant_V( VmathMatrix4 mat ) { return vmathM4Determinant(&mat); } static inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Add(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Sub(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Neg(&result, &mat); return result; } static inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4AbsPerElem(&result, &mat); return result; } static inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar ) { VmathMatrix4 result; vmathM4ScalarMul(&result, &mat, scalar); return result; } static inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec ) { VmathVector4 result; vmathM4MulV4(&result, &mat, &vec); return result; } static inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec ) { VmathVector4 result; vmathM4MulV3(&result, &mat, &vec); return result; } static inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt ) { VmathVector4 result; vmathM4MulP3(&result, &mat, &pnt); return result; } static inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Mul(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm1 ) { VmathMatrix4 result; vmathM4MulT3(&result, &mat, &tfrm1); return result; } static inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4MakeIdentity_V( ) { VmathMatrix4 result; vmathM4MakeIdentity(&result); return result; } static inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 ) { vmathM4SetUpper3x3(result, &mat3); } static inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat ) { VmathMatrix3 result; vmathM4GetUpper3x3(&result, &mat); return result; } static inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec ) { vmathM4SetTranslation(result, &translateVec); } static inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat ) { VmathVector3 result; vmathM4GetTranslation(&result, &mat); return result; } static inline VmathMatrix4 vmathM4MakeRotationX_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationX(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationY_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationY(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationZ(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathMatrix4 result; vmathM4MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathMatrix4 result; vmathM4MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat ) { VmathMatrix4 result; vmathM4MakeRotationQ(&result, &unitQuat); return result; } static inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec ) { VmathMatrix4 result; vmathM4MakeScale(&result, &scaleVec); return result; } static inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec ) { VmathMatrix4 result; vmathM4AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeTranslation(&result, &translateVec); return result; } static inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec ) { VmathMatrix4 result; vmathM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec); return result; } static inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 ) { VmathMatrix4 result; vmathM4Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathM4Print_V( VmathMatrix4 mat ) { vmathM4Print(&mat); } static inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name ) { vmathM4Prints(&mat, name); } #endif static inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar ) { VmathTransform3 result; vmathT3MakeFromScalar(&result, scalar); return result; } static inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2, VmathVector3 _col3 ) { VmathTransform3 result; vmathT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeFromM3V3(&result, &tfrm, &translateVec); return result; } static inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 _col0 ) { vmathT3SetCol0(result, &_col0); } static inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 _col1 ) { vmathT3SetCol1(result, &_col1); } static inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 _col2 ) { vmathT3SetCol2(result, &_col2); } static inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 _col3 ) { vmathT3SetCol3(result, &_col3); } static inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec ) { vmathT3SetCol(result, col, &vec); } static inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec ) { vmathT3SetRow(result, row, &vec); } static inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val ) { vmathT3SetElem(result, col, row, val); } static inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row ) { return vmathT3GetElem(&tfrm, col, row); } static inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol0(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol1(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol2(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol3(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col ) { VmathVector3 result; vmathT3GetCol(&result, &tfrm, col); return result; } static inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row ) { VmathVector4 result; vmathT3GetRow(&result, &tfrm, row); return result; } static inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3Inverse(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3OrthoInverse(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3AbsPerElem(&result, &tfrm); return result; } static inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec ) { VmathVector3 result; vmathT3MulV3(&result, &tfrm, &vec); return result; } static inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt ) { VmathPoint3 result; vmathT3MulP3(&result, &tfrm, &pnt); return result; } static inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ) { VmathTransform3 result; vmathT3Mul(&result, &tfrm0, &tfrm1); return result; } static inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ) { VmathTransform3 result; vmathT3MulPerElem(&result, &tfrm0, &tfrm1); return result; } static inline VmathTransform3 vmathT3MakeIdentity_V( ) { VmathTransform3 result; vmathT3MakeIdentity(&result); return result; } static inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 tfrm ) { vmathT3SetUpper3x3(result, &tfrm); } static inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm ) { VmathMatrix3 result; vmathT3GetUpper3x3(&result, &tfrm); return result; } static inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec ) { vmathT3SetTranslation(result, &translateVec); } static inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetTranslation(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3MakeRotationX_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationX(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationY_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationY(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationZ_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationZ(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathTransform3 result; vmathT3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathTransform3 result; vmathT3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat ) { VmathTransform3 result; vmathT3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec ) { VmathTransform3 result; vmathT3MakeScale(&result, &scaleVec); return result; } static inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec ) { VmathTransform3 result; vmathT3AppendScale(&result, &tfrm, &scaleVec); return result; } static inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3PrependScale(&result, &scaleVec, &tfrm); return result; } static inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeTranslation(&result, &translateVec); return result; } static inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 ) { VmathTransform3 result; vmathT3Select(&result, &tfrm0, &tfrm1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathT3Print_V( VmathTransform3 tfrm ) { vmathT3Print(&tfrm); } static inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name ) { vmathT3Prints(&tfrm, name); } #endif static inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 tfrm ) { VmathQuat result; vmathQMakeFromM3(&result, &tfrm); return result; } static inline VmathMatrix3 vmathV3Outer_V( VmathVector3 tfrm0, VmathVector3 tfrm1 ) { VmathMatrix3 result; vmathV3Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathMatrix4 vmathV4Outer_V( VmathVector4 tfrm0, VmathVector4 tfrm1 ) { VmathMatrix4 result; vmathV4Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat ) { VmathVector3 result; vmathV3RowMul(&result, &vec, &mat); return result; } static inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec ) { VmathMatrix3 result; vmathV3CrossMatrix(&result, &vec); return result; } static inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat ) { VmathMatrix3 result; vmathV3CrossMatrixMul(&result, &vec, &mat); return result; } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/mat_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_SOA_C_H #define _VECTORMATH_MAT_SOA_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants */ #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline void vmathSoaM3Copy( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Copy( &result->col0, &mat->col0 ); vmathSoaV3Copy( &result->col1, &mat->col1 ); vmathSoaV3Copy( &result->col2, &mat->col2 ); } static inline void vmathSoaM3MakeFromScalar( VmathSoaMatrix3 *result, vec_float4 scalar ) { vmathSoaV3MakeFromScalar( &result->col0, scalar ); vmathSoaV3MakeFromScalar( &result->col1, scalar ); vmathSoaV3MakeFromScalar( &result->col2, scalar ); } static inline void vmathSoaM3MakeFromQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat ) { vec_float4 qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; qx = unitQuat->x; qy = unitQuat->y; qz = unitQuat->z; qw = unitQuat->w; qx2 = vec_add( qx, qx ); qy2 = vec_add( qy, qy ); qz2 = vec_add( qz, qz ); qxqx2 = vec_madd( qx, qx2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qxqy2 = vec_madd( qx, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qxqz2 = vec_madd( qx, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qxqw2 = vec_madd( qw, qx2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qyqy2 = vec_madd( qy, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qyqz2 = vec_madd( qy, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qyqw2 = vec_madd( qw, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qzqz2 = vec_madd( qz, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qzqw2 = vec_madd( qw, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); 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 ) ); 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 ) ); 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 ) ); } static inline void vmathSoaM3MakeFromCols( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col0, const VmathSoaVector3 *_col1, const VmathSoaVector3 *_col2 ) { vmathSoaV3Copy( &result->col0, _col0 ); vmathSoaV3Copy( &result->col1, _col1 ); vmathSoaV3Copy( &result->col2, _col2 ); } static inline void vmathSoaM3MakeFromAos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat ) { vmathSoaV3MakeFromAos( &result->col0, &mat->col0 ); vmathSoaV3MakeFromAos( &result->col1, &mat->col1 ); vmathSoaV3MakeFromAos( &result->col2, &mat->col2 ); } static inline void vmathSoaM3MakeFrom4Aos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, const VmathMatrix3 *mat2, const VmathMatrix3 *mat3 ) { vmathSoaV3MakeFrom4Aos( &result->col0, &mat0->col0, &mat1->col0, &mat2->col0, &mat3->col0 ); vmathSoaV3MakeFrom4Aos( &result->col1, &mat0->col1, &mat1->col1, &mat2->col1, &mat3->col1 ); vmathSoaV3MakeFrom4Aos( &result->col2, &mat0->col2, &mat1->col2, &mat2->col2, &mat3->col2 ); } static inline void vmathSoaM3Get4Aos( const VmathSoaMatrix3 *mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 ) { vmathSoaV3Get4Aos( &mat->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 ); vmathSoaV3Get4Aos( &mat->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 ); vmathSoaV3Get4Aos( &mat->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 ); } static inline void vmathSoaM3SetCol0( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col0 ) { vmathSoaV3Copy( &result->col0, _col0 ); } static inline void vmathSoaM3SetCol1( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col1 ) { vmathSoaV3Copy( &result->col1, _col1 ); } static inline void vmathSoaM3SetCol2( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col2 ) { vmathSoaV3Copy( &result->col2, _col2 ); } static inline void vmathSoaM3SetCol( VmathSoaMatrix3 *result, int col, const VmathSoaVector3 *vec ) { vmathSoaV3Copy( (&result->col0 + col), vec ); } static inline void vmathSoaM3SetRow( VmathSoaMatrix3 *result, int row, const VmathSoaVector3 *vec ) { vmathSoaV3SetElem( &result->col0, row, vmathSoaV3GetElem( vec, 0 ) ); vmathSoaV3SetElem( &result->col1, row, vmathSoaV3GetElem( vec, 1 ) ); vmathSoaV3SetElem( &result->col2, row, vmathSoaV3GetElem( vec, 2 ) ); } static inline void vmathSoaM3SetElem( VmathSoaMatrix3 *result, int col, int row, vec_float4 val ) { VmathSoaVector3 tmpV3_0; vmathSoaM3GetCol( &tmpV3_0, result, col ); vmathSoaV3SetElem( &tmpV3_0, row, val ); vmathSoaM3SetCol( result, col, &tmpV3_0 ); } static inline vec_float4 vmathSoaM3GetElem( const VmathSoaMatrix3 *mat, int col, int row ) { VmathSoaVector3 tmpV3_0; vmathSoaM3GetCol( &tmpV3_0, mat, col ); return vmathSoaV3GetElem( &tmpV3_0, row ); } static inline void vmathSoaM3GetCol0( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Copy( result, &mat->col0 ); } static inline void vmathSoaM3GetCol1( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Copy( result, &mat->col1 ); } static inline void vmathSoaM3GetCol2( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Copy( result, &mat->col2 ); } static inline void vmathSoaM3GetCol( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int col ) { vmathSoaV3Copy( result, (&mat->col0 + col) ); } static inline void vmathSoaM3GetRow( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int row ) { vmathSoaV3MakeFromElems( result, vmathSoaV3GetElem( &mat->col0, row ), vmathSoaV3GetElem( &mat->col1, row ), vmathSoaV3GetElem( &mat->col2, row ) ); } static inline void vmathSoaM3Transpose( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { VmathSoaMatrix3 tmpResult; vmathSoaV3MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x ); vmathSoaV3MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y ); vmathSoaV3MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z ); vmathSoaM3Copy( result, &tmpResult ); } static inline void vmathSoaM3Inverse( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { VmathSoaVector3 tmp0, tmp1, tmp2; vec_float4 detinv; vmathSoaV3Cross( &tmp0, &mat->col1, &mat->col2 ); vmathSoaV3Cross( &tmp1, &mat->col2, &mat->col0 ); vmathSoaV3Cross( &tmp2, &mat->col0, &mat->col1 ); detinv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vmathSoaV3Dot( &mat->col2, &tmp2 ) ); 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}) ) ); 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}) ) ); 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}) ) ); } static inline vec_float4 vmathSoaM3Determinant( const VmathSoaMatrix3 *mat ) { VmathSoaVector3 tmpV3_0; vmathSoaV3Cross( &tmpV3_0, &mat->col0, &mat->col1 ); return vmathSoaV3Dot( &mat->col2, &tmpV3_0 ); } static inline void vmathSoaM3Add( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ) { vmathSoaV3Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV3Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV3Add( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathSoaM3Sub( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ) { vmathSoaV3Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV3Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV3Sub( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathSoaM3Neg( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Neg( &result->col0, &mat->col0 ); vmathSoaV3Neg( &result->col1, &mat->col1 ); vmathSoaV3Neg( &result->col2, &mat->col2 ); } static inline void vmathSoaM3AbsPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3AbsPerElem( &result->col0, &mat->col0 ); vmathSoaV3AbsPerElem( &result->col1, &mat->col1 ); vmathSoaV3AbsPerElem( &result->col2, &mat->col2 ); } static inline void vmathSoaM3ScalarMul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, vec_float4 scalar ) { vmathSoaV3ScalarMul( &result->col0, &mat->col0, scalar ); vmathSoaV3ScalarMul( &result->col1, &mat->col1, scalar ); vmathSoaV3ScalarMul( &result->col2, &mat->col2, scalar ); } static inline void vmathSoaM3MulV3( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *vec ) { vec_float4 tmpX, tmpY, tmpZ; 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}) ) ); 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}) ) ); 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}) ) ); vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaM3Mul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ) { VmathSoaMatrix3 tmpResult; vmathSoaM3MulV3( &tmpResult.col0, mat0, &mat1->col0 ); vmathSoaM3MulV3( &tmpResult.col1, mat0, &mat1->col1 ); vmathSoaM3MulV3( &tmpResult.col2, mat0, &mat1->col2 ); vmathSoaM3Copy( result, &tmpResult ); } static inline void vmathSoaM3MulPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ) { vmathSoaV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathSoaM3MakeIdentity( VmathSoaMatrix3 *result ) { vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeZAxis( &result->col2 ); } static inline void vmathSoaM3MakeRotationX( VmathSoaMatrix3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s ); vmathSoaV3MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c ); } static inline void vmathSoaM3MakeRotationY( VmathSoaMatrix3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeFromElems( &result->col0, c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ) ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeFromElems( &result->col2, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ); } static inline void vmathSoaM3MakeRotationZ( VmathSoaMatrix3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeFromElems( &result->col0, c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV3MakeFromElems( &result->col1, negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV3MakeZAxis( &result->col2 ); } static inline void vmathSoaM3MakeRotationZYX( VmathSoaMatrix3 *result, const VmathSoaVector3 *radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ->x, &sX, &cX ); sincosf4( radiansXYZ->y, &sY, &cY ); sincosf4( radiansXYZ->z, &sZ, &cZ ); tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); 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 ) ); 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}) ) ); 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}) ) ); } static inline void vmathSoaM3MakeRotationAxis( VmathSoaMatrix3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ) { vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx; sincosf4( radians, &s, &c ); x = unitVec->x; y = unitVec->y; z = unitVec->z; xy = vec_madd( x, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); yz = vec_madd( y, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); zx = vec_madd( z, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c ); 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}) ) ) ); 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}) ) ) ); 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 ) ); } static inline void vmathSoaM3MakeRotationQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat ) { vmathSoaM3MakeFromQ( result, unitQuat ); } static inline void vmathSoaM3MakeScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec ) { 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}) ); 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}) ); 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 ); } static inline void vmathSoaM3AppendScale( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *scaleVec ) { vmathSoaV3ScalarMul( &result->col0, &mat->col0, vmathSoaV3GetX( scaleVec ) ); vmathSoaV3ScalarMul( &result->col1, &mat->col1, vmathSoaV3GetY( scaleVec ) ); vmathSoaV3ScalarMul( &result->col2, &mat->col2, vmathSoaV3GetZ( scaleVec ) ); } static inline void vmathSoaM3PrependScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix3 *mat ) { vmathSoaV3MulPerElem( &result->col0, &mat->col0, scaleVec ); vmathSoaV3MulPerElem( &result->col1, &mat->col1, scaleVec ); vmathSoaV3MulPerElem( &result->col2, &mat->col2, scaleVec ); } static inline void vmathSoaM3Select( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1, vec_uint4 select1 ) { vmathSoaV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathSoaV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathSoaV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaM3Print( const VmathSoaMatrix3 *mat ) { VmathMatrix3 mat0, mat1, mat2, mat3; vmathSoaM3Get4Aos( mat, &mat0, &mat1, &mat2, &mat3 ); printf("slot 0:\n"); vmathM3Print( &mat0 ); printf("slot 1:\n"); vmathM3Print( &mat1 ); printf("slot 2:\n"); vmathM3Print( &mat2 ); printf("slot 3:\n"); vmathM3Print( &mat3 ); } static inline void vmathSoaM3Prints( const VmathSoaMatrix3 *mat, const char *name ) { printf("%s:\n", name); vmathSoaM3Print( mat ); } #endif static inline void vmathSoaM4Copy( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( &result->col0, &mat->col0 ); vmathSoaV4Copy( &result->col1, &mat->col1 ); vmathSoaV4Copy( &result->col2, &mat->col2 ); vmathSoaV4Copy( &result->col3, &mat->col3 ); } static inline void vmathSoaM4MakeFromScalar( VmathSoaMatrix4 *result, vec_float4 scalar ) { vmathSoaV4MakeFromScalar( &result->col0, scalar ); vmathSoaV4MakeFromScalar( &result->col1, scalar ); vmathSoaV4MakeFromScalar( &result->col2, scalar ); vmathSoaV4MakeFromScalar( &result->col3, scalar ); } static inline void vmathSoaM4MakeFromT3( VmathSoaMatrix4 *result, const VmathSoaTransform3 *mat ) { vmathSoaV4MakeFromV3Scalar( &result->col0, &mat->col0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col1, &mat->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col2, &mat->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col3, &mat->col3, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); } static inline void vmathSoaM4MakeFromCols( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col0, const VmathSoaVector4 *_col1, const VmathSoaVector4 *_col2, const VmathSoaVector4 *_col3 ) { vmathSoaV4Copy( &result->col0, _col0 ); vmathSoaV4Copy( &result->col1, _col1 ); vmathSoaV4Copy( &result->col2, _col2 ); vmathSoaV4Copy( &result->col3, _col3 ); } static inline void vmathSoaM4MakeFromM3V3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *translateVec ) { vmathSoaV4MakeFromV3Scalar( &result->col0, &mat->col0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col1, &mat->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col2, &mat->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); } static inline void vmathSoaM4MakeFromQV3( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec ) { VmathSoaMatrix3 mat; vmathSoaM3MakeFromQ( &mat, unitQuat ); vmathSoaV4MakeFromV3Scalar( &result->col0, &mat.col0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col1, &mat.col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col2, &mat.col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); } static inline void vmathSoaM4MakeFromAos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat ) { vmathSoaV4MakeFromAos( &result->col0, &mat->col0 ); vmathSoaV4MakeFromAos( &result->col1, &mat->col1 ); vmathSoaV4MakeFromAos( &result->col2, &mat->col2 ); vmathSoaV4MakeFromAos( &result->col3, &mat->col3 ); } static inline void vmathSoaM4MakeFrom4Aos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, const VmathMatrix4 *mat2, const VmathMatrix4 *mat3 ) { vmathSoaV4MakeFrom4Aos( &result->col0, &mat0->col0, &mat1->col0, &mat2->col0, &mat3->col0 ); vmathSoaV4MakeFrom4Aos( &result->col1, &mat0->col1, &mat1->col1, &mat2->col1, &mat3->col1 ); vmathSoaV4MakeFrom4Aos( &result->col2, &mat0->col2, &mat1->col2, &mat2->col2, &mat3->col2 ); vmathSoaV4MakeFrom4Aos( &result->col3, &mat0->col3, &mat1->col3, &mat2->col3, &mat3->col3 ); } static inline void vmathSoaM4Get4Aos( const VmathSoaMatrix4 *mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 ) { vmathSoaV4Get4Aos( &mat->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 ); vmathSoaV4Get4Aos( &mat->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 ); vmathSoaV4Get4Aos( &mat->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 ); vmathSoaV4Get4Aos( &mat->col3, &result0->col3, &result1->col3, &result2->col3, &result3->col3 ); } static inline void vmathSoaM4SetCol0( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col0 ) { vmathSoaV4Copy( &result->col0, _col0 ); } static inline void vmathSoaM4SetCol1( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col1 ) { vmathSoaV4Copy( &result->col1, _col1 ); } static inline void vmathSoaM4SetCol2( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col2 ) { vmathSoaV4Copy( &result->col2, _col2 ); } static inline void vmathSoaM4SetCol3( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col3 ) { vmathSoaV4Copy( &result->col3, _col3 ); } static inline void vmathSoaM4SetCol( VmathSoaMatrix4 *result, int col, const VmathSoaVector4 *vec ) { vmathSoaV4Copy( (&result->col0 + col), vec ); } static inline void vmathSoaM4SetRow( VmathSoaMatrix4 *result, int row, const VmathSoaVector4 *vec ) { vmathSoaV4SetElem( &result->col0, row, vmathSoaV4GetElem( vec, 0 ) ); vmathSoaV4SetElem( &result->col1, row, vmathSoaV4GetElem( vec, 1 ) ); vmathSoaV4SetElem( &result->col2, row, vmathSoaV4GetElem( vec, 2 ) ); vmathSoaV4SetElem( &result->col3, row, vmathSoaV4GetElem( vec, 3 ) ); } static inline void vmathSoaM4SetElem( VmathSoaMatrix4 *result, int col, int row, vec_float4 val ) { VmathSoaVector4 tmpV3_0; vmathSoaM4GetCol( &tmpV3_0, result, col ); vmathSoaV4SetElem( &tmpV3_0, row, val ); vmathSoaM4SetCol( result, col, &tmpV3_0 ); } static inline vec_float4 vmathSoaM4GetElem( const VmathSoaMatrix4 *mat, int col, int row ) { VmathSoaVector4 tmpV4_0; vmathSoaM4GetCol( &tmpV4_0, mat, col ); return vmathSoaV4GetElem( &tmpV4_0, row ); } static inline void vmathSoaM4GetCol0( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( result, &mat->col0 ); } static inline void vmathSoaM4GetCol1( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( result, &mat->col1 ); } static inline void vmathSoaM4GetCol2( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( result, &mat->col2 ); } static inline void vmathSoaM4GetCol3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( result, &mat->col3 ); } static inline void vmathSoaM4GetCol( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int col ) { vmathSoaV4Copy( result, (&mat->col0 + col) ); } static inline void vmathSoaM4GetRow( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int row ) { vmathSoaV4MakeFromElems( result, vmathSoaV4GetElem( &mat->col0, row ), vmathSoaV4GetElem( &mat->col1, row ), vmathSoaV4GetElem( &mat->col2, row ), vmathSoaV4GetElem( &mat->col3, row ) ); } static inline void vmathSoaM4Transpose( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { VmathSoaMatrix4 tmpResult; vmathSoaV4MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x, mat->col3.x ); vmathSoaV4MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y, mat->col3.y ); vmathSoaV4MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z, mat->col3.z ); vmathSoaV4MakeFromElems( &tmpResult.col3, mat->col0.w, mat->col1.w, mat->col2.w, mat->col3.w ); vmathSoaM4Copy( result, &tmpResult ); } static inline void vmathSoaM4Inverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { VmathSoaVector4 res0, res1, res2, res3; 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; mA = mat->col0.x; mB = mat->col0.y; mC = mat->col0.z; mD = mat->col0.w; mE = mat->col1.x; mF = mat->col1.y; mG = mat->col1.z; mH = mat->col1.w; mI = mat->col2.x; mJ = mat->col2.y; mK = mat->col2.z; mL = mat->col2.w; mM = mat->col3.x; mN = mat->col3.y; mO = mat->col3.z; mP = mat->col3.w; 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ) ); 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}) ) ) ); 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}) ) ) ); 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}) ) ) ); 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}) ) ) ); vmathSoaV4SetX( &res1, vec_madd( mI, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetY( &res1, vec_madd( mM, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetZ( &res1, vec_madd( mA, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetW( &res1, vec_madd( mE, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetX( &res3, vec_madd( mI, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetY( &res3, vec_madd( mM, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetZ( &res3, vec_madd( mA, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetW( &res3, vec_madd( mE, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetX( &res2, vec_madd( mI, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetY( &res2, vec_madd( mM, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetZ( &res2, vec_madd( mA, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); vmathSoaV4SetW( &res2, vec_madd( mE, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); 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 ) ); vmathSoaV4ScalarMul( &result->col0, &res0, detInv ); vmathSoaV4ScalarMul( &result->col1, &res1, detInv ); vmathSoaV4ScalarMul( &result->col2, &res2, detInv ); vmathSoaV4ScalarMul( &result->col3, &res3, detInv ); } static inline void vmathSoaM4AffineInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { VmathSoaTransform3 affineMat, tmpT3_0; VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathSoaV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathSoaT3SetCol0( &affineMat, &tmpV3_0 ); vmathSoaV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathSoaT3SetCol1( &affineMat, &tmpV3_1 ); vmathSoaV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathSoaT3SetCol2( &affineMat, &tmpV3_2 ); vmathSoaV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathSoaT3SetCol3( &affineMat, &tmpV3_3 ); vmathSoaT3Inverse( &tmpT3_0, &affineMat ); vmathSoaM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathSoaM4OrthoInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { VmathSoaTransform3 affineMat, tmpT3_0; VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathSoaV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathSoaT3SetCol0( &affineMat, &tmpV3_0 ); vmathSoaV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathSoaT3SetCol1( &affineMat, &tmpV3_1 ); vmathSoaV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathSoaT3SetCol2( &affineMat, &tmpV3_2 ); vmathSoaV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathSoaT3SetCol3( &affineMat, &tmpV3_3 ); vmathSoaT3OrthoInverse( &tmpT3_0, &affineMat ); vmathSoaM4MakeFromT3( result, &tmpT3_0 ); } static inline vec_float4 vmathSoaM4Determinant( const VmathSoaMatrix4 *mat ) { 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; mA = mat->col0.x; mB = mat->col0.y; mC = mat->col0.z; mD = mat->col0.w; mE = mat->col1.x; mF = mat->col1.y; mG = mat->col1.z; mH = mat->col1.w; mI = mat->col2.x; mJ = mat->col2.y; mK = mat->col2.z; mL = mat->col2.w; mM = mat->col3.x; mN = mat->col3.y; mO = mat->col3.z; mP = mat->col3.w; 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); } static inline void vmathSoaM4Add( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ) { vmathSoaV4Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV4Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV4Add( &result->col2, &mat0->col2, &mat1->col2 ); vmathSoaV4Add( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathSoaM4Sub( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ) { vmathSoaV4Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV4Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV4Sub( &result->col2, &mat0->col2, &mat1->col2 ); vmathSoaV4Sub( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathSoaM4Neg( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Neg( &result->col0, &mat->col0 ); vmathSoaV4Neg( &result->col1, &mat->col1 ); vmathSoaV4Neg( &result->col2, &mat->col2 ); vmathSoaV4Neg( &result->col3, &mat->col3 ); } static inline void vmathSoaM4AbsPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4AbsPerElem( &result->col0, &mat->col0 ); vmathSoaV4AbsPerElem( &result->col1, &mat->col1 ); vmathSoaV4AbsPerElem( &result->col2, &mat->col2 ); vmathSoaV4AbsPerElem( &result->col3, &mat->col3 ); } static inline void vmathSoaM4ScalarMul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, vec_float4 scalar ) { vmathSoaV4ScalarMul( &result->col0, &mat->col0, scalar ); vmathSoaV4ScalarMul( &result->col1, &mat->col1, scalar ); vmathSoaV4ScalarMul( &result->col2, &mat->col2, scalar ); vmathSoaV4ScalarMul( &result->col3, &mat->col3, scalar ); } static inline void vmathSoaM4MulV4( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector4 *vec ) { vec_float4 tmpX, tmpY, tmpZ, tmpW; 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); vmathSoaV4MakeFromElems( result, tmpX, tmpY, tmpZ, tmpW ); } static inline void vmathSoaM4MulV3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *vec ) { 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); } static inline void vmathSoaM4MulP3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaPoint3 *pnt ) { 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 ); 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 ); 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 ); 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 ); } static inline void vmathSoaM4Mul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ) { VmathSoaMatrix4 tmpResult; vmathSoaM4MulV4( &tmpResult.col0, mat0, &mat1->col0 ); vmathSoaM4MulV4( &tmpResult.col1, mat0, &mat1->col1 ); vmathSoaM4MulV4( &tmpResult.col2, mat0, &mat1->col2 ); vmathSoaM4MulV4( &tmpResult.col3, mat0, &mat1->col3 ); vmathSoaM4Copy( result, &tmpResult ); } static inline void vmathSoaM4MulT3( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaTransform3 *tfrm1 ) { VmathSoaMatrix4 tmpResult; VmathSoaPoint3 tmpP3_0; vmathSoaM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 ); vmathSoaM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 ); vmathSoaM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 ); vmathSoaP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathSoaM4MulP3( &tmpResult.col3, mat, &tmpP3_0 ); vmathSoaM4Copy( result, &tmpResult ); } static inline void vmathSoaM4MulPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ) { vmathSoaV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); vmathSoaV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathSoaM4MakeIdentity( VmathSoaMatrix4 *result ) { vmathSoaV4MakeXAxis( &result->col0 ); vmathSoaV4MakeYAxis( &result->col1 ); vmathSoaV4MakeZAxis( &result->col2 ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4SetUpper3x3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat3 ) { vmathSoaV4SetXYZ( &result->col0, &mat3->col0 ); vmathSoaV4SetXYZ( &result->col1, &mat3->col1 ); vmathSoaV4SetXYZ( &result->col2, &mat3->col2 ); } static inline void vmathSoaM4GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4GetXYZ( &result->col0, &mat->col0 ); vmathSoaV4GetXYZ( &result->col1, &mat->col1 ); vmathSoaV4GetXYZ( &result->col2, &mat->col2 ); } static inline void vmathSoaM4SetTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec ) { vmathSoaV4SetXYZ( &result->col3, translateVec ); } static inline void vmathSoaM4GetTranslation( VmathSoaVector3 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4GetXYZ( result, &mat->col3 ); } static inline void vmathSoaM4MakeRotationX( VmathSoaMatrix4 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV4MakeXAxis( &result->col0 ); 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}) ); 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}) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationY( VmathSoaMatrix4 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); 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}) ); vmathSoaV4MakeYAxis( &result->col1 ); 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}) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationZ( VmathSoaMatrix4 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); 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}) ); 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}) ); vmathSoaV4MakeZAxis( &result->col2 ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationZYX( VmathSoaMatrix4 *result, const VmathSoaVector3 *radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ->x, &sX, &cX ); sincosf4( radiansXYZ->y, &sY, &cY ); sincosf4( radiansXYZ->z, &sZ, &cZ ); tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); 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}) ); 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}) ); 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}) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationAxis( VmathSoaMatrix4 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ) { vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx; sincosf4( radians, &s, &c ); x = unitVec->x; y = unitVec->y; z = unitVec->z; xy = vec_madd( x, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); yz = vec_madd( y, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); zx = vec_madd( z, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c ); 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}) ); 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}) ); 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}) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationQ( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat ) { VmathSoaTransform3 tmpT3_0; vmathSoaT3MakeRotationQ( &tmpT3_0, unitQuat ); vmathSoaM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathSoaM4MakeScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec ) { 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}) ); 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}) ); 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}) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4AppendScale( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *scaleVec ) { vmathSoaV4ScalarMul( &result->col0, &mat->col0, vmathSoaV3GetX( scaleVec ) ); vmathSoaV4ScalarMul( &result->col1, &mat->col1, vmathSoaV3GetY( scaleVec ) ); vmathSoaV4ScalarMul( &result->col2, &mat->col2, vmathSoaV3GetZ( scaleVec ) ); vmathSoaV4Copy( &result->col3, &mat->col3 ); } static inline void vmathSoaM4PrependScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix4 *mat ) { VmathSoaVector4 scale4; vmathSoaV4MakeFromV3Scalar( &scale4, scaleVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); vmathSoaV4MulPerElem( &result->col0, &mat->col0, &scale4 ); vmathSoaV4MulPerElem( &result->col1, &mat->col1, &scale4 ); vmathSoaV4MulPerElem( &result->col2, &mat->col2, &scale4 ); vmathSoaV4MulPerElem( &result->col3, &mat->col3, &scale4 ); } static inline void vmathSoaM4MakeTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec ) { vmathSoaV4MakeXAxis( &result->col0 ); vmathSoaV4MakeYAxis( &result->col1 ); vmathSoaV4MakeZAxis( &result->col2 ); vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); } static inline void vmathSoaM4MakeLookAt( VmathSoaMatrix4 *result, const VmathSoaPoint3 *eyePos, const VmathSoaPoint3 *lookAtPos, const VmathSoaVector3 *upVec ) { VmathSoaMatrix4 m4EyeFrame; VmathSoaVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1; VmathSoaVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; vmathSoaV3Normalize( &v3Y, upVec ); vmathSoaP3Sub( &tmpV3_0, eyePos, lookAtPos ); vmathSoaV3Normalize( &v3Z, &tmpV3_0 ); vmathSoaV3Cross( &tmpV3_1, &v3Y, &v3Z ); vmathSoaV3Normalize( &v3X, &tmpV3_1 ); vmathSoaV3Cross( &v3Y, &v3Z, &v3X ); vmathSoaV4MakeFromV3( &tmpV4_0, &v3X ); vmathSoaV4MakeFromV3( &tmpV4_1, &v3Y ); vmathSoaV4MakeFromV3( &tmpV4_2, &v3Z ); vmathSoaV4MakeFromP3( &tmpV4_3, eyePos ); vmathSoaM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 ); vmathSoaM4OrthoInverse( result, &m4EyeFrame ); } static inline void vmathSoaM4MakePerspective( VmathSoaMatrix4 *result, vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ) { vec_float4 f, rangeInv; 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}) ) ) ); rangeInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) ); 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}) ); 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}) ); 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}) ); 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}) ); } static inline void vmathSoaM4MakeFrustum( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; sum_rl = vec_add( right, left ); sum_tb = vec_add( top, bottom ); sum_nf = vec_add( zNear, zFar ); inv_rl = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( right, left ) ); inv_tb = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( top, bottom ) ); inv_nf = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) ); n2 = vec_add( zNear, zNear ); 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}) ); 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}) ); 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}) ); 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}) ); } static inline void vmathSoaM4MakeOrthographic( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; sum_rl = vec_add( right, left ); sum_tb = vec_add( top, bottom ); sum_nf = vec_add( zNear, zFar ); inv_rl = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( right, left ) ); inv_tb = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( top, bottom ) ); inv_nf = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) ); 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}) ); 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}) ); 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}) ); 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}) ); } static inline void vmathSoaM4Select( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1, vec_uint4 select1 ) { vmathSoaV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathSoaV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathSoaV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); vmathSoaV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaM4Print( const VmathSoaMatrix4 *mat ) { VmathMatrix4 mat0, mat1, mat2, mat3; vmathSoaM4Get4Aos( mat, &mat0, &mat1, &mat2, &mat3 ); printf("slot 0:\n"); vmathM4Print( &mat0 ); printf("slot 1:\n"); vmathM4Print( &mat1 ); printf("slot 2:\n"); vmathM4Print( &mat2 ); printf("slot 3:\n"); vmathM4Print( &mat3 ); } static inline void vmathSoaM4Prints( const VmathSoaMatrix4 *mat, const char *name ) { printf("%s:\n", name); vmathSoaM4Print( mat ); } #endif static inline void vmathSoaT3Copy( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( &result->col0, &tfrm->col0 ); vmathSoaV3Copy( &result->col1, &tfrm->col1 ); vmathSoaV3Copy( &result->col2, &tfrm->col2 ); vmathSoaV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathSoaT3MakeFromScalar( VmathSoaTransform3 *result, vec_float4 scalar ) { vmathSoaV3MakeFromScalar( &result->col0, scalar ); vmathSoaV3MakeFromScalar( &result->col1, scalar ); vmathSoaV3MakeFromScalar( &result->col2, scalar ); vmathSoaV3MakeFromScalar( &result->col3, scalar ); } static inline void vmathSoaT3MakeFromCols( VmathSoaTransform3 *result, const VmathSoaVector3 *_col0, const VmathSoaVector3 *_col1, const VmathSoaVector3 *_col2, const VmathSoaVector3 *_col3 ) { vmathSoaV3Copy( &result->col0, _col0 ); vmathSoaV3Copy( &result->col1, _col1 ); vmathSoaV3Copy( &result->col2, _col2 ); vmathSoaV3Copy( &result->col3, _col3 ); } static inline void vmathSoaT3MakeFromM3V3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm, const VmathSoaVector3 *translateVec ) { vmathSoaT3SetUpper3x3( result, tfrm ); vmathSoaT3SetTranslation( result, translateVec ); } static inline void vmathSoaT3MakeFromQV3( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec ) { VmathSoaMatrix3 tmpM3_0; vmathSoaM3MakeFromQ( &tmpM3_0, unitQuat ); vmathSoaT3SetUpper3x3( result, &tmpM3_0 ); vmathSoaT3SetTranslation( result, translateVec ); } static inline void vmathSoaT3MakeFromAos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm ) { vmathSoaV3MakeFromAos( &result->col0, &tfrm->col0 ); vmathSoaV3MakeFromAos( &result->col1, &tfrm->col1 ); vmathSoaV3MakeFromAos( &result->col2, &tfrm->col2 ); vmathSoaV3MakeFromAos( &result->col3, &tfrm->col3 ); } static inline void vmathSoaT3MakeFrom4Aos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, const VmathTransform3 *tfrm2, const VmathTransform3 *tfrm3 ) { vmathSoaV3MakeFrom4Aos( &result->col0, &tfrm0->col0, &tfrm1->col0, &tfrm2->col0, &tfrm3->col0 ); vmathSoaV3MakeFrom4Aos( &result->col1, &tfrm0->col1, &tfrm1->col1, &tfrm2->col1, &tfrm3->col1 ); vmathSoaV3MakeFrom4Aos( &result->col2, &tfrm0->col2, &tfrm1->col2, &tfrm2->col2, &tfrm3->col2 ); vmathSoaV3MakeFrom4Aos( &result->col3, &tfrm0->col3, &tfrm1->col3, &tfrm2->col3, &tfrm3->col3 ); } static inline void vmathSoaT3Get4Aos( const VmathSoaTransform3 *tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 ) { vmathSoaV3Get4Aos( &tfrm->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 ); vmathSoaV3Get4Aos( &tfrm->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 ); vmathSoaV3Get4Aos( &tfrm->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 ); vmathSoaV3Get4Aos( &tfrm->col3, &result0->col3, &result1->col3, &result2->col3, &result3->col3 ); } static inline void vmathSoaT3SetCol0( VmathSoaTransform3 *result, const VmathSoaVector3 *_col0 ) { vmathSoaV3Copy( &result->col0, _col0 ); } static inline void vmathSoaT3SetCol1( VmathSoaTransform3 *result, const VmathSoaVector3 *_col1 ) { vmathSoaV3Copy( &result->col1, _col1 ); } static inline void vmathSoaT3SetCol2( VmathSoaTransform3 *result, const VmathSoaVector3 *_col2 ) { vmathSoaV3Copy( &result->col2, _col2 ); } static inline void vmathSoaT3SetCol3( VmathSoaTransform3 *result, const VmathSoaVector3 *_col3 ) { vmathSoaV3Copy( &result->col3, _col3 ); } static inline void vmathSoaT3SetCol( VmathSoaTransform3 *result, int col, const VmathSoaVector3 *vec ) { vmathSoaV3Copy( (&result->col0 + col), vec ); } static inline void vmathSoaT3SetRow( VmathSoaTransform3 *result, int row, const VmathSoaVector4 *vec ) { vmathSoaV3SetElem( &result->col0, row, vmathSoaV4GetElem( vec, 0 ) ); vmathSoaV3SetElem( &result->col1, row, vmathSoaV4GetElem( vec, 1 ) ); vmathSoaV3SetElem( &result->col2, row, vmathSoaV4GetElem( vec, 2 ) ); vmathSoaV3SetElem( &result->col3, row, vmathSoaV4GetElem( vec, 3 ) ); } static inline void vmathSoaT3SetElem( VmathSoaTransform3 *result, int col, int row, vec_float4 val ) { VmathSoaVector3 tmpV3_0; vmathSoaT3GetCol( &tmpV3_0, result, col ); vmathSoaV3SetElem( &tmpV3_0, row, val ); vmathSoaT3SetCol( result, col, &tmpV3_0 ); } static inline vec_float4 vmathSoaT3GetElem( const VmathSoaTransform3 *tfrm, int col, int row ) { VmathSoaVector3 tmpV3_0; vmathSoaT3GetCol( &tmpV3_0, tfrm, col ); return vmathSoaV3GetElem( &tmpV3_0, row ); } static inline void vmathSoaT3GetCol0( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col0 ); } static inline void vmathSoaT3GetCol1( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col1 ); } static inline void vmathSoaT3GetCol2( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col2 ); } static inline void vmathSoaT3GetCol3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col3 ); } static inline void vmathSoaT3GetCol( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, int col ) { vmathSoaV3Copy( result, (&tfrm->col0 + col) ); } static inline void vmathSoaT3GetRow( VmathSoaVector4 *result, const VmathSoaTransform3 *tfrm, int row ) { vmathSoaV4MakeFromElems( result, vmathSoaV3GetElem( &tfrm->col0, row ), vmathSoaV3GetElem( &tfrm->col1, row ), vmathSoaV3GetElem( &tfrm->col2, row ), vmathSoaV3GetElem( &tfrm->col3, row ) ); } static inline void vmathSoaT3Inverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ) { VmathSoaVector3 tmp0, tmp1, tmp2, inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5; vec_float4 detinv; vmathSoaV3Cross( &tmp0, &tfrm->col1, &tfrm->col2 ); vmathSoaV3Cross( &tmp1, &tfrm->col2, &tfrm->col0 ); vmathSoaV3Cross( &tmp2, &tfrm->col0, &tfrm->col1 ); detinv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vmathSoaV3Dot( &tfrm->col2, &tmp2 ) ); 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}) ) ); 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}) ) ); 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}) ) ); vmathSoaV3Copy( &result->col0, &inv0 ); vmathSoaV3Copy( &result->col1, &inv1 ); vmathSoaV3Copy( &result->col2, &inv2 ); vmathSoaV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x ); vmathSoaV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y ); vmathSoaV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z ); vmathSoaV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 ); vmathSoaV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 ); vmathSoaV3Neg( &tmpV3_5, &tmpV3_4 ); vmathSoaV3Copy( &result->col3, &tmpV3_5 ); } static inline void vmathSoaT3OrthoInverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ) { VmathSoaVector3 inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5; vmathSoaV3MakeFromElems( &inv0, tfrm->col0.x, tfrm->col1.x, tfrm->col2.x ); vmathSoaV3MakeFromElems( &inv1, tfrm->col0.y, tfrm->col1.y, tfrm->col2.y ); vmathSoaV3MakeFromElems( &inv2, tfrm->col0.z, tfrm->col1.z, tfrm->col2.z ); vmathSoaV3Copy( &result->col0, &inv0 ); vmathSoaV3Copy( &result->col1, &inv1 ); vmathSoaV3Copy( &result->col2, &inv2 ); vmathSoaV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x ); vmathSoaV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y ); vmathSoaV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z ); vmathSoaV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 ); vmathSoaV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 ); vmathSoaV3Neg( &tmpV3_5, &tmpV3_4 ); vmathSoaV3Copy( &result->col3, &tmpV3_5 ); } static inline void vmathSoaT3AbsPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3AbsPerElem( &result->col0, &tfrm->col0 ); vmathSoaV3AbsPerElem( &result->col1, &tfrm->col1 ); vmathSoaV3AbsPerElem( &result->col2, &tfrm->col2 ); vmathSoaV3AbsPerElem( &result->col3, &tfrm->col3 ); } static inline void vmathSoaT3MulV3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *vec ) { vec_float4 tmpX, tmpY, tmpZ; 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}) ) ); 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}) ) ); 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}) ) ); vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaT3MulP3( VmathSoaPoint3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaPoint3 *pnt ) { vec_float4 tmpX, tmpY, tmpZ; 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 ); 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 ); 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 ); vmathSoaP3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaT3Mul( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 ) { VmathSoaTransform3 tmpResult; VmathSoaPoint3 tmpP3_0, tmpP3_1; vmathSoaT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 ); vmathSoaT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 ); vmathSoaT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 ); vmathSoaP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathSoaT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 ); vmathSoaV3MakeFromP3( &tmpResult.col3, &tmpP3_1 ); vmathSoaT3Copy( result, &tmpResult ); } static inline void vmathSoaT3MulPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 ) { vmathSoaV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 ); vmathSoaV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 ); vmathSoaV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 ); vmathSoaV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 ); } static inline void vmathSoaT3MakeIdentity( VmathSoaTransform3 *result ) { vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeZAxis( &result->col2 ); vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaT3SetUpper3x3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm ) { vmathSoaV3Copy( &result->col0, &tfrm->col0 ); vmathSoaV3Copy( &result->col1, &tfrm->col1 ); vmathSoaV3Copy( &result->col2, &tfrm->col2 ); } static inline void vmathSoaT3GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 ); } static inline void vmathSoaT3SetTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec ) { vmathSoaV3Copy( &result->col3, translateVec ); } static inline void vmathSoaT3GetTranslation( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col3 ); } static inline void vmathSoaT3MakeRotationX( VmathSoaTransform3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeFromElems( &result->col1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s ); vmathSoaV3MakeFromElems( &result->col2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c ); vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaT3MakeRotationY( VmathSoaTransform3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeFromElems( &result->col0, c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ) ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeFromElems( &result->col2, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ); vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaT3MakeRotationZ( VmathSoaTransform3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeFromElems( &result->col0, c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV3MakeFromElems( &result->col1, negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaV3MakeZAxis( &result->col2 ); vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaT3MakeRotationZYX( VmathSoaTransform3 *result, const VmathSoaVector3 *radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ->x, &sX, &cX ); sincosf4( radiansXYZ->y, &sY, &cY ); sincosf4( radiansXYZ->z, &sZ, &cZ ); tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); 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 ) ); 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}) ) ); 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}) ) ); vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaT3MakeRotationAxis( VmathSoaTransform3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ) { VmathSoaMatrix3 tmpM3_0; VmathSoaVector3 tmpV3_0; vmathSoaM3MakeRotationAxis( &tmpM3_0, radians, unitVec ); vmathSoaV3MakeFromScalar( &tmpV3_0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathSoaT3MakeRotationQ( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat ) { VmathSoaMatrix3 tmpM3_0; VmathSoaVector3 tmpV3_0; vmathSoaM3MakeFromQ( &tmpM3_0, unitQuat ); vmathSoaV3MakeFromScalar( &tmpV3_0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathSoaT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathSoaT3MakeScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec ) { 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}) ); 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}) ); 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 ); vmathSoaV3MakeFromScalar( &result->col3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaT3AppendScale( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *scaleVec ) { vmathSoaV3ScalarMul( &result->col0, &tfrm->col0, vmathSoaV3GetX( scaleVec ) ); vmathSoaV3ScalarMul( &result->col1, &tfrm->col1, vmathSoaV3GetY( scaleVec ) ); vmathSoaV3ScalarMul( &result->col2, &tfrm->col2, vmathSoaV3GetZ( scaleVec ) ); vmathSoaV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathSoaT3PrependScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaTransform3 *tfrm ) { vmathSoaV3MulPerElem( &result->col0, &tfrm->col0, scaleVec ); vmathSoaV3MulPerElem( &result->col1, &tfrm->col1, scaleVec ); vmathSoaV3MulPerElem( &result->col2, &tfrm->col2, scaleVec ); vmathSoaV3MulPerElem( &result->col3, &tfrm->col3, scaleVec ); } static inline void vmathSoaT3MakeTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec ) { vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeZAxis( &result->col2 ); vmathSoaV3Copy( &result->col3, translateVec ); } static inline void vmathSoaT3Select( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1, vec_uint4 select1 ) { vmathSoaV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 ); vmathSoaV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 ); vmathSoaV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 ); vmathSoaV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaT3Print( const VmathSoaTransform3 *tfrm ) { VmathTransform3 mat0, mat1, mat2, mat3; vmathSoaT3Get4Aos( tfrm, &mat0, &mat1, &mat2, &mat3 ); printf("slot 0:\n"); vmathT3Print( &mat0 ); printf("slot 1:\n"); vmathT3Print( &mat1 ); printf("slot 2:\n"); vmathT3Print( &mat2 ); printf("slot 3:\n"); vmathT3Print( &mat3 ); } static inline void vmathSoaT3Prints( const VmathSoaTransform3 *tfrm, const char *name ) { printf("%s:\n", name); vmathSoaT3Print( tfrm ); } #endif static inline void vmathSoaQMakeFromM3( VmathSoaQuat *result, const VmathSoaMatrix3 *tfrm ) { vec_float4 trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; vec_uint4 negTrace, ZgtX, ZgtY, YgtX; vec_uint4 largestXorY, largestYorZ, largestZorX; xx = tfrm->col0.x; yx = tfrm->col0.y; zx = tfrm->col0.z; xy = tfrm->col1.x; yy = tfrm->col1.y; zy = tfrm->col1.z; xz = tfrm->col2.x; yz = tfrm->col2.y; zz = tfrm->col2.z; trace = vec_add( vec_add( xx, yy ), zz ); negTrace = (vec_uint4)vec_cmpgt( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), trace ); ZgtX = (vec_uint4)vec_cmpgt( zz, xx ); ZgtY = (vec_uint4)vec_cmpgt( zz, yy ); YgtX = (vec_uint4)vec_cmpgt( yy, xx ); largestXorY = vec_andc( negTrace, vec_and( ZgtX, ZgtY ) ); largestYorZ = vec_and( negTrace, vec_or( YgtX, ZgtX ) ); largestZorX = vec_andc( negTrace, vec_andc( YgtX, ZgtY ) ); zz = vec_sel( zz, negatef4(zz), largestXorY ); xy = vec_sel( xy, negatef4(xy), largestXorY ); xx = vec_sel( xx, negatef4(xx), largestYorZ ); yz = vec_sel( yz, negatef4(yz), largestYorZ ); yy = vec_sel( yy, negatef4(yy), largestZorX ); zx = vec_sel( zx, negatef4(zx), largestZorX ); radicand = vec_add( vec_add( vec_add( xx, yy ), zz ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); 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}) ); tmpx = vec_madd( vec_sub( zy, yz ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmpy = vec_madd( vec_sub( xz, zx ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmpz = vec_madd( vec_sub( yx, xy ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmpw = vec_madd( radicand, scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qx = tmpx; qy = tmpy; qz = tmpz; qw = tmpw; qx = vec_sel( qx, tmpw, largestXorY ); qy = vec_sel( qy, tmpz, largestXorY ); qz = vec_sel( qz, tmpy, largestXorY ); qw = vec_sel( qw, tmpx, largestXorY ); tmpx = qx; tmpz = qz; qx = vec_sel( qx, qy, largestYorZ ); qy = vec_sel( qy, tmpx, largestYorZ ); qz = vec_sel( qz, qw, largestYorZ ); qw = vec_sel( qw, tmpz, largestYorZ ); result->x = qx; result->y = qy; result->z = qz; result->w = qw; } static inline void vmathSoaV3Outer( VmathSoaMatrix3 *result, const VmathSoaVector3 *tfrm0, const VmathSoaVector3 *tfrm1 ) { vmathSoaV3ScalarMul( &result->col0, tfrm0, vmathSoaV3GetX( tfrm1 ) ); vmathSoaV3ScalarMul( &result->col1, tfrm0, vmathSoaV3GetY( tfrm1 ) ); vmathSoaV3ScalarMul( &result->col2, tfrm0, vmathSoaV3GetZ( tfrm1 ) ); } static inline void vmathSoaV4Outer( VmathSoaMatrix4 *result, const VmathSoaVector4 *tfrm0, const VmathSoaVector4 *tfrm1 ) { vmathSoaV4ScalarMul( &result->col0, tfrm0, vmathSoaV4GetX( tfrm1 ) ); vmathSoaV4ScalarMul( &result->col1, tfrm0, vmathSoaV4GetY( tfrm1 ) ); vmathSoaV4ScalarMul( &result->col2, tfrm0, vmathSoaV4GetZ( tfrm1 ) ); vmathSoaV4ScalarMul( &result->col3, tfrm0, vmathSoaV4GetW( tfrm1 ) ); } static inline void vmathSoaV3RowMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat ) { vec_float4 tmpX, tmpY, tmpZ; 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}) ) ); 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}) ) ); 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}) ) ); vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaV3CrossMatrix( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec ) { vmathSoaV3MakeFromElems( &result->col0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec->z, negatef4( vec->y ) ); vmathSoaV3MakeFromElems( &result->col1, negatef4( vec->z ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec->x ); vmathSoaV3MakeFromElems( &result->col2, vec->y, negatef4( vec->x ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaV3CrossMatrixMul( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat ) { VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2; vmathSoaV3Cross( &tmpV3_0, vec, &mat->col0 ); vmathSoaV3Cross( &tmpV3_1, vec, &mat->col1 ); vmathSoaV3Cross( &tmpV3_2, vec, &mat->col2 ); vmathSoaM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 ); } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/mat_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_SOA_V_C_H #define _VECTORMATH_MAT_SOA_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants */ #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromScalar_V( vec_float4 scalar ) { VmathSoaMatrix3 result; vmathSoaM3MakeFromScalar(&result, scalar); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeFromQ_V( VmathSoaQuat unitQuat ) { VmathSoaMatrix3 result; vmathSoaM3MakeFromQ(&result, &unitQuat); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeFromCols_V( VmathSoaVector3 _col0, VmathSoaVector3 _col1, VmathSoaVector3 _col2 ) { VmathSoaMatrix3 result; vmathSoaM3MakeFromCols(&result, &_col0, &_col1, &_col2); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeFromAos_V( VmathMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3MakeFromAos(&result, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeFrom4Aos_V( VmathMatrix3 mat0, VmathMatrix3 mat1, VmathMatrix3 mat2, VmathMatrix3 mat3 ) { VmathSoaMatrix3 result; vmathSoaM3MakeFrom4Aos(&result, &mat0, &mat1, &mat2, &mat3); return result; } static inline void vmathSoaM3Get4Aos_V( VmathSoaMatrix3 mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 ) { vmathSoaM3Get4Aos(&mat, result0, result1, result2, result3); } static inline void vmathSoaM3SetCol0_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col0 ) { vmathSoaM3SetCol0(result, &_col0); } static inline void vmathSoaM3SetCol1_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col1 ) { vmathSoaM3SetCol1(result, &_col1); } static inline void vmathSoaM3SetCol2_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col2 ) { vmathSoaM3SetCol2(result, &_col2); } static inline void vmathSoaM3SetCol_V( VmathSoaMatrix3 *result, int col, VmathSoaVector3 vec ) { vmathSoaM3SetCol(result, col, &vec); } static inline void vmathSoaM3SetRow_V( VmathSoaMatrix3 *result, int row, VmathSoaVector3 vec ) { vmathSoaM3SetRow(result, row, &vec); } static inline void vmathSoaM3SetElem_V( VmathSoaMatrix3 *result, int col, int row, vec_float4 val ) { vmathSoaM3SetElem(result, col, row, val); } static inline vec_float4 vmathSoaM3GetElem_V( VmathSoaMatrix3 mat, int col, int row ) { return vmathSoaM3GetElem(&mat, col, row); } static inline VmathSoaVector3 vmathSoaM3GetCol0_V( VmathSoaMatrix3 mat ) { VmathSoaVector3 result; vmathSoaM3GetCol0(&result, &mat); return result; } static inline VmathSoaVector3 vmathSoaM3GetCol1_V( VmathSoaMatrix3 mat ) { VmathSoaVector3 result; vmathSoaM3GetCol1(&result, &mat); return result; } static inline VmathSoaVector3 vmathSoaM3GetCol2_V( VmathSoaMatrix3 mat ) { VmathSoaVector3 result; vmathSoaM3GetCol2(&result, &mat); return result; } static inline VmathSoaVector3 vmathSoaM3GetCol_V( VmathSoaMatrix3 mat, int col ) { VmathSoaVector3 result; vmathSoaM3GetCol(&result, &mat, col); return result; } static inline VmathSoaVector3 vmathSoaM3GetRow_V( VmathSoaMatrix3 mat, int row ) { VmathSoaVector3 result; vmathSoaM3GetRow(&result, &mat, row); return result; } static inline VmathSoaMatrix3 vmathSoaM3Transpose_V( VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3Transpose(&result, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3Inverse_V( VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3Inverse(&result, &mat); return result; } static inline vec_float4 vmathSoaM3Determinant_V( VmathSoaMatrix3 mat ) { return vmathSoaM3Determinant(&mat); } static inline VmathSoaMatrix3 vmathSoaM3Add_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ) { VmathSoaMatrix3 result; vmathSoaM3Add(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix3 vmathSoaM3Sub_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ) { VmathSoaMatrix3 result; vmathSoaM3Sub(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix3 vmathSoaM3Neg_V( VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3Neg(&result, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3AbsPerElem_V( VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3AbsPerElem(&result, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3ScalarMul_V( VmathSoaMatrix3 mat, vec_float4 scalar ) { VmathSoaMatrix3 result; vmathSoaM3ScalarMul(&result, &mat, scalar); return result; } static inline VmathSoaVector3 vmathSoaM3MulV3_V( VmathSoaMatrix3 mat, VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaM3MulV3(&result, &mat, &vec); return result; } static inline VmathSoaMatrix3 vmathSoaM3Mul_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ) { VmathSoaMatrix3 result; vmathSoaM3Mul(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix3 vmathSoaM3MulPerElem_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ) { VmathSoaMatrix3 result; vmathSoaM3MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeIdentity_V( ) { VmathSoaMatrix3 result; vmathSoaM3MakeIdentity(&result); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationX_V( vec_float4 radians ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationX(&result, radians); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationY_V( vec_float4 radians ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationY(&result, radians); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationZ_V( vec_float4 radians ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationZ(&result, radians); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationQ_V( VmathSoaQuat unitQuat ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeScale_V( VmathSoaVector3 scaleVec ) { VmathSoaMatrix3 result; vmathSoaM3MakeScale(&result, &scaleVec); return result; } static inline VmathSoaMatrix3 vmathSoaM3AppendScale_V( VmathSoaMatrix3 mat, VmathSoaVector3 scaleVec ) { VmathSoaMatrix3 result; vmathSoaM3AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathSoaMatrix3 vmathSoaM3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3Select_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1, vec_uint4 select1 ) { VmathSoaMatrix3 result; vmathSoaM3Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaM3Print_V( VmathSoaMatrix3 mat ) { vmathSoaM3Print(&mat); } static inline void vmathSoaM3Prints_V( VmathSoaMatrix3 mat, const char *name ) { vmathSoaM3Prints(&mat, name); } #endif static inline VmathSoaMatrix4 vmathSoaM4MakeFromScalar_V( vec_float4 scalar ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromScalar(&result, scalar); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromT3_V( VmathSoaTransform3 mat ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromT3(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromCols_V( VmathSoaVector4 _col0, VmathSoaVector4 _col1, VmathSoaVector4 _col2, VmathSoaVector4 _col3 ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromM3V3_V( VmathSoaMatrix3 mat, VmathSoaVector3 translateVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromM3V3(&result, &mat, &translateVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromAos_V( VmathMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromAos(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFrom4Aos_V( VmathMatrix4 mat0, VmathMatrix4 mat1, VmathMatrix4 mat2, VmathMatrix4 mat3 ) { VmathSoaMatrix4 result; vmathSoaM4MakeFrom4Aos(&result, &mat0, &mat1, &mat2, &mat3); return result; } static inline void vmathSoaM4Get4Aos_V( VmathSoaMatrix4 mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 ) { vmathSoaM4Get4Aos(&mat, result0, result1, result2, result3); } static inline void vmathSoaM4SetCol0_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col0 ) { vmathSoaM4SetCol0(result, &_col0); } static inline void vmathSoaM4SetCol1_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col1 ) { vmathSoaM4SetCol1(result, &_col1); } static inline void vmathSoaM4SetCol2_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col2 ) { vmathSoaM4SetCol2(result, &_col2); } static inline void vmathSoaM4SetCol3_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col3 ) { vmathSoaM4SetCol3(result, &_col3); } static inline void vmathSoaM4SetCol_V( VmathSoaMatrix4 *result, int col, VmathSoaVector4 vec ) { vmathSoaM4SetCol(result, col, &vec); } static inline void vmathSoaM4SetRow_V( VmathSoaMatrix4 *result, int row, VmathSoaVector4 vec ) { vmathSoaM4SetRow(result, row, &vec); } static inline void vmathSoaM4SetElem_V( VmathSoaMatrix4 *result, int col, int row, vec_float4 val ) { vmathSoaM4SetElem(result, col, row, val); } static inline vec_float4 vmathSoaM4GetElem_V( VmathSoaMatrix4 mat, int col, int row ) { return vmathSoaM4GetElem(&mat, col, row); } static inline VmathSoaVector4 vmathSoaM4GetCol0_V( VmathSoaMatrix4 mat ) { VmathSoaVector4 result; vmathSoaM4GetCol0(&result, &mat); return result; } static inline VmathSoaVector4 vmathSoaM4GetCol1_V( VmathSoaMatrix4 mat ) { VmathSoaVector4 result; vmathSoaM4GetCol1(&result, &mat); return result; } static inline VmathSoaVector4 vmathSoaM4GetCol2_V( VmathSoaMatrix4 mat ) { VmathSoaVector4 result; vmathSoaM4GetCol2(&result, &mat); return result; } static inline VmathSoaVector4 vmathSoaM4GetCol3_V( VmathSoaMatrix4 mat ) { VmathSoaVector4 result; vmathSoaM4GetCol3(&result, &mat); return result; } static inline VmathSoaVector4 vmathSoaM4GetCol_V( VmathSoaMatrix4 mat, int col ) { VmathSoaVector4 result; vmathSoaM4GetCol(&result, &mat, col); return result; } static inline VmathSoaVector4 vmathSoaM4GetRow_V( VmathSoaMatrix4 mat, int row ) { VmathSoaVector4 result; vmathSoaM4GetRow(&result, &mat, row); return result; } static inline VmathSoaMatrix4 vmathSoaM4Transpose_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4Transpose(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4Inverse_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4Inverse(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4AffineInverse_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4AffineInverse(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4OrthoInverse_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4OrthoInverse(&result, &mat); return result; } static inline vec_float4 vmathSoaM4Determinant_V( VmathSoaMatrix4 mat ) { return vmathSoaM4Determinant(&mat); } static inline VmathSoaMatrix4 vmathSoaM4Add_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ) { VmathSoaMatrix4 result; vmathSoaM4Add(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix4 vmathSoaM4Sub_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ) { VmathSoaMatrix4 result; vmathSoaM4Sub(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix4 vmathSoaM4Neg_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4Neg(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4AbsPerElem_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4AbsPerElem(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4ScalarMul_V( VmathSoaMatrix4 mat, vec_float4 scalar ) { VmathSoaMatrix4 result; vmathSoaM4ScalarMul(&result, &mat, scalar); return result; } static inline VmathSoaVector4 vmathSoaM4MulV4_V( VmathSoaMatrix4 mat, VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaM4MulV4(&result, &mat, &vec); return result; } static inline VmathSoaVector4 vmathSoaM4MulV3_V( VmathSoaMatrix4 mat, VmathSoaVector3 vec ) { VmathSoaVector4 result; vmathSoaM4MulV3(&result, &mat, &vec); return result; } static inline VmathSoaVector4 vmathSoaM4MulP3_V( VmathSoaMatrix4 mat, VmathSoaPoint3 pnt ) { VmathSoaVector4 result; vmathSoaM4MulP3(&result, &mat, &pnt); return result; } static inline VmathSoaMatrix4 vmathSoaM4Mul_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ) { VmathSoaMatrix4 result; vmathSoaM4Mul(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix4 vmathSoaM4MulT3_V( VmathSoaMatrix4 mat, VmathSoaTransform3 tfrm1 ) { VmathSoaMatrix4 result; vmathSoaM4MulT3(&result, &mat, &tfrm1); return result; } static inline VmathSoaMatrix4 vmathSoaM4MulPerElem_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ) { VmathSoaMatrix4 result; vmathSoaM4MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeIdentity_V( ) { VmathSoaMatrix4 result; vmathSoaM4MakeIdentity(&result); return result; } static inline void vmathSoaM4SetUpper3x3_V( VmathSoaMatrix4 *result, VmathSoaMatrix3 mat3 ) { vmathSoaM4SetUpper3x3(result, &mat3); } static inline VmathSoaMatrix3 vmathSoaM4GetUpper3x3_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix3 result; vmathSoaM4GetUpper3x3(&result, &mat); return result; } static inline void vmathSoaM4SetTranslation_V( VmathSoaMatrix4 *result, VmathSoaVector3 translateVec ) { vmathSoaM4SetTranslation(result, &translateVec); } static inline VmathSoaVector3 vmathSoaM4GetTranslation_V( VmathSoaMatrix4 mat ) { VmathSoaVector3 result; vmathSoaM4GetTranslation(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationX_V( vec_float4 radians ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationX(&result, radians); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationY_V( vec_float4 radians ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationY(&result, radians); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationZ_V( vec_float4 radians ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationZ(&result, radians); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationQ_V( VmathSoaQuat unitQuat ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationQ(&result, &unitQuat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeScale_V( VmathSoaVector3 scaleVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeScale(&result, &scaleVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4AppendScale_V( VmathSoaMatrix4 mat, VmathSoaVector3 scaleVec ) { VmathSoaMatrix4 result; vmathSoaM4AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeTranslation_V( VmathSoaVector3 translateVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeTranslation(&result, &translateVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeLookAt_V( VmathSoaPoint3 eyePos, VmathSoaPoint3 lookAtPos, VmathSoaVector3 upVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakePerspective_V( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ) { VmathSoaMatrix4 result; vmathSoaM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFrustum_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { VmathSoaMatrix4 result; vmathSoaM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeOrthographic_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { VmathSoaMatrix4 result; vmathSoaM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathSoaMatrix4 vmathSoaM4Select_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1, vec_uint4 select1 ) { VmathSoaMatrix4 result; vmathSoaM4Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaM4Print_V( VmathSoaMatrix4 mat ) { vmathSoaM4Print(&mat); } static inline void vmathSoaM4Prints_V( VmathSoaMatrix4 mat, const char *name ) { vmathSoaM4Prints(&mat, name); } #endif static inline VmathSoaTransform3 vmathSoaT3MakeFromScalar_V( vec_float4 scalar ) { VmathSoaTransform3 result; vmathSoaT3MakeFromScalar(&result, scalar); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFromCols_V( VmathSoaVector3 _col0, VmathSoaVector3 _col1, VmathSoaVector3 _col2, VmathSoaVector3 _col3 ) { VmathSoaTransform3 result; vmathSoaT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFromM3V3_V( VmathSoaMatrix3 tfrm, VmathSoaVector3 translateVec ) { VmathSoaTransform3 result; vmathSoaT3MakeFromM3V3(&result, &tfrm, &translateVec); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec ) { VmathSoaTransform3 result; vmathSoaT3MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFromAos_V( VmathTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3MakeFromAos(&result, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFrom4Aos_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, VmathTransform3 tfrm2, VmathTransform3 tfrm3 ) { VmathSoaTransform3 result; vmathSoaT3MakeFrom4Aos(&result, &tfrm0, &tfrm1, &tfrm2, &tfrm3); return result; } static inline void vmathSoaT3Get4Aos_V( VmathSoaTransform3 tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 ) { vmathSoaT3Get4Aos(&tfrm, result0, result1, result2, result3); } static inline void vmathSoaT3SetCol0_V( VmathSoaTransform3 *result, VmathSoaVector3 _col0 ) { vmathSoaT3SetCol0(result, &_col0); } static inline void vmathSoaT3SetCol1_V( VmathSoaTransform3 *result, VmathSoaVector3 _col1 ) { vmathSoaT3SetCol1(result, &_col1); } static inline void vmathSoaT3SetCol2_V( VmathSoaTransform3 *result, VmathSoaVector3 _col2 ) { vmathSoaT3SetCol2(result, &_col2); } static inline void vmathSoaT3SetCol3_V( VmathSoaTransform3 *result, VmathSoaVector3 _col3 ) { vmathSoaT3SetCol3(result, &_col3); } static inline void vmathSoaT3SetCol_V( VmathSoaTransform3 *result, int col, VmathSoaVector3 vec ) { vmathSoaT3SetCol(result, col, &vec); } static inline void vmathSoaT3SetRow_V( VmathSoaTransform3 *result, int row, VmathSoaVector4 vec ) { vmathSoaT3SetRow(result, row, &vec); } static inline void vmathSoaT3SetElem_V( VmathSoaTransform3 *result, int col, int row, vec_float4 val ) { vmathSoaT3SetElem(result, col, row, val); } static inline vec_float4 vmathSoaT3GetElem_V( VmathSoaTransform3 tfrm, int col, int row ) { return vmathSoaT3GetElem(&tfrm, col, row); } static inline VmathSoaVector3 vmathSoaT3GetCol0_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetCol0(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3GetCol1_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetCol1(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3GetCol2_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetCol2(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3GetCol3_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetCol3(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3GetCol_V( VmathSoaTransform3 tfrm, int col ) { VmathSoaVector3 result; vmathSoaT3GetCol(&result, &tfrm, col); return result; } static inline VmathSoaVector4 vmathSoaT3GetRow_V( VmathSoaTransform3 tfrm, int row ) { VmathSoaVector4 result; vmathSoaT3GetRow(&result, &tfrm, row); return result; } static inline VmathSoaTransform3 vmathSoaT3Inverse_V( VmathSoaTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3Inverse(&result, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3OrthoInverse_V( VmathSoaTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3OrthoInverse(&result, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3AbsPerElem_V( VmathSoaTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3AbsPerElem(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3MulV3_V( VmathSoaTransform3 tfrm, VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaT3MulV3(&result, &tfrm, &vec); return result; } static inline VmathSoaPoint3 vmathSoaT3MulP3_V( VmathSoaTransform3 tfrm, VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaT3MulP3(&result, &tfrm, &pnt); return result; } static inline VmathSoaTransform3 vmathSoaT3Mul_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 ) { VmathSoaTransform3 result; vmathSoaT3Mul(&result, &tfrm0, &tfrm1); return result; } static inline VmathSoaTransform3 vmathSoaT3MulPerElem_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 ) { VmathSoaTransform3 result; vmathSoaT3MulPerElem(&result, &tfrm0, &tfrm1); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeIdentity_V( ) { VmathSoaTransform3 result; vmathSoaT3MakeIdentity(&result); return result; } static inline void vmathSoaT3SetUpper3x3_V( VmathSoaTransform3 *result, VmathSoaMatrix3 tfrm ) { vmathSoaT3SetUpper3x3(result, &tfrm); } static inline VmathSoaMatrix3 vmathSoaT3GetUpper3x3_V( VmathSoaTransform3 tfrm ) { VmathSoaMatrix3 result; vmathSoaT3GetUpper3x3(&result, &tfrm); return result; } static inline void vmathSoaT3SetTranslation_V( VmathSoaTransform3 *result, VmathSoaVector3 translateVec ) { vmathSoaT3SetTranslation(result, &translateVec); } static inline VmathSoaVector3 vmathSoaT3GetTranslation_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetTranslation(&result, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationX_V( vec_float4 radians ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationX(&result, radians); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationY_V( vec_float4 radians ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationY(&result, radians); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationZ_V( vec_float4 radians ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationZ(&result, radians); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationQ_V( VmathSoaQuat unitQuat ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeScale_V( VmathSoaVector3 scaleVec ) { VmathSoaTransform3 result; vmathSoaT3MakeScale(&result, &scaleVec); return result; } static inline VmathSoaTransform3 vmathSoaT3AppendScale_V( VmathSoaTransform3 tfrm, VmathSoaVector3 scaleVec ) { VmathSoaTransform3 result; vmathSoaT3AppendScale(&result, &tfrm, &scaleVec); return result; } static inline VmathSoaTransform3 vmathSoaT3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3PrependScale(&result, &scaleVec, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeTranslation_V( VmathSoaVector3 translateVec ) { VmathSoaTransform3 result; vmathSoaT3MakeTranslation(&result, &translateVec); return result; } static inline VmathSoaTransform3 vmathSoaT3Select_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1, vec_uint4 select1 ) { VmathSoaTransform3 result; vmathSoaT3Select(&result, &tfrm0, &tfrm1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaT3Print_V( VmathSoaTransform3 tfrm ) { vmathSoaT3Print(&tfrm); } static inline void vmathSoaT3Prints_V( VmathSoaTransform3 tfrm, const char *name ) { vmathSoaT3Prints(&tfrm, name); } #endif static inline VmathSoaQuat vmathSoaQMakeFromM3_V( VmathSoaMatrix3 tfrm ) { VmathSoaQuat result; vmathSoaQMakeFromM3(&result, &tfrm); return result; } static inline VmathSoaMatrix3 vmathSoaV3Outer_V( VmathSoaVector3 tfrm0, VmathSoaVector3 tfrm1 ) { VmathSoaMatrix3 result; vmathSoaV3Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathSoaMatrix4 vmathSoaV4Outer_V( VmathSoaVector4 tfrm0, VmathSoaVector4 tfrm1 ) { VmathSoaMatrix4 result; vmathSoaV4Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathSoaVector3 vmathSoaV3RowMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat ) { VmathSoaVector3 result; vmathSoaV3RowMul(&result, &vec, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaV3CrossMatrix_V( VmathSoaVector3 vec ) { VmathSoaMatrix3 result; vmathSoaV3CrossMatrix(&result, &vec); return result; } static inline VmathSoaMatrix3 vmathSoaV3CrossMatrixMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaV3CrossMatrixMul(&result, &vec, &mat); return result; } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/quat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_C_H #define _VECTORMATH_QUAT_AOS_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat ) { result->vec128 = quat->vec128; } static inline void vmathQMakeFromElems( VmathQuat *result, float _x, float _y, float _z, float _w ) { if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z) & __builtin_constant_p(_w)) { result->vec128 = (vec_float4){_x, _y, _z, _w}; } else { float *pf = (float *)&result->vec128; pf[0] = _x; pf[1] = _y; pf[2] = _z; pf[3] = _w; } } static inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float _w ) { result->vec128 = xyz->vec128; _vmathVfSetElement(result->vec128, _w, 3); } static inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec ) { result->vec128 = vec->vec128; } static inline void vmathQMakeFromScalar( VmathQuat *result, float scalar ) { result->vec128 = _vmathVfSplatScalar(scalar); } static inline void vmathQMakeFrom128( VmathQuat *result, vec_float4 vf4 ) { result->vec128 = vf4; } static inline void vmathQMakeIdentity( VmathQuat *result ) { result->vec128 = _VECTORMATH_UNIT_0001; } static inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 ) { VmathQuat tmpQ_0, tmpQ_1; vmathQSub( &tmpQ_0, quat1, quat0 ); vmathQScalarMul( &tmpQ_1, &tmpQ_0, t ); vmathQAdd( result, quat0, &tmpQ_1 ); } static inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 ) { VmathQuat start; vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; cosAngle = _vmathVfDot4( unitQuat0->vec128, unitQuat1->vec128 ); cosAngle = vec_splat( cosAngle, 0 ); selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), cosAngle ); cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask ); start.vec128 = vec_sel( unitQuat0->vec128, negatef4( unitQuat0->vec128 ), selectMask ); selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle ); angle = acosf4( cosAngle ); tttt = _vmathVfSplatScalar(t); oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( angles, oneMinusT ); angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sines = sinf4( angles ); scales = divf4( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); result->vec128 = vec_madd( start.vec128, scale0, vec_madd( unitQuat1->vec128, scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } static inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 ) { VmathQuat tmp0, tmp1; vmathQSlerp( &tmp0, t, unitQuat0, unitQuat3 ); vmathQSlerp( &tmp1, t, unitQuat1, unitQuat2 ); vmathQSlerp( result, ( ( 2.0f * t ) * ( 1.0f - t ) ), &tmp0, &tmp1 ); } static inline vec_float4 vmathQGet128( const VmathQuat *quat ) { return quat->vec128; } static inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec ) { result->vec128 = vec_sel( vec->vec128, result->vec128, _VECTORMATH_MASK_0x000F ); } static inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat ) { result->vec128 = quat->vec128; } static inline void vmathQSetX( VmathQuat *result, float _x ) { _vmathVfSetElement(result->vec128, _x, 0); } static inline float vmathQGetX( const VmathQuat *quat ) { return _vmathVfGetElement(quat->vec128, 0); } static inline void vmathQSetY( VmathQuat *result, float _y ) { _vmathVfSetElement(result->vec128, _y, 1); } static inline float vmathQGetY( const VmathQuat *quat ) { return _vmathVfGetElement(quat->vec128, 1); } static inline void vmathQSetZ( VmathQuat *result, float _z ) { _vmathVfSetElement(result->vec128, _z, 2); } static inline float vmathQGetZ( const VmathQuat *quat ) { return _vmathVfGetElement(quat->vec128, 2); } static inline void vmathQSetW( VmathQuat *result, float _w ) { _vmathVfSetElement(result->vec128, _w, 3); } static inline float vmathQGetW( const VmathQuat *quat ) { return _vmathVfGetElement(quat->vec128, 3); } static inline void vmathQSetElem( VmathQuat *result, int idx, float value ) { _vmathVfSetElement(result->vec128, value, idx); } static inline float vmathQGetElem( const VmathQuat *quat, int idx ) { return _vmathVfGetElement(quat->vec128, idx); } static inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { result->vec128 = vec_add( quat0->vec128, quat1->vec128 ); } static inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { result->vec128 = vec_sub( quat0->vec128, quat1->vec128 ); } static inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar ) { result->vec128 = vec_madd( quat->vec128, _vmathVfSplatScalar(scalar), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar ) { result->vec128 = divf4( quat->vec128, _vmathVfSplatScalar(scalar) ); } static inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat ) { result->vec128 = negatef4( quat->vec128 ); } static inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 ) { vec_float4 result = _vmathVfDot4( quat0->vec128, quat1->vec128 ); return _vmathVfGetElement(result, 0); } static inline float vmathQNorm( const VmathQuat *quat ) { vec_float4 result = _vmathVfDot4( quat->vec128, quat->vec128 ); return _vmathVfGetElement(result, 0); } static inline float vmathQLength( const VmathQuat *quat ) { return sqrtf( vmathQNorm( quat ) ); } static inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat ) { vec_float4 dot = _vmathVfDot4( quat->vec128, quat->vec128 ); result->vec128 = vec_madd( quat->vec128, rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ) { VmathVector3 crossVec, tmpV3_0; vec_float4 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; cosAngle = _vmathVfDot3( unitVec0->vec128, unitVec1->vec128 ); cosAngle = vec_splat( cosAngle, 0 ); cosAngleX2Plus2 = vec_madd( cosAngle, ((vec_float4){2.0f,2.0f,2.0f,2.0f}), ((vec_float4){2.0f,2.0f,2.0f,2.0f}) ); recipCosHalfAngleX2 = rsqrtf4( cosAngleX2Plus2 ); cosHalfAngleX2 = vec_madd( recipCosHalfAngleX2, cosAngleX2Plus2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); vmathV3Cross( &tmpV3_0, unitVec0, unitVec1 ); crossVec = tmpV3_0; res = vec_madd( crossVec.vec128, recipCosHalfAngleX2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); 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 ); result->vec128 = res; } static inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec ) { vec_float4 s, c, angle, res; 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}) ); sincosf4( angle, &s, &c ); res = vec_sel( vec_madd( unitVec->vec128, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c, _VECTORMATH_MASK_0x000F ); result->vec128 = res; } static inline void vmathQMakeRotationX( VmathQuat *result, float radians ) { vec_float4 s, c, angle, res; 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}) ); sincosf4( angle, &s, &c ); res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0xF000 ); res = vec_sel( res, c, _VECTORMATH_MASK_0x000F ); result->vec128 = res; } static inline void vmathQMakeRotationY( VmathQuat *result, float radians ) { vec_float4 s, c, angle, res; 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}) ); sincosf4( angle, &s, &c ); res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0x0F00 ); res = vec_sel( res, c, _VECTORMATH_MASK_0x000F ); result->vec128 = res; } static inline void vmathQMakeRotationZ( VmathQuat *result, float radians ) { vec_float4 s, c, angle, res; 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}) ); sincosf4( angle, &s, &c ); res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0x00F0 ); res = vec_sel( res, c, _VECTORMATH_MASK_0x000F ); result->vec128 = res; } static inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { vec_float4 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; vec_float4 product, l_wxyz, r_wxyz, xy, qw; ldata = quat0->vec128; rdata = quat1->vec128; tmp0 = vec_perm( ldata, ldata, _VECTORMATH_PERM_YZXW ); tmp1 = vec_perm( rdata, rdata, _VECTORMATH_PERM_ZXYW ); tmp2 = vec_perm( ldata, ldata, _VECTORMATH_PERM_ZXYW ); tmp3 = vec_perm( rdata, rdata, _VECTORMATH_PERM_YZXW ); qv = vec_madd( vec_splat( ldata, 3 ), rdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv ); qv = vec_madd( tmp0, tmp1, qv ); qv = vec_nmsub( tmp2, tmp3, qv ); product = vec_madd( ldata, rdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); l_wxyz = vec_sld( ldata, ldata, 12 ); r_wxyz = vec_sld( rdata, rdata, 12 ); qw = vec_nmsub( l_wxyz, r_wxyz, product ); xy = vec_madd( l_wxyz, r_wxyz, product ); qw = vec_sub( qw, vec_sld( xy, xy, 8 ) ); result->vec128 = vec_sel( qv, qw, _VECTORMATH_MASK_0x000F ); } static inline void vmathQRotate( VmathVector3 *result, const VmathQuat *quat, const VmathVector3 *vec ) { vec_float4 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; qdata = quat->vec128; vdata = vec->vec128; tmp0 = vec_perm( qdata, qdata, _VECTORMATH_PERM_YZXW ); tmp1 = vec_perm( vdata, vdata, _VECTORMATH_PERM_ZXYW ); tmp2 = vec_perm( qdata, qdata, _VECTORMATH_PERM_ZXYW ); tmp3 = vec_perm( vdata, vdata, _VECTORMATH_PERM_YZXW ); wwww = vec_splat( qdata, 3 ); qv = vec_madd( wwww, vdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qv = vec_madd( tmp0, tmp1, qv ); qv = vec_nmsub( tmp2, tmp3, qv ); product = vec_madd( qdata, vdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product ); qw = vec_add( vec_sld( product, product, 8 ), qw ); tmp1 = vec_perm( qv, qv, _VECTORMATH_PERM_ZXYW ); tmp3 = vec_perm( qv, qv, _VECTORMATH_PERM_YZXW ); res = vec_madd( vec_splat( qw, 0 ), qdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); res = vec_madd( wwww, qv, res ); res = vec_madd( tmp0, tmp1, res ); res = vec_nmsub( tmp2, tmp3, res ); result->vec128 = res; } static inline void vmathQConj( VmathQuat *result, const VmathQuat *quat ) { result->vec128 = vec_xor( quat->vec128, ((vec_float4)(vec_int4){0x80000000,0x80000000,0x80000000,0}) ); } static inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 ) { unsigned int tmp; tmp = (unsigned int)-(select1 > 0); result->vec128 = vec_sel( quat0->vec128, quat1->vec128, _vmathVuiSplatScalar(tmp) ); } #ifdef _VECTORMATH_DEBUG static inline void vmathQPrint( const VmathQuat *quat ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = quat->vec128; printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } static inline void vmathQPrints( const VmathQuat *quat, const char *name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = quat->vec128; printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/quat_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_V_C_H #define _VECTORMATH_QUAT_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathQuat vmathQMakeFromElems_V( float _x, float _y, float _z, float _w ) { VmathQuat result; vmathQMakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float _w ) { VmathQuat result; vmathQMakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec ) { VmathQuat result; vmathQMakeFromV4(&result, &vec); return result; } static inline VmathQuat vmathQMakeFromScalar_V( float scalar ) { VmathQuat result; vmathQMakeFromScalar(&result, scalar); return result; } static inline VmathQuat vmathQMakeFrom128_V( vec_float4 vf4 ) { VmathQuat result; vmathQMakeFrom128(&result, vf4); return result; } static inline VmathQuat vmathQMakeIdentity_V( ) { VmathQuat result; vmathQMakeIdentity(&result); return result; } static inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQLerp(&result, t, &quat0, &quat1); return result; } static inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 ) { VmathQuat result; vmathQSlerp(&result, t, &unitQuat0, &unitQuat1); return result; } static inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 ) { VmathQuat result; vmathQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3); return result; } static inline vec_float4 vmathQGet128_V( VmathQuat quat ) { return vmathQGet128(&quat); } static inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec ) { vmathQSetXYZ(result, &vec); } static inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat ) { VmathVector3 result; vmathQGetXYZ(&result, &quat); return result; } static inline void vmathQSetX_V( VmathQuat *result, float _x ) { vmathQSetX(result, _x); } static inline float vmathQGetX_V( VmathQuat quat ) { return vmathQGetX(&quat); } static inline void vmathQSetY_V( VmathQuat *result, float _y ) { vmathQSetY(result, _y); } static inline float vmathQGetY_V( VmathQuat quat ) { return vmathQGetY(&quat); } static inline void vmathQSetZ_V( VmathQuat *result, float _z ) { vmathQSetZ(result, _z); } static inline float vmathQGetZ_V( VmathQuat quat ) { return vmathQGetZ(&quat); } static inline void vmathQSetW_V( VmathQuat *result, float _w ) { vmathQSetW(result, _w); } static inline float vmathQGetW_V( VmathQuat quat ) { return vmathQGetW(&quat); } static inline void vmathQSetElem_V( VmathQuat *result, int idx, float value ) { vmathQSetElem(result, idx, value); } static inline float vmathQGetElem_V( VmathQuat quat, int idx ) { return vmathQGetElem(&quat, idx); } static inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQAdd(&result, &quat0, &quat1); return result; } static inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQSub(&result, &quat0, &quat1); return result; } static inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar ) { VmathQuat result; vmathQScalarMul(&result, &quat, scalar); return result; } static inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar ) { VmathQuat result; vmathQScalarDiv(&result, &quat, scalar); return result; } static inline VmathQuat vmathQNeg_V( VmathQuat quat ) { VmathQuat result; vmathQNeg(&result, &quat); return result; } static inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 ) { return vmathQDot(&quat0, &quat1); } static inline float vmathQNorm_V( VmathQuat quat ) { return vmathQNorm(&quat); } static inline float vmathQLength_V( VmathQuat quat ) { return vmathQLength(&quat); } static inline VmathQuat vmathQNormalize_V( VmathQuat quat ) { VmathQuat result; vmathQNormalize(&result, &quat); return result; } static inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 ) { VmathQuat result; vmathQMakeRotationArc(&result, &unitVec0, &unitVec1); return result; } static inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathQuat result; vmathQMakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathQuat vmathQMakeRotationX_V( float radians ) { VmathQuat result; vmathQMakeRotationX(&result, radians); return result; } static inline VmathQuat vmathQMakeRotationY_V( float radians ) { VmathQuat result; vmathQMakeRotationY(&result, radians); return result; } static inline VmathQuat vmathQMakeRotationZ_V( float radians ) { VmathQuat result; vmathQMakeRotationZ(&result, radians); return result; } static inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQMul(&result, &quat0, &quat1); return result; } static inline VmathVector3 vmathQRotate_V( VmathQuat quat, VmathVector3 vec ) { VmathVector3 result; vmathQRotate(&result, &quat, &vec); return result; } static inline VmathQuat vmathQConj_V( VmathQuat quat ) { VmathQuat result; vmathQConj(&result, &quat); return result; } static inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 ) { VmathQuat result; vmathQSelect(&result, &quat0, &quat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathQPrint_V( VmathQuat quat ) { vmathQPrint(&quat); } static inline void vmathQPrints_V( VmathQuat quat, const char *name ) { vmathQPrints(&quat, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/quat_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_SOA_C_H #define _VECTORMATH_QUAT_SOA_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat ) { result->x = quat->x; result->y = quat->y; result->z = quat->z; result->w = quat->w; } static inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { result->x = _x; result->y = _y; result->z = _z; result->w = _w; } static inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 _w ) { vmathSoaQSetXYZ( result, xyz ); vmathSoaQSetW( result, _w ); } static inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = vec->w; } static inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; result->w = scalar; } static inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat ) { vec_float4 vec128 = quat->vec128; result->x = vec_splat( vec128, 0 ); result->y = vec_splat( vec128, 1 ); result->z = vec_splat( vec128, 2 ); result->w = vec_splat( vec128, 3 ); } static inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( quat0->vec128, quat2->vec128 ); tmp1 = vec_mergeh( quat1->vec128, quat3->vec128 ); tmp2 = vec_mergel( quat0->vec128, quat2->vec128 ); tmp3 = vec_mergel( quat1->vec128, quat3->vec128 ); result->x = vec_mergeh( tmp0, tmp1 ); result->y = vec_mergel( tmp0, tmp1 ); result->z = vec_mergeh( tmp2, tmp3 ); result->w = vec_mergel( tmp2, tmp3 ); } static inline void vmathSoaQMakeIdentity( VmathSoaQuat *result ) { 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}) ); } static inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { VmathSoaQuat tmpQ_0, tmpQ_1; vmathSoaQSub( &tmpQ_0, quat1, quat0 ); vmathSoaQScalarMul( &tmpQ_1, &tmpQ_0, t ); vmathSoaQAdd( result, quat0, &tmpQ_1 ); } static inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 ) { VmathSoaQuat start, tmpQ_0, tmpQ_1; vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = vmathSoaQDot( unitQuat0, unitQuat1 ); selectMask = (vec_uint4)vec_cmpgt( (vec_float4){0.0f,0.0f,0.0f,0.0f}, cosAngle ); cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask ); vmathSoaQSetX( &start, vec_sel( unitQuat0->x, negatef4( unitQuat0->x ), selectMask ) ); vmathSoaQSetY( &start, vec_sel( unitQuat0->y, negatef4( unitQuat0->y ), selectMask ) ); vmathSoaQSetZ( &start, vec_sel( unitQuat0->z, negatef4( unitQuat0->z ), selectMask ) ); vmathSoaQSetW( &start, vec_sel( unitQuat0->w, negatef4( unitQuat0->w ), selectMask ) ); selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) ); 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 ); 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 ); vmathSoaQScalarMul( &tmpQ_0, &start, scale0 ); vmathSoaQScalarMul( &tmpQ_1, unitQuat1, scale1 ); vmathSoaQAdd( result, &tmpQ_0, &tmpQ_1 ); } static inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 ) { VmathSoaQuat tmp0, tmp1; vmathSoaQSlerp( &tmp0, t, unitQuat0, unitQuat3 ); vmathSoaQSlerp( &tmp1, t, unitQuat1, unitQuat2 ); 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 ); } static inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( quat->x, quat->z ); tmp1 = vec_mergeh( quat->y, quat->w ); tmp2 = vec_mergel( quat->x, quat->z ); tmp3 = vec_mergel( quat->y, quat->w ); vmathQMakeFrom128( result0, vec_mergeh( tmp0, tmp1 ) ); vmathQMakeFrom128( result1, vec_mergel( tmp0, tmp1 ) ); vmathQMakeFrom128( result2, vec_mergeh( tmp2, tmp3 ) ); vmathQMakeFrom128( result3, vec_mergel( tmp2, tmp3 ) ); } static inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat ) { vmathSoaV3MakeFromElems( result, quat->x, quat->y, quat->z ); } static inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 _x ) { result->x = _x; } static inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat ) { return quat->x; } static inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 _y ) { result->y = _y; } static inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat ) { return quat->y; } static inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 _z ) { result->z = _z; } static inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat ) { return quat->z; } static inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 _w ) { result->w = _w; } static inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat ) { return quat->w; } static inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value ) { *(&result->x + idx) = value; } static inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx ) { return *(&quat->x + idx); } static inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { result->x = vec_add( quat0->x, quat1->x ); result->y = vec_add( quat0->y, quat1->y ); result->z = vec_add( quat0->z, quat1->z ); result->w = vec_add( quat0->w, quat1->w ); } static inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { result->x = vec_sub( quat0->x, quat1->x ); result->y = vec_sub( quat0->y, quat1->y ); result->z = vec_sub( quat0->z, quat1->z ); result->w = vec_sub( quat0->w, quat1->w ); } static inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar ) { result->x = vec_madd( quat->x, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( quat->y, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( quat->z, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->w = vec_madd( quat->w, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar ) { result->x = divf4( quat->x, scalar ); result->y = divf4( quat->y, scalar ); result->z = divf4( quat->z, scalar ); result->w = divf4( quat->w, scalar ); } static inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat ) { result->x = negatef4( quat->x ); result->y = negatef4( quat->y ); result->z = negatef4( quat->z ); result->w = negatef4( quat->w ); } static inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { vec_float4 result; result = vec_madd( quat0->x, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( quat0->y, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( quat0->z, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( quat0->w, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } static inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat ) { vec_float4 result; result = vec_madd( quat->x, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( quat->y, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( quat->z, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( quat->w, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } static inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat ) { return sqrtf4( vmathSoaQNorm( quat ) ); } static inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat ) { vec_float4 lenSqr, lenInv; lenSqr = vmathSoaQNorm( quat ); lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) ); result->x = vec_madd( quat->x, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( quat->y, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( quat->z, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->w = vec_madd( quat->w, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 ) { VmathSoaVector3 tmpV3_0, tmpV3_1; vec_float4 cosHalfAngleX2, recipCosHalfAngleX2; 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}) ) ); recipCosHalfAngleX2 = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), cosHalfAngleX2 ); vmathSoaV3Cross( &tmpV3_0, unitVec0, unitVec1 ); vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, recipCosHalfAngleX2 ); 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}) ) ); } static inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec ) { VmathSoaVector3 tmpV3_0; vec_float4 s, c, angle; angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sincosf4( angle, &s, &c ); vmathSoaV3ScalarMul( &tmpV3_0, unitVec, s ); vmathSoaQMakeFromV3Scalar( result, &tmpV3_0, c ); } static inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians ) { vec_float4 s, c, angle; angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sincosf4( angle, &s, &c ); vmathSoaQMakeFromElems( result, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ); } static inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians ) { vec_float4 s, c, angle; angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sincosf4( angle, &s, &c ); vmathSoaQMakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ); } static inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians ) { vec_float4 s, c, angle; angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sincosf4( angle, &s, &c ); vmathSoaQMakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, c ); } static inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { vec_float4 tmpX, tmpY, tmpZ, tmpW; 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); vmathSoaQMakeFromElems( result, tmpX, tmpY, tmpZ, tmpW ); } static inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *quat, const VmathSoaVector3 *vec ) { vec_float4 tmpX, tmpY, tmpZ, tmpW; 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); } static inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat ) { vmathSoaQMakeFromElems( result, negatef4( quat->x ), negatef4( quat->y ), negatef4( quat->z ), quat->w ); } static inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 ) { result->x = vec_sel( quat0->x, quat1->x, select1 ); result->y = vec_sel( quat0->y, quat1->y, select1 ); result->z = vec_sel( quat0->z, quat1->z, select1 ); result->w = vec_sel( quat0->w, quat1->w, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaQPrint( const VmathSoaQuat *quat ) { VmathQuat vec0, vec1, vec2, vec3; vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathQPrint( &vec0 ); printf("slot 1:\n"); vmathQPrint( &vec1 ); printf("slot 2:\n"); vmathQPrint( &vec2 ); printf("slot 3:\n"); vmathQPrint( &vec3 ); } static inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name ) { VmathQuat vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathQPrint( &vec0 ); printf("slot 1:\n"); vmathQPrint( &vec1 ); printf("slot 2:\n"); vmathQPrint( &vec2 ); printf("slot 3:\n"); vmathQPrint( &vec3 ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/quat_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_SOA_V_C_H #define _VECTORMATH_QUAT_SOA_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathSoaQuat vmathSoaQMakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { VmathSoaQuat result; vmathSoaQMakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathSoaQuat vmathSoaQMakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 _w ) { VmathSoaQuat result; vmathSoaQMakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathSoaQuat vmathSoaQMakeFromV4_V( VmathSoaVector4 vec ) { VmathSoaQuat result; vmathSoaQMakeFromV4(&result, &vec); return result; } static inline VmathSoaQuat vmathSoaQMakeFromScalar_V( vec_float4 scalar ) { VmathSoaQuat result; vmathSoaQMakeFromScalar(&result, scalar); return result; } static inline VmathSoaQuat vmathSoaQMakeFromAos_V( VmathQuat quat ) { VmathSoaQuat result; vmathSoaQMakeFromAos(&result, &quat); return result; } static inline VmathSoaQuat vmathSoaQMakeFrom4Aos_V( VmathQuat quat0, VmathQuat quat1, VmathQuat quat2, VmathQuat quat3 ) { VmathSoaQuat result; vmathSoaQMakeFrom4Aos(&result, &quat0, &quat1, &quat2, &quat3); return result; } static inline VmathSoaQuat vmathSoaQMakeIdentity_V( ) { VmathSoaQuat result; vmathSoaQMakeIdentity(&result); return result; } static inline VmathSoaQuat vmathSoaQLerp_V( vec_float4 t, VmathSoaQuat quat0, VmathSoaQuat quat1 ) { VmathSoaQuat result; vmathSoaQLerp(&result, t, &quat0, &quat1); return result; } static inline VmathSoaQuat vmathSoaQSlerp_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1 ) { VmathSoaQuat result; vmathSoaQSlerp(&result, t, &unitQuat0, &unitQuat1); return result; } static inline VmathSoaQuat vmathSoaQSquad_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1, VmathSoaQuat unitQuat2, VmathSoaQuat unitQuat3 ) { VmathSoaQuat result; vmathSoaQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3); return result; } static inline void vmathSoaQGet4Aos_V( VmathSoaQuat quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 ) { vmathSoaQGet4Aos(&quat, result0, result1, result2, result3); } static inline void vmathSoaQSetXYZ_V( VmathSoaQuat *result, VmathSoaVector3 vec ) { vmathSoaQSetXYZ(result, &vec); } static inline VmathSoaVector3 vmathSoaQGetXYZ_V( VmathSoaQuat quat ) { VmathSoaVector3 result; vmathSoaQGetXYZ(&result, &quat); return result; } static inline void vmathSoaQSetX_V( VmathSoaQuat *result, vec_float4 _x ) { vmathSoaQSetX(result, _x); } static inline vec_float4 vmathSoaQGetX_V( VmathSoaQuat quat ) { return vmathSoaQGetX(&quat); } static inline void vmathSoaQSetY_V( VmathSoaQuat *result, vec_float4 _y ) { vmathSoaQSetY(result, _y); } static inline vec_float4 vmathSoaQGetY_V( VmathSoaQuat quat ) { return vmathSoaQGetY(&quat); } static inline void vmathSoaQSetZ_V( VmathSoaQuat *result, vec_float4 _z ) { vmathSoaQSetZ(result, _z); } static inline vec_float4 vmathSoaQGetZ_V( VmathSoaQuat quat ) { return vmathSoaQGetZ(&quat); } static inline void vmathSoaQSetW_V( VmathSoaQuat *result, vec_float4 _w ) { vmathSoaQSetW(result, _w); } static inline vec_float4 vmathSoaQGetW_V( VmathSoaQuat quat ) { return vmathSoaQGetW(&quat); } static inline void vmathSoaQSetElem_V( VmathSoaQuat *result, int idx, vec_float4 value ) { vmathSoaQSetElem(result, idx, value); } static inline vec_float4 vmathSoaQGetElem_V( VmathSoaQuat quat, int idx ) { return vmathSoaQGetElem(&quat, idx); } static inline VmathSoaQuat vmathSoaQAdd_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ) { VmathSoaQuat result; vmathSoaQAdd(&result, &quat0, &quat1); return result; } static inline VmathSoaQuat vmathSoaQSub_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ) { VmathSoaQuat result; vmathSoaQSub(&result, &quat0, &quat1); return result; } static inline VmathSoaQuat vmathSoaQScalarMul_V( VmathSoaQuat quat, vec_float4 scalar ) { VmathSoaQuat result; vmathSoaQScalarMul(&result, &quat, scalar); return result; } static inline VmathSoaQuat vmathSoaQScalarDiv_V( VmathSoaQuat quat, vec_float4 scalar ) { VmathSoaQuat result; vmathSoaQScalarDiv(&result, &quat, scalar); return result; } static inline VmathSoaQuat vmathSoaQNeg_V( VmathSoaQuat quat ) { VmathSoaQuat result; vmathSoaQNeg(&result, &quat); return result; } static inline vec_float4 vmathSoaQDot_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ) { return vmathSoaQDot(&quat0, &quat1); } static inline vec_float4 vmathSoaQNorm_V( VmathSoaQuat quat ) { return vmathSoaQNorm(&quat); } static inline vec_float4 vmathSoaQLength_V( VmathSoaQuat quat ) { return vmathSoaQLength(&quat); } static inline VmathSoaQuat vmathSoaQNormalize_V( VmathSoaQuat quat ) { VmathSoaQuat result; vmathSoaQNormalize(&result, &quat); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationArc_V( VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 ) { VmathSoaQuat result; vmathSoaQMakeRotationArc(&result, &unitVec0, &unitVec1); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ) { VmathSoaQuat result; vmathSoaQMakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationX_V( vec_float4 radians ) { VmathSoaQuat result; vmathSoaQMakeRotationX(&result, radians); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationY_V( vec_float4 radians ) { VmathSoaQuat result; vmathSoaQMakeRotationY(&result, radians); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationZ_V( vec_float4 radians ) { VmathSoaQuat result; vmathSoaQMakeRotationZ(&result, radians); return result; } static inline VmathSoaQuat vmathSoaQMul_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ) { VmathSoaQuat result; vmathSoaQMul(&result, &quat0, &quat1); return result; } static inline VmathSoaVector3 vmathSoaQRotate_V( VmathSoaQuat quat, VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaQRotate(&result, &quat, &vec); return result; } static inline VmathSoaQuat vmathSoaQConj_V( VmathSoaQuat quat ) { VmathSoaQuat result; vmathSoaQConj(&result, &quat); return result; } static inline VmathSoaQuat vmathSoaQSelect_V( VmathSoaQuat quat0, VmathSoaQuat quat1, vec_uint4 select1 ) { VmathSoaQuat result; vmathSoaQSelect(&result, &quat0, &quat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaQPrint_V( VmathSoaQuat quat ) { vmathSoaQPrint(&quat); } static inline void vmathSoaQPrints_V( VmathSoaQuat quat, const char *name ) { vmathSoaQPrints(&quat, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/vec_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_C_H #define _VECTORMATH_VEC_AOS_C_H #include #include #include #include "vec_types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for permutes words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_PERM_X 0x00010203 #define _VECTORMATH_PERM_Y 0x04050607 #define _VECTORMATH_PERM_Z 0x08090a0b #define _VECTORMATH_PERM_W 0x0c0d0e0f #define _VECTORMATH_PERM_A 0x10111213 #define _VECTORMATH_PERM_B 0x14151617 #define _VECTORMATH_PERM_C 0x18191a1b #define _VECTORMATH_PERM_D 0x1c1d1e1f #define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A } #define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B } #define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C } #define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W } #define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 } #define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 } #define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 } #define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff } #define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f } #define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f } #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS static inline vec_float4 _vmathVfDot3( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 result; result = vec_madd( vec0, vec1, (vec_float4){0.0f,0.0f,0.0f,0.0f} ); result = vec_madd( vec_sld( vec0, vec0, 4 ), vec_sld( vec1, vec1, 4 ), result ); return vec_madd( vec_sld( vec0, vec0, 8 ), vec_sld( vec1, vec1, 8 ), result ); } static inline vec_float4 _vmathVfDot4( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 result; result = vec_madd( vec0, vec1, (vec_float4){0.0f,0.0f,0.0f,0.0f} ); result = vec_madd( vec_sld( vec0, vec0, 4 ), vec_sld( vec1, vec1, 4 ), result ); return vec_add( vec_sld( result, result, 8 ), result ); } static inline vec_float4 _vmathVfCross( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 tmp0, tmp1, tmp2, tmp3, result; tmp0 = vec_perm( vec0, vec0, _VECTORMATH_PERM_YZXW ); tmp1 = vec_perm( vec1, vec1, _VECTORMATH_PERM_ZXYW ); tmp2 = vec_perm( vec0, vec0, _VECTORMATH_PERM_ZXYW ); tmp3 = vec_perm( vec1, vec1, _VECTORMATH_PERM_YZXW ); result = vec_madd( tmp0, tmp1, (vec_float4){0.0f,0.0f,0.0f,0.0f} ); result = vec_nmsub( tmp2, tmp3, result ); return result; } static inline vec_uint4 _vmathVfToHalfFloatsUnpacked(vec_float4 v) { vec_int4 bexp; vec_uint4 mant, sign, hfloat; vec_uint4 notZero, isInf; const vec_uint4 hfloatInf = (vec_uint4){0x00007c00u,0x00007c00u,0x00007c00u,0x00007c00u}; const vec_uint4 mergeMant = (vec_uint4){0x000003ffu,0x000003ffu,0x000003ffu,0x000003ffu}; const vec_uint4 mergeSign = (vec_uint4){0x00008000u,0x00008000u,0x00008000u,0x00008000u}; sign = vec_sr((vec_uint4)v, (vec_uint4){16,16,16,16}); mant = vec_sr((vec_uint4)v, (vec_uint4){13,13,13,13}); bexp = vec_and(vec_sr((vec_int4)v, (vec_uint4){23,23,23,23}), (vec_int4){0xff,0xff,0xff,0xff}); notZero = (vec_uint4)vec_cmpgt(bexp, (vec_int4){112,112,112,112}); isInf = (vec_uint4)vec_cmpgt(bexp, (vec_int4){142,142,142,142}); bexp = vec_add(bexp, (vec_int4){-112,-112,-112,-112}); bexp = vec_sl(bexp, (vec_uint4){10,10,10,10}); hfloat = vec_sel((vec_uint4)bexp, mant, mergeMant); hfloat = vec_sel((vec_uint4){0,0,0,0}, hfloat, notZero); hfloat = vec_sel(hfloat, hfloatInf, isInf); hfloat = vec_sel(hfloat, sign, mergeSign); return hfloat; } static inline vec_ushort8 _vmath2VfToHalfFloats(vec_float4 u, vec_float4 v) { vec_uint4 hfloat_u, hfloat_v; const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31}; hfloat_u = _vmathVfToHalfFloatsUnpacked(u); hfloat_v = _vmathVfToHalfFloatsUnpacked(v); return (vec_ushort8)vec_perm(hfloat_u, hfloat_v, pack); } #ifndef __GNUC__ #define __builtin_constant_p(x) 0 #endif static inline vec_float4 _vmathVfInsert(vec_float4 dst, vec_float4 src, int slot) { #ifdef __GNUC__ if (__builtin_constant_p(slot)) { dst = vec_sld(dst, dst, slot<<2); dst = vec_sld(dst, src, 4); if (slot != 3) dst = vec_sld(dst, dst, (3-slot)<<2); return dst; } else #endif { vec_uchar16 shiftpattern = vec_lvsr( 0, (float *)(size_t)(slot<<2) ); vec_uint4 selectmask = (vec_uint4)vec_perm( (vec_uint4){0,0,0,0}, _VECTORMATH_MASK_0xF000, shiftpattern ); return vec_sel( dst, src, selectmask ); } } #define _vmathVfGetElement(vec, slot) ((float *)&(vec))[slot] #ifdef _VECTORMATH_SET_CONSTS_IN_MEM #define _vmathVfSetElement(vec, scalar, slot) ((float *)&(vec))[slot] = scalar #else #define _vmathVfSetElement(vec, scalar, slot) \ { \ if (__builtin_constant_p(scalar)) { \ (vec) = _vmathVfInsert(vec, (vec_float4){scalar, scalar, scalar, scalar}, slot); \ } else { \ ((float *)&(vec))[slot] = scalar; \ } \ } #endif static inline vec_float4 _vmathVfSplatScalar(float scalar) { vec_float4 result; if (__builtin_constant_p(scalar)) { result = (vec_float4){scalar, scalar, scalar, scalar}; } else { result = vec_ld(0, &scalar); result = vec_splat(vec_perm(result, result, vec_lvsl(0, &scalar)), 0); } return result; } static inline vec_uint4 _vmathVuiSplatScalar(unsigned int scalar) { vec_uint4 result; if (__builtin_constant_p(scalar)) { result = (vec_uint4){scalar, scalar, scalar, scalar}; } else { result = vec_ld(0, &scalar); result = vec_splat(vec_perm(result, result, vec_lvsl(0, &scalar)), 0); } return result; } #endif static inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = vec->vec128; } static inline void vmathV3MakeFromElems( VmathVector3 *result, float _x, float _y, float _z ) { if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z)) { result->vec128 = (vec_float4){_x, _y, _z, 0.0f}; } else { float *pf = (float *)&result->vec128; pf[0] = _x; pf[1] = _y; pf[2] = _z; } } static inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt ) { result->vec128 = pnt->vec128; } static inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar ) { result->vec128 = _vmathVfSplatScalar(scalar); } static inline void vmathV3MakeFrom128( VmathVector3 *result, vec_float4 vf4 ) { result->vec128 = vf4; } static inline void vmathV3MakeXAxis( VmathVector3 *result ) { result->vec128 = _VECTORMATH_UNIT_1000; } static inline void vmathV3MakeYAxis( VmathVector3 *result ) { result->vec128 = _VECTORMATH_UNIT_0100; } static inline void vmathV3MakeZAxis( VmathVector3 *result ) { result->vec128 = _VECTORMATH_UNIT_0010; } static inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { VmathVector3 tmpV3_0, tmpV3_1; vmathV3Sub( &tmpV3_0, vec1, vec0 ); vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathV3Add( result, vec0, &tmpV3_1 ); } static inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ) { vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; cosAngle = _vmathVfDot3( unitVec0->vec128, unitVec1->vec128 ); cosAngle = vec_splat( cosAngle, 0 ); selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle ); angle = acosf4( cosAngle ); tttt = _vmathVfSplatScalar(t); oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( angles, oneMinusT ); angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sines = sinf4( angles ); scales = divf4( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); result->vec128 = vec_madd( unitVec0->vec128, scale0, vec_madd( unitVec1->vec128, scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } static inline vec_float4 vmathV3Get128( const VmathVector3 *vec ) { return vec->vec128; } static inline void vmathV3StoreXYZ( const VmathVector3 *vec, vec_float4 *quad ) { vec_float4 dstVec = *quad; vec_uint4 mask = _VECTORMATH_MASK_0x000F; dstVec = vec_sel(vec->vec128, dstVec, mask); *quad = dstVec; } static inline void vmathV3LoadXYZArray( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyz1 = vec_sld( xyzx, yzxy, 12 ); xyz2 = vec_sld( yzxy, zxyz, 8 ); xyz3 = vec_sld( zxyz, zxyz, 4 ); vec0->vec128 = xyzx; vec1->vec128 = xyz1; vec2->vec128 = xyz2; vec3->vec128 = xyz3; } static inline void vmathV3StoreXYZArray( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz; xyzx = vec_perm( vec0->vec128, vec1->vec128, _VECTORMATH_PERM_XYZA ); yzxy = vec_perm( vec1->vec128, vec2->vec128, _VECTORMATH_PERM_YZAB ); zxyz = vec_perm( vec2->vec128, vec3->vec128, _VECTORMATH_PERM_ZABC ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } static 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 ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; vmathV3StoreXYZArray( vec0, vec1, vec2, vec3, xyz0 ); vmathV3StoreXYZArray( vec4, vec5, vec6, vec7, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } static inline void vmathV3SetX( VmathVector3 *result, float _x ) { _vmathVfSetElement(result->vec128, _x, 0); } static inline float vmathV3GetX( const VmathVector3 *vec ) { return _vmathVfGetElement(vec->vec128, 0); } static inline void vmathV3SetY( VmathVector3 *result, float _y ) { _vmathVfSetElement(result->vec128, _y, 1); } static inline float vmathV3GetY( const VmathVector3 *vec ) { return _vmathVfGetElement(vec->vec128, 1); } static inline void vmathV3SetZ( VmathVector3 *result, float _z ) { _vmathVfSetElement(result->vec128, _z, 2); } static inline float vmathV3GetZ( const VmathVector3 *vec ) { return _vmathVfGetElement(vec->vec128, 2); } static inline void vmathV3SetElem( VmathVector3 *result, int idx, float value ) { _vmathVfSetElement(result->vec128, value, idx); } static inline float vmathV3GetElem( const VmathVector3 *vec, int idx ) { return _vmathVfGetElement(vec->vec128, idx); } static inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = vec_add( vec0->vec128, vec1->vec128 ); } static inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = vec_sub( vec0->vec128, vec1->vec128 ); } static inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt1 ) { result->vec128 = vec_add( vec->vec128, pnt1->vec128 ); } static inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar ) { result->vec128 = vec_madd( vec->vec128, _vmathVfSplatScalar(scalar), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar ) { result->vec128 = divf4( vec->vec128, _vmathVfSplatScalar(scalar) ); } static inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = negatef4( vec->vec128 ); } static inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = vec_madd( vec0->vec128, vec1->vec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = divf4( vec0->vec128, vec1->vec128 ); } static inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = recipf4( vec->vec128 ); } static inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = sqrtf4( vec->vec128 ); } static inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = rsqrtf4( vec->vec128 ); } static inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = fabsf4( vec->vec128 ); } static inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = copysignf4( vec0->vec128, vec1->vec128 ); } static inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = fmaxf4( vec0->vec128, vec1->vec128 ); } static inline float vmathV3MaxElem( const VmathVector3 *vec ) { vec_float4 result; result = fmaxf4( vec_splat( vec->vec128, 1 ), vec->vec128 ); result = fmaxf4( vec_splat( vec->vec128, 2 ), result ); return _vmathVfGetElement(result, 0); } static inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = fminf4( vec0->vec128, vec1->vec128 ); } static inline float vmathV3MinElem( const VmathVector3 *vec ) { vec_float4 result; result = fminf4( vec_splat( vec->vec128, 1 ), vec->vec128 ); result = fminf4( vec_splat( vec->vec128, 2 ), result ); return _vmathVfGetElement(result, 0); } static inline float vmathV3Sum( const VmathVector3 *vec ) { vec_float4 result; result = vec_add( vec_splat( vec->vec128, 1 ), vec->vec128 ); result = vec_add( vec_splat( vec->vec128, 2 ), result ); return _vmathVfGetElement(result, 0); } static inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 ) { vec_float4 result = _vmathVfDot3( vec0->vec128, vec1->vec128 ); return _vmathVfGetElement(result, 0); } static inline float vmathV3LengthSqr( const VmathVector3 *vec ) { vec_float4 result = _vmathVfDot3( vec->vec128, vec->vec128 ); return _vmathVfGetElement(result, 0); } static inline float vmathV3Length( const VmathVector3 *vec ) { return sqrtf( vmathV3LengthSqr( vec ) ); } static inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec ) { vec_float4 dot = _vmathVfDot3( vec->vec128, vec->vec128 ); dot = vec_splat( dot, 0 ); result->vec128 = vec_madd( vec->vec128, rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = _vmathVfCross( vec0->vec128, vec1->vec128 ); } static inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 ) { unsigned int tmp; tmp = (unsigned int)-(select1 > 0); result->vec128 = vec_sel( vec0->vec128, vec1->vec128, _vmathVuiSplatScalar(tmp) ); } #ifdef _VECTORMATH_DEBUG static inline void vmathV3Print( const VmathVector3 *vec ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec->vec128; printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } static inline void vmathV3Prints( const VmathVector3 *vec, const char *name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec->vec128; printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif static inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = vec->vec128; } static inline void vmathV4MakeFromElems( VmathVector4 *result, float _x, float _y, float _z, float _w ) { if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z) & __builtin_constant_p(_w)) { result->vec128 = (vec_float4){_x, _y, _z, _w}; } else { float *pf = (float *)&result->vec128; pf[0] = _x; pf[1] = _y; pf[2] = _z; pf[3] = _w; } } static inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float _w ) { result->vec128 = xyz->vec128; _vmathVfSetElement(result->vec128, _w, 3); } static inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec ) { result->vec128 = vec->vec128; result->vec128 = _vmathVfInsert(result->vec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), 3); } static inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt ) { result->vec128 = pnt->vec128; result->vec128 = _vmathVfInsert(result->vec128, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), 3); } static inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat ) { result->vec128 = quat->vec128; } static inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar ) { result->vec128 = _vmathVfSplatScalar(scalar); } static inline void vmathV4MakeFrom128( VmathVector4 *result, vec_float4 vf4 ) { result->vec128 = vf4; } static inline void vmathV4MakeXAxis( VmathVector4 *result ) { result->vec128 = _VECTORMATH_UNIT_1000; } static inline void vmathV4MakeYAxis( VmathVector4 *result ) { result->vec128 = _VECTORMATH_UNIT_0100; } static inline void vmathV4MakeZAxis( VmathVector4 *result ) { result->vec128 = _VECTORMATH_UNIT_0010; } static inline void vmathV4MakeWAxis( VmathVector4 *result ) { result->vec128 = _VECTORMATH_UNIT_0001; } static inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { VmathVector4 tmpV4_0, tmpV4_1; vmathV4Sub( &tmpV4_0, vec1, vec0 ); vmathV4ScalarMul( &tmpV4_1, &tmpV4_0, t ); vmathV4Add( result, vec0, &tmpV4_1 ); } static inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 ) { vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; cosAngle = _vmathVfDot4( unitVec0->vec128, unitVec1->vec128 ); cosAngle = vec_splat( cosAngle, 0 ); selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle ); angle = acosf4( cosAngle ); tttt = _vmathVfSplatScalar(t); oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( angles, oneMinusT ); angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sines = sinf4( angles ); scales = divf4( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); result->vec128 = vec_madd( unitVec0->vec128, scale0, vec_madd( unitVec1->vec128, scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } static inline vec_float4 vmathV4Get128( const VmathVector4 *vec ) { return vec->vec128; } static inline void vmathV4StoreHalfFloats( const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3, vec_ushort8 *twoQuads ) { twoQuads[0] = _vmath2VfToHalfFloats(vec0->vec128, vec1->vec128); twoQuads[1] = _vmath2VfToHalfFloats(vec2->vec128, vec3->vec128); } static inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec ) { result->vec128 = vec_sel( vec->vec128, result->vec128, _VECTORMATH_MASK_0x000F ); } static inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec ) { result->vec128 = vec->vec128; } static inline void vmathV4SetX( VmathVector4 *result, float _x ) { _vmathVfSetElement(result->vec128, _x, 0); } static inline float vmathV4GetX( const VmathVector4 *vec ) { return _vmathVfGetElement(vec->vec128, 0); } static inline void vmathV4SetY( VmathVector4 *result, float _y ) { _vmathVfSetElement(result->vec128, _y, 1); } static inline float vmathV4GetY( const VmathVector4 *vec ) { return _vmathVfGetElement(vec->vec128, 1); } static inline void vmathV4SetZ( VmathVector4 *result, float _z ) { _vmathVfSetElement(result->vec128, _z, 2); } static inline float vmathV4GetZ( const VmathVector4 *vec ) { return _vmathVfGetElement(vec->vec128, 2); } static inline void vmathV4SetW( VmathVector4 *result, float _w ) { _vmathVfSetElement(result->vec128, _w, 3); } static inline float vmathV4GetW( const VmathVector4 *vec ) { return _vmathVfGetElement(vec->vec128, 3); } static inline void vmathV4SetElem( VmathVector4 *result, int idx, float value ) { _vmathVfSetElement(result->vec128, value, idx); } static inline float vmathV4GetElem( const VmathVector4 *vec, int idx ) { return _vmathVfGetElement(vec->vec128, idx); } static inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = vec_add( vec0->vec128, vec1->vec128 ); } static inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = vec_sub( vec0->vec128, vec1->vec128 ); } static inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar ) { result->vec128 = vec_madd( vec->vec128, _vmathVfSplatScalar(scalar), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar ) { result->vec128 = divf4( vec->vec128, _vmathVfSplatScalar(scalar) ); } static inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = negatef4( vec->vec128 ); } static inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = vec_madd( vec0->vec128, vec1->vec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = divf4( vec0->vec128, vec1->vec128 ); } static inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = recipf4( vec->vec128 ); } static inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = sqrtf4( vec->vec128 ); } static inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = rsqrtf4( vec->vec128 ); } static inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = fabsf4( vec->vec128 ); } static inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = copysignf4( vec0->vec128, vec1->vec128 ); } static inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = fmaxf4( vec0->vec128, vec1->vec128 ); } static inline float vmathV4MaxElem( const VmathVector4 *vec ) { vec_float4 result; result = fmaxf4( vec_splat( vec->vec128, 1 ), vec->vec128 ); result = fmaxf4( vec_splat( vec->vec128, 2 ), result ); result = fmaxf4( vec_splat( vec->vec128, 3 ), result ); return _vmathVfGetElement(result, 0); } static inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = fminf4( vec0->vec128, vec1->vec128 ); } static inline float vmathV4MinElem( const VmathVector4 *vec ) { vec_float4 result; result = fminf4( vec_splat( vec->vec128, 1 ), vec->vec128 ); result = fminf4( vec_splat( vec->vec128, 2 ), result ); result = fminf4( vec_splat( vec->vec128, 3 ), result ); return _vmathVfGetElement(result, 0); } static inline float vmathV4Sum( const VmathVector4 *vec ) { vec_float4 result; result = vec_add( vec_splat( vec->vec128, 1 ), vec->vec128 ); result = vec_add( vec_splat( vec->vec128, 2 ), result ); result = vec_add( vec_splat( vec->vec128, 3 ), result ); return _vmathVfGetElement(result, 0); } static inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 ) { vec_float4 result = _vmathVfDot4( vec0->vec128, vec1->vec128 ); return _vmathVfGetElement(result, 0); } static inline float vmathV4LengthSqr( const VmathVector4 *vec ) { vec_float4 result = _vmathVfDot4( vec->vec128, vec->vec128 ); return _vmathVfGetElement(result, 0); } static inline float vmathV4Length( const VmathVector4 *vec ) { return sqrtf( vmathV4LengthSqr( vec ) ); } static inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec ) { vec_float4 dot = _vmathVfDot4( vec->vec128, vec->vec128 ); result->vec128 = vec_madd( vec->vec128, rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 ) { unsigned int tmp; tmp = (unsigned int)-(select1 > 0); result->vec128 = vec_sel( vec0->vec128, vec1->vec128, _vmathVuiSplatScalar(tmp) ); } #ifdef _VECTORMATH_DEBUG static inline void vmathV4Print( const VmathVector4 *vec ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec->vec128; printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } static inline void vmathV4Prints( const VmathVector4 *vec, const char *name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec->vec128; printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif static inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = pnt->vec128; } static inline void vmathP3MakeFromElems( VmathPoint3 *result, float _x, float _y, float _z ) { if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z)) { result->vec128 = (vec_float4){_x, _y, _z, 0.0f}; } else { float *pf = (float *)&result->vec128; pf[0] = _x; pf[1] = _y; pf[2] = _z; } } static inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec ) { result->vec128 = vec->vec128; } static inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar ) { result->vec128 = _vmathVfSplatScalar(scalar); } static inline void vmathP3MakeFrom128( VmathPoint3 *result, vec_float4 vf4 ) { result->vec128 = vf4; } static inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0, tmpV3_1; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathP3AddV3( result, pnt0, &tmpV3_1 ); } static inline vec_float4 vmathP3Get128( const VmathPoint3 *pnt ) { return pnt->vec128; } static inline void vmathP3StoreXYZ( const VmathPoint3 *pnt, vec_float4 *quad ) { vec_float4 dstVec = *quad; vec_uint4 mask = _VECTORMATH_MASK_0x000F; dstVec = vec_sel(pnt->vec128, dstVec, mask); *quad = dstVec; } static inline void vmathP3LoadXYZArray( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyz1 = vec_sld( xyzx, yzxy, 12 ); xyz2 = vec_sld( yzxy, zxyz, 8 ); xyz3 = vec_sld( zxyz, zxyz, 4 ); pnt0->vec128 = xyzx; pnt1->vec128 = xyz1; pnt2->vec128 = xyz2; pnt3->vec128 = xyz3; } static inline void vmathP3StoreXYZArray( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz; xyzx = vec_perm( pnt0->vec128, pnt1->vec128, _VECTORMATH_PERM_XYZA ); yzxy = vec_perm( pnt1->vec128, pnt2->vec128, _VECTORMATH_PERM_YZAB ); zxyz = vec_perm( pnt2->vec128, pnt3->vec128, _VECTORMATH_PERM_ZABC ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } static 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 ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; vmathP3StoreXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 ); vmathP3StoreXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } static inline void vmathP3SetX( VmathPoint3 *result, float _x ) { _vmathVfSetElement(result->vec128, _x, 0); } static inline float vmathP3GetX( const VmathPoint3 *pnt ) { return _vmathVfGetElement(pnt->vec128, 0); } static inline void vmathP3SetY( VmathPoint3 *result, float _y ) { _vmathVfSetElement(result->vec128, _y, 1); } static inline float vmathP3GetY( const VmathPoint3 *pnt ) { return _vmathVfGetElement(pnt->vec128, 1); } static inline void vmathP3SetZ( VmathPoint3 *result, float _z ) { _vmathVfSetElement(result->vec128, _z, 2); } static inline float vmathP3GetZ( const VmathPoint3 *pnt ) { return _vmathVfGetElement(pnt->vec128, 2); } static inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value ) { _vmathVfSetElement(result->vec128, value, idx); } static inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx ) { return _vmathVfGetElement(pnt->vec128, idx); } static inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = vec_sub( pnt0->vec128, pnt1->vec128 ); } static inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 ) { result->vec128 = vec_add( pnt->vec128, vec1->vec128 ); } static inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 ) { result->vec128 = vec_sub( pnt->vec128, vec1->vec128 ); } static inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = vec_madd( pnt0->vec128, pnt1->vec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = divf4( pnt0->vec128, pnt1->vec128 ); } static inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = recipf4( pnt->vec128 ); } static inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = sqrtf4( pnt->vec128 ); } static inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = rsqrtf4( pnt->vec128 ); } static inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = fabsf4( pnt->vec128 ); } static inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = copysignf4( pnt0->vec128, pnt1->vec128 ); } static inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = fmaxf4( pnt0->vec128, pnt1->vec128 ); } static inline float vmathP3MaxElem( const VmathPoint3 *pnt ) { vec_float4 result; result = fmaxf4( vec_splat( pnt->vec128, 1 ), pnt->vec128 ); result = fmaxf4( vec_splat( pnt->vec128, 2 ), result ); return _vmathVfGetElement(result, 0); } static inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = fminf4( pnt0->vec128, pnt1->vec128 ); } static inline float vmathP3MinElem( const VmathPoint3 *pnt ) { vec_float4 result; result = fminf4( vec_splat( pnt->vec128, 1 ), pnt->vec128 ); result = fminf4( vec_splat( pnt->vec128, 2 ), result ); return _vmathVfGetElement(result, 0); } static inline float vmathP3Sum( const VmathPoint3 *pnt ) { vec_float4 result; result = vec_add( vec_splat( pnt->vec128, 1 ), pnt->vec128 ); result = vec_add( vec_splat( pnt->vec128, 2 ), result ); return _vmathVfGetElement(result, 0); } static inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal ) { VmathPoint3 tmpP3_0; vmathP3MakeFromScalar( &tmpP3_0, scaleVal ); vmathP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec ) { VmathPoint3 tmpP3_0; vmathP3MakeFromV3( &tmpP3_0, scaleVec ); vmathP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec ) { vec_float4 result = _vmathVfDot3( pnt->vec128, unitVec->vec128 ); return _vmathVfGetElement(result, 0); } static inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt ) { VmathVector3 tmpV3_0; vmathV3MakeFromP3( &tmpV3_0, pnt ); return vmathV3LengthSqr( &tmpV3_0 ); } static inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt ) { VmathVector3 tmpV3_0; vmathV3MakeFromP3( &tmpV3_0, pnt ); return vmathV3Length( &tmpV3_0 ); } static inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathV3LengthSqr( &tmpV3_0 ); } static inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathV3Length( &tmpV3_0 ); } static inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 ) { unsigned int tmp; tmp = (unsigned int)-(select1 > 0); result->vec128 = vec_sel( pnt0->vec128, pnt1->vec128, _vmathVuiSplatScalar(tmp) ); } #ifdef _VECTORMATH_DEBUG static inline void vmathP3Print( const VmathPoint3 *pnt ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = pnt->vec128; printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } static inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = pnt->vec128; printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/vec_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_V_C_H #define _VECTORMATH_VEC_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for permutes words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_PERM_X 0x00010203 #define _VECTORMATH_PERM_Y 0x04050607 #define _VECTORMATH_PERM_Z 0x08090a0b #define _VECTORMATH_PERM_W 0x0c0d0e0f #define _VECTORMATH_PERM_A 0x10111213 #define _VECTORMATH_PERM_B 0x14151617 #define _VECTORMATH_PERM_C 0x18191a1b #define _VECTORMATH_PERM_D 0x1c1d1e1f #define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A } #define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B } #define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C } #define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W } #define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 } #define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 } #define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 } #define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff } #define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f } #define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f } #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathVector3 vmathV3MakeFromElems_V( float _x, float _y, float _z ) { VmathVector3 result; vmathV3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt ) { VmathVector3 result; vmathV3MakeFromP3(&result, &pnt); return result; } static inline VmathVector3 vmathV3MakeFromScalar_V( float scalar ) { VmathVector3 result; vmathV3MakeFromScalar(&result, scalar); return result; } static inline VmathVector3 vmathV3MakeFrom128_V( vec_float4 vf4 ) { VmathVector3 result; vmathV3MakeFrom128(&result, vf4); return result; } static inline VmathVector3 vmathV3MakeXAxis_V( ) { VmathVector3 result; vmathV3MakeXAxis(&result); return result; } static inline VmathVector3 vmathV3MakeYAxis_V( ) { VmathVector3 result; vmathV3MakeYAxis(&result); return result; } static inline VmathVector3 vmathV3MakeZAxis_V( ) { VmathVector3 result; vmathV3MakeZAxis(&result); return result; } static inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 ) { VmathVector3 result; vmathV3Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline vec_float4 vmathV3Get128_V( VmathVector3 vec ) { return vmathV3Get128(&vec); } static inline void vmathV3StoreXYZ_V( VmathVector3 vec, vec_float4 *quad ) { vmathV3StoreXYZ(&vec, quad); } static inline void vmathV3LoadXYZArray_V( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads ) { vmathV3LoadXYZArray(vec0, vec1, vec2, vec3, threeQuads); } static inline void vmathV3StoreXYZArray_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, vec_float4 *threeQuads ) { vmathV3StoreXYZArray(&vec0, &vec1, &vec2, &vec3, threeQuads); } static inline void vmathV3StoreHalfFloats_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, VmathVector3 vec4, VmathVector3 vec5, VmathVector3 vec6, VmathVector3 vec7, vec_ushort8 *threeQuads ) { vmathV3StoreHalfFloats(&vec0, &vec1, &vec2, &vec3, &vec4, &vec5, &vec6, &vec7, threeQuads); } static inline void vmathV3SetX_V( VmathVector3 *result, float _x ) { vmathV3SetX(result, _x); } static inline float vmathV3GetX_V( VmathVector3 vec ) { return vmathV3GetX(&vec); } static inline void vmathV3SetY_V( VmathVector3 *result, float _y ) { vmathV3SetY(result, _y); } static inline float vmathV3GetY_V( VmathVector3 vec ) { return vmathV3GetY(&vec); } static inline void vmathV3SetZ_V( VmathVector3 *result, float _z ) { vmathV3SetZ(result, _z); } static inline float vmathV3GetZ_V( VmathVector3 vec ) { return vmathV3GetZ(&vec); } static inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value ) { vmathV3SetElem(result, idx, value); } static inline float vmathV3GetElem_V( VmathVector3 vec, int idx ) { return vmathV3GetElem(&vec, idx); } static inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Add(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Sub(&result, &vec0, &vec1); return result; } static inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathV3AddP3(&result, &vec, &pnt1); return result; } static inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar ) { VmathVector3 result; vmathV3ScalarMul(&result, &vec, scalar); return result; } static inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar ) { VmathVector3 result; vmathV3ScalarDiv(&result, &vec, scalar); return result; } static inline VmathVector3 vmathV3Neg_V( VmathVector3 vec ) { VmathVector3 result; vmathV3Neg(&result, &vec); return result; } static inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3RecipPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3SqrtPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3RsqrtPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3AbsPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MaxPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV3MaxElem_V( VmathVector3 vec ) { return vmathV3MaxElem(&vec); } static inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MinPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV3MinElem_V( VmathVector3 vec ) { return vmathV3MinElem(&vec); } static inline float vmathV3Sum_V( VmathVector3 vec ) { return vmathV3Sum(&vec); } static inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 ) { return vmathV3Dot(&vec0, &vec1); } static inline float vmathV3LengthSqr_V( VmathVector3 vec ) { return vmathV3LengthSqr(&vec); } static inline float vmathV3Length_V( VmathVector3 vec ) { return vmathV3Length(&vec); } static inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec ) { VmathVector3 result; vmathV3Normalize(&result, &vec); return result; } static inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Cross(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 ) { VmathVector3 result; vmathV3Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathV3Print_V( VmathVector3 vec ) { vmathV3Print(&vec); } static inline void vmathV3Prints_V( VmathVector3 vec, const char *name ) { vmathV3Prints(&vec, name); } #endif static inline VmathVector4 vmathV4MakeFromElems_V( float _x, float _y, float _z, float _w ) { VmathVector4 result; vmathV4MakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float _w ) { VmathVector4 result; vmathV4MakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec ) { VmathVector4 result; vmathV4MakeFromV3(&result, &vec); return result; } static inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt ) { VmathVector4 result; vmathV4MakeFromP3(&result, &pnt); return result; } static inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat ) { VmathVector4 result; vmathV4MakeFromQ(&result, &quat); return result; } static inline VmathVector4 vmathV4MakeFromScalar_V( float scalar ) { VmathVector4 result; vmathV4MakeFromScalar(&result, scalar); return result; } static inline VmathVector4 vmathV4MakeFrom128_V( vec_float4 vf4 ) { VmathVector4 result; vmathV4MakeFrom128(&result, vf4); return result; } static inline VmathVector4 vmathV4MakeXAxis_V( ) { VmathVector4 result; vmathV4MakeXAxis(&result); return result; } static inline VmathVector4 vmathV4MakeYAxis_V( ) { VmathVector4 result; vmathV4MakeYAxis(&result); return result; } static inline VmathVector4 vmathV4MakeZAxis_V( ) { VmathVector4 result; vmathV4MakeZAxis(&result); return result; } static inline VmathVector4 vmathV4MakeWAxis_V( ) { VmathVector4 result; vmathV4MakeWAxis(&result); return result; } static inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 ) { VmathVector4 result; vmathV4Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline vec_float4 vmathV4Get128_V( VmathVector4 vec ) { return vmathV4Get128(&vec); } static inline void vmathV4StoreHalfFloats_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3, vec_ushort8 *twoQuads ) { vmathV4StoreHalfFloats(&vec0, &vec1, &vec2, &vec3, twoQuads); } static inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec ) { vmathV4SetXYZ(result, &vec); } static inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec ) { VmathVector3 result; vmathV4GetXYZ(&result, &vec); return result; } static inline void vmathV4SetX_V( VmathVector4 *result, float _x ) { vmathV4SetX(result, _x); } static inline float vmathV4GetX_V( VmathVector4 vec ) { return vmathV4GetX(&vec); } static inline void vmathV4SetY_V( VmathVector4 *result, float _y ) { vmathV4SetY(result, _y); } static inline float vmathV4GetY_V( VmathVector4 vec ) { return vmathV4GetY(&vec); } static inline void vmathV4SetZ_V( VmathVector4 *result, float _z ) { vmathV4SetZ(result, _z); } static inline float vmathV4GetZ_V( VmathVector4 vec ) { return vmathV4GetZ(&vec); } static inline void vmathV4SetW_V( VmathVector4 *result, float _w ) { vmathV4SetW(result, _w); } static inline float vmathV4GetW_V( VmathVector4 vec ) { return vmathV4GetW(&vec); } static inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value ) { vmathV4SetElem(result, idx, value); } static inline float vmathV4GetElem_V( VmathVector4 vec, int idx ) { return vmathV4GetElem(&vec, idx); } static inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Add(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Sub(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar ) { VmathVector4 result; vmathV4ScalarMul(&result, &vec, scalar); return result; } static inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar ) { VmathVector4 result; vmathV4ScalarDiv(&result, &vec, scalar); return result; } static inline VmathVector4 vmathV4Neg_V( VmathVector4 vec ) { VmathVector4 result; vmathV4Neg(&result, &vec); return result; } static inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4RecipPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4SqrtPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4RsqrtPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4AbsPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MaxPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV4MaxElem_V( VmathVector4 vec ) { return vmathV4MaxElem(&vec); } static inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MinPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV4MinElem_V( VmathVector4 vec ) { return vmathV4MinElem(&vec); } static inline float vmathV4Sum_V( VmathVector4 vec ) { return vmathV4Sum(&vec); } static inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 ) { return vmathV4Dot(&vec0, &vec1); } static inline float vmathV4LengthSqr_V( VmathVector4 vec ) { return vmathV4LengthSqr(&vec); } static inline float vmathV4Length_V( VmathVector4 vec ) { return vmathV4Length(&vec); } static inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec ) { VmathVector4 result; vmathV4Normalize(&result, &vec); return result; } static inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 ) { VmathVector4 result; vmathV4Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathV4Print_V( VmathVector4 vec ) { vmathV4Print(&vec); } static inline void vmathV4Prints_V( VmathVector4 vec, const char *name ) { vmathV4Prints(&vec, name); } #endif static inline VmathPoint3 vmathP3MakeFromElems_V( float _x, float _y, float _z ) { VmathPoint3 result; vmathP3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec ) { VmathPoint3 result; vmathP3MakeFromV3(&result, &vec); return result; } static inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar ) { VmathPoint3 result; vmathP3MakeFromScalar(&result, scalar); return result; } static inline VmathPoint3 vmathP3MakeFrom128_V( vec_float4 vf4 ) { VmathPoint3 result; vmathP3MakeFrom128(&result, vf4); return result; } static inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3Lerp(&result, t, &pnt0, &pnt1); return result; } static inline vec_float4 vmathP3Get128_V( VmathPoint3 pnt ) { return vmathP3Get128(&pnt); } static inline void vmathP3StoreXYZ_V( VmathPoint3 pnt, vec_float4 *quad ) { vmathP3StoreXYZ(&pnt, quad); } static inline void vmathP3LoadXYZArray_V( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads ) { vmathP3LoadXYZArray(pnt0, pnt1, pnt2, pnt3, threeQuads); } static inline void vmathP3StoreXYZArray_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, vec_float4 *threeQuads ) { vmathP3StoreXYZArray(&pnt0, &pnt1, &pnt2, &pnt3, threeQuads); } static inline void vmathP3StoreHalfFloats_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, VmathPoint3 pnt4, VmathPoint3 pnt5, VmathPoint3 pnt6, VmathPoint3 pnt7, vec_ushort8 *threeQuads ) { vmathP3StoreHalfFloats(&pnt0, &pnt1, &pnt2, &pnt3, &pnt4, &pnt5, &pnt6, &pnt7, threeQuads); } static inline void vmathP3SetX_V( VmathPoint3 *result, float _x ) { vmathP3SetX(result, _x); } static inline float vmathP3GetX_V( VmathPoint3 pnt ) { return vmathP3GetX(&pnt); } static inline void vmathP3SetY_V( VmathPoint3 *result, float _y ) { vmathP3SetY(result, _y); } static inline float vmathP3GetY_V( VmathPoint3 pnt ) { return vmathP3GetY(&pnt); } static inline void vmathP3SetZ_V( VmathPoint3 *result, float _z ) { vmathP3SetZ(result, _z); } static inline float vmathP3GetZ_V( VmathPoint3 pnt ) { return vmathP3GetZ(&pnt); } static inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value ) { vmathP3SetElem(result, idx, value); } static inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx ) { return vmathP3GetElem(&pnt, idx); } static inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathVector3 result; vmathP3Sub(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec1 ) { VmathPoint3 result; vmathP3AddV3(&result, &pnt, &vec1); return result; } static inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec1 ) { VmathPoint3 result; vmathP3SubV3(&result, &pnt, &vec1); return result; } static inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MulPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3DivPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3RecipPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3SqrtPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3RsqrtPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3AbsPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3CopySignPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MaxPerElem(&result, &pnt0, &pnt1); return result; } static inline float vmathP3MaxElem_V( VmathPoint3 pnt ) { return vmathP3MaxElem(&pnt); } static inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MinPerElem(&result, &pnt0, &pnt1); return result; } static inline float vmathP3MinElem_V( VmathPoint3 pnt ) { return vmathP3MinElem(&pnt); } static inline float vmathP3Sum_V( VmathPoint3 pnt ) { return vmathP3Sum(&pnt); } static inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal ) { VmathPoint3 result; vmathP3Scale(&result, &pnt, scaleVal); return result; } static inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec ) { VmathPoint3 result; vmathP3NonUniformScale(&result, &pnt, &scaleVec); return result; } static inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec ) { return vmathP3Projection(&pnt, &unitVec); } static inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt ) { return vmathP3DistSqrFromOrigin(&pnt); } static inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt ) { return vmathP3DistFromOrigin(&pnt); } static inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { return vmathP3DistSqr(&pnt0, &pnt1); } static inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { return vmathP3Dist(&pnt0, &pnt1); } static inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 ) { VmathPoint3 result; vmathP3Select(&result, &pnt0, &pnt1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathP3Print_V( VmathPoint3 pnt ) { vmathP3Print(&pnt); } static inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name ) { vmathP3Prints(&pnt, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/vec_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_SOA_C_H #define _VECTORMATH_VEC_SOA_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for permutes, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_PERM_X 0x00010203 #define _VECTORMATH_PERM_Y 0x04050607 #define _VECTORMATH_PERM_Z 0x08090a0b #define _VECTORMATH_PERM_W 0x0c0d0e0f #define _VECTORMATH_PERM_A 0x10111213 #define _VECTORMATH_PERM_B 0x14151617 #define _VECTORMATH_PERM_C 0x18191a1b #define _VECTORMATH_PERM_D 0x1c1d1e1f #define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_ZDWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_ZCXA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_XBZD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_WDYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_WCYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B }) #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline void vmathSoaV3Copy( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathSoaV3MakeFromElems( VmathSoaVector3 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z ) { result->x = _x; result->y = _y; result->z = _z; } static inline void vmathSoaV3MakeFromP3( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; } static inline void vmathSoaV3MakeFromScalar( VmathSoaVector3 *result, vec_float4 scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; } static inline void vmathSoaV3MakeFromAos( VmathSoaVector3 *result, const VmathVector3 *vec ) { vec_float4 vec128 = vec->vec128; result->x = vec_splat( vec128, 0 ); result->y = vec_splat( vec128, 1 ); result->z = vec_splat( vec128, 2 ); } static inline void vmathSoaV3MakeFrom4Aos( VmathSoaVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( vec0->vec128, vec2->vec128 ); tmp1 = vec_mergeh( vec1->vec128, vec3->vec128 ); tmp2 = vec_mergel( vec0->vec128, vec2->vec128 ); tmp3 = vec_mergel( vec1->vec128, vec3->vec128 ); result->x = vec_mergeh( tmp0, tmp1 ); result->y = vec_mergel( tmp0, tmp1 ); result->z = vec_mergeh( tmp2, tmp3 ); } static inline void vmathSoaV3MakeXAxis( VmathSoaVector3 *result ) { 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}) ); } static inline void vmathSoaV3MakeYAxis( VmathSoaVector3 *result ) { 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}) ); } static inline void vmathSoaV3MakeZAxis( VmathSoaVector3 *result ) { 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}) ); } static inline void vmathSoaV3Lerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { VmathSoaVector3 tmpV3_0, tmpV3_1; vmathSoaV3Sub( &tmpV3_0, vec1, vec0 ); vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathSoaV3Add( result, vec0, &tmpV3_1 ); } static inline void vmathSoaV3Slerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 ) { VmathSoaVector3 tmpV3_0, tmpV3_1; vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = vmathSoaV3Dot( unitVec0, unitVec1 ); selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) ); 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 ); 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 ); vmathSoaV3ScalarMul( &tmpV3_0, unitVec0, scale0 ); vmathSoaV3ScalarMul( &tmpV3_1, unitVec1, scale1 ); vmathSoaV3Add( result, &tmpV3_0, &tmpV3_1 ); } static inline void vmathSoaV3Get4Aos( const VmathSoaVector3 *vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 ) { vec_float4 tmp0, tmp1; tmp0 = vec_mergeh( vec->x, vec->z ); tmp1 = vec_mergel( vec->x, vec->z ); vmathV3MakeFrom128( result0, vec_mergeh( tmp0, vec->y ) ); vmathV3MakeFrom128( result1, vec_perm( tmp0, vec->y, _VECTORMATH_PERM_ZBWX ) ); vmathV3MakeFrom128( result2, vec_perm( tmp1, vec->y, _VECTORMATH_PERM_XCYX ) ); vmathV3MakeFrom128( result3, vec_perm( tmp1, vec->y, _VECTORMATH_PERM_ZDWX ) ); } static inline void vmathSoaV3LoadXYZArray( VmathSoaVector3 *vec, const vec_float4 *threeQuads ) { vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyxy = vec_sld( yzxy, xyzx, 8 ); zxzx = vec_sld( xyzx, zxyz, 8 ); yzyz = vec_sld( zxyz, yzxy, 8 ); vmathSoaV3SetX( vec, vec_perm( xyxy, zxzx, _VECTORMATH_PERM_ZBXD ) ); vmathSoaV3SetY( vec, vec_perm( xyxy, yzyz, _VECTORMATH_PERM_WCYA ) ); vmathSoaV3SetZ( vec, vec_perm( zxzx, yzyz, _VECTORMATH_PERM_XDZB ) ); } static inline void vmathSoaV3StoreXYZArray( const VmathSoaVector3 *vec, vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz; xyxy = vec_perm( vec->x, vec->y, _VECTORMATH_PERM_ZCXA ); zxzx = vec_perm( vec->z, vec->x, _VECTORMATH_PERM_XBZD ); yzyz = vec_perm( vec->y, vec->z, _VECTORMATH_PERM_WDYB ); xyzx = vec_sld( xyxy, zxzx, 8 ); yzxy = vec_sld( yzyz, xyxy, 8 ); zxyz = vec_sld( zxzx, yzyz, 8 ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } static inline void vmathSoaV3StoreHalfFloats( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_ushort8 *threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; vmathSoaV3StoreXYZArray( vec0, xyz0 ); vmathSoaV3StoreXYZArray( vec1, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } static inline void vmathSoaV3SetX( VmathSoaVector3 *result, vec_float4 _x ) { result->x = _x; } static inline vec_float4 vmathSoaV3GetX( const VmathSoaVector3 *vec ) { return vec->x; } static inline void vmathSoaV3SetY( VmathSoaVector3 *result, vec_float4 _y ) { result->y = _y; } static inline vec_float4 vmathSoaV3GetY( const VmathSoaVector3 *vec ) { return vec->y; } static inline void vmathSoaV3SetZ( VmathSoaVector3 *result, vec_float4 _z ) { result->z = _z; } static inline vec_float4 vmathSoaV3GetZ( const VmathSoaVector3 *vec ) { return vec->z; } static inline void vmathSoaV3SetElem( VmathSoaVector3 *result, int idx, vec_float4 value ) { *(&result->x + idx) = value; } static inline vec_float4 vmathSoaV3GetElem( const VmathSoaVector3 *vec, int idx ) { return *(&vec->x + idx); } static inline void vmathSoaV3Add( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = vec_add( vec0->x, vec1->x ); result->y = vec_add( vec0->y, vec1->y ); result->z = vec_add( vec0->z, vec1->z ); } static inline void vmathSoaV3Sub( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = vec_sub( vec0->x, vec1->x ); result->y = vec_sub( vec0->y, vec1->y ); result->z = vec_sub( vec0->z, vec1->z ); } static inline void vmathSoaV3AddP3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec, const VmathSoaPoint3 *pnt1 ) { result->x = vec_add( vec->x, pnt1->x ); result->y = vec_add( vec->y, pnt1->y ); result->z = vec_add( vec->z, pnt1->z ); } static inline void vmathSoaV3ScalarMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar ) { result->x = vec_madd( vec->x, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( vec->y, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( vec->z, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaV3ScalarDiv( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar ) { result->x = divf4( vec->x, scalar ); result->y = divf4( vec->y, scalar ); result->z = divf4( vec->z, scalar ); } static inline void vmathSoaV3Neg( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = negatef4( vec->x ); result->y = negatef4( vec->y ); result->z = negatef4( vec->z ); } static inline void vmathSoaV3MulPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = vec_madd( vec0->x, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( vec0->y, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( vec0->z, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaV3DivPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = divf4( vec0->x, vec1->x ); result->y = divf4( vec0->y, vec1->y ); result->z = divf4( vec0->z, vec1->z ); } static inline void vmathSoaV3RecipPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->x ); result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->y ); result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->z ); } static inline void vmathSoaV3SqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = sqrtf4( vec->x ); result->y = sqrtf4( vec->y ); result->z = sqrtf4( vec->z ); } static inline void vmathSoaV3RsqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->x ) ); result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->y ) ); result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->z ) ); } static inline void vmathSoaV3AbsPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = fabsf4( vec->x ); result->y = fabsf4( vec->y ); result->z = fabsf4( vec->z ); } static inline void vmathSoaV3CopySignPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = copysignf4( vec0->x, vec1->x ); result->y = copysignf4( vec0->y, vec1->y ); result->z = copysignf4( vec0->z, vec1->z ); } static inline void vmathSoaV3MaxPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = fmaxf4( vec0->x, vec1->x ); result->y = fmaxf4( vec0->y, vec1->y ); result->z = fmaxf4( vec0->z, vec1->z ); } static inline vec_float4 vmathSoaV3MaxElem( const VmathSoaVector3 *vec ) { vec_float4 result; result = fmaxf4( vec->x, vec->y ); result = fmaxf4( vec->z, result ); return result; } static inline void vmathSoaV3MinPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = fminf4( vec0->x, vec1->x ); result->y = fminf4( vec0->y, vec1->y ); result->z = fminf4( vec0->z, vec1->z ); } static inline vec_float4 vmathSoaV3MinElem( const VmathSoaVector3 *vec ) { vec_float4 result; result = fminf4( vec->x, vec->y ); result = fminf4( vec->z, result ); return result; } static inline vec_float4 vmathSoaV3Sum( const VmathSoaVector3 *vec ) { vec_float4 result; result = vec_add( vec->x, vec->y ); result = vec_add( result, vec->z ); return result; } static inline vec_float4 vmathSoaV3Dot( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { vec_float4 result; result = vec_madd( vec0->x, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( vec0->y, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec0->z, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } static inline vec_float4 vmathSoaV3LengthSqr( const VmathSoaVector3 *vec ) { vec_float4 result; result = vec_madd( vec->x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( vec->y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec->z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } static inline vec_float4 vmathSoaV3Length( const VmathSoaVector3 *vec ) { return sqrtf4( vmathSoaV3LengthSqr( vec ) ); } static inline void vmathSoaV3Normalize( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { vec_float4 lenSqr, lenInv; lenSqr = vmathSoaV3LengthSqr( vec ); lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) ); result->x = vec_madd( vec->x, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( vec->y, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( vec->z, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaV3Cross( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { vec_float4 tmpX, tmpY, tmpZ; 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}) ) ); 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}) ) ); 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}) ) ); vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaV3Select( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_uint4 select1 ) { result->x = vec_sel( vec0->x, vec1->x, select1 ); result->y = vec_sel( vec0->y, vec1->y, select1 ); result->z = vec_sel( vec0->z, vec1->z, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaV3Print( const VmathSoaVector3 *vec ) { VmathVector3 vec0, vec1, vec2, vec3; vmathSoaV3Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathV3Print( &vec0 ); printf("slot 1:\n"); vmathV3Print( &vec1 ); printf("slot 2:\n"); vmathV3Print( &vec2 ); printf("slot 3:\n"); vmathV3Print( &vec3 ); } static inline void vmathSoaV3Prints( const VmathSoaVector3 *vec, const char *name ) { VmathVector3 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vmathSoaV3Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathV3Print( &vec0 ); printf("slot 1:\n"); vmathV3Print( &vec1 ); printf("slot 2:\n"); vmathV3Print( &vec2 ); printf("slot 3:\n"); vmathV3Print( &vec3 ); } #endif static inline void vmathSoaV4Copy( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = vec->w; } static inline void vmathSoaV4MakeFromElems( VmathSoaVector4 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { result->x = _x; result->y = _y; result->z = _z; result->w = _w; } static inline void vmathSoaV4MakeFromV3Scalar( VmathSoaVector4 *result, const VmathSoaVector3 *xyz, vec_float4 _w ) { vmathSoaV4SetXYZ( result, xyz ); vmathSoaV4SetW( result, _w ); } static inline void vmathSoaV4MakeFromV3( VmathSoaVector4 *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); } static inline void vmathSoaV4MakeFromP3( VmathSoaVector4 *result, const VmathSoaPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; result->w = ((vec_float4){1.0f,1.0f,1.0f,1.0f}); } static inline void vmathSoaV4MakeFromQ( VmathSoaVector4 *result, const VmathSoaQuat *quat ) { result->x = quat->x; result->y = quat->y; result->z = quat->z; result->w = quat->w; } static inline void vmathSoaV4MakeFromScalar( VmathSoaVector4 *result, vec_float4 scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; result->w = scalar; } static inline void vmathSoaV4MakeFromAos( VmathSoaVector4 *result, const VmathVector4 *vec ) { vec_float4 vec128 = vec->vec128; result->x = vec_splat( vec128, 0 ); result->y = vec_splat( vec128, 1 ); result->z = vec_splat( vec128, 2 ); result->w = vec_splat( vec128, 3 ); } static inline void vmathSoaV4MakeFrom4Aos( VmathSoaVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( vec0->vec128, vec2->vec128 ); tmp1 = vec_mergeh( vec1->vec128, vec3->vec128 ); tmp2 = vec_mergel( vec0->vec128, vec2->vec128 ); tmp3 = vec_mergel( vec1->vec128, vec3->vec128 ); result->x = vec_mergeh( tmp0, tmp1 ); result->y = vec_mergel( tmp0, tmp1 ); result->z = vec_mergeh( tmp2, tmp3 ); result->w = vec_mergel( tmp2, tmp3 ); } static inline void vmathSoaV4MakeXAxis( VmathSoaVector4 *result ) { 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}) ); } static inline void vmathSoaV4MakeYAxis( VmathSoaVector4 *result ) { 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}) ); } static inline void vmathSoaV4MakeZAxis( VmathSoaVector4 *result ) { 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}) ); } static inline void vmathSoaV4MakeWAxis( VmathSoaVector4 *result ) { 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}) ); } static inline void vmathSoaV4Lerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { VmathSoaVector4 tmpV4_0, tmpV4_1; vmathSoaV4Sub( &tmpV4_0, vec1, vec0 ); vmathSoaV4ScalarMul( &tmpV4_1, &tmpV4_0, t ); vmathSoaV4Add( result, vec0, &tmpV4_1 ); } static inline void vmathSoaV4Slerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *unitVec0, const VmathSoaVector4 *unitVec1 ) { VmathSoaVector4 tmpV4_0, tmpV4_1; vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = vmathSoaV4Dot( unitVec0, unitVec1 ); selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) ); 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 ); 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 ); vmathSoaV4ScalarMul( &tmpV4_0, unitVec0, scale0 ); vmathSoaV4ScalarMul( &tmpV4_1, unitVec1, scale1 ); vmathSoaV4Add( result, &tmpV4_0, &tmpV4_1 ); } static inline void vmathSoaV4Get4Aos( const VmathSoaVector4 *vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( vec->x, vec->z ); tmp1 = vec_mergeh( vec->y, vec->w ); tmp2 = vec_mergel( vec->x, vec->z ); tmp3 = vec_mergel( vec->y, vec->w ); vmathV4MakeFrom128( result0, vec_mergeh( tmp0, tmp1 ) ); vmathV4MakeFrom128( result1, vec_mergel( tmp0, tmp1 ) ); vmathV4MakeFrom128( result2, vec_mergeh( tmp2, tmp3 ) ); vmathV4MakeFrom128( result3, vec_mergel( tmp2, tmp3 ) ); } static inline void vmathSoaV4StoreHalfFloats( const VmathSoaVector4 *vec, vec_ushort8 *twoQuads ) { VmathVector4 v0, v1, v2, v3; vmathSoaV4Get4Aos( vec, &v0, &v1, &v2, &v3 ); twoQuads[0] = _vmath2VfToHalfFloats(v0.vec128, v1.vec128); twoQuads[1] = _vmath2VfToHalfFloats(v2.vec128, v3.vec128); } static inline void vmathSoaV4SetXYZ( VmathSoaVector4 *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathSoaV4GetXYZ( VmathSoaVector3 *result, const VmathSoaVector4 *vec ) { vmathSoaV3MakeFromElems( result, vec->x, vec->y, vec->z ); } static inline void vmathSoaV4SetX( VmathSoaVector4 *result, vec_float4 _x ) { result->x = _x; } static inline vec_float4 vmathSoaV4GetX( const VmathSoaVector4 *vec ) { return vec->x; } static inline void vmathSoaV4SetY( VmathSoaVector4 *result, vec_float4 _y ) { result->y = _y; } static inline vec_float4 vmathSoaV4GetY( const VmathSoaVector4 *vec ) { return vec->y; } static inline void vmathSoaV4SetZ( VmathSoaVector4 *result, vec_float4 _z ) { result->z = _z; } static inline vec_float4 vmathSoaV4GetZ( const VmathSoaVector4 *vec ) { return vec->z; } static inline void vmathSoaV4SetW( VmathSoaVector4 *result, vec_float4 _w ) { result->w = _w; } static inline vec_float4 vmathSoaV4GetW( const VmathSoaVector4 *vec ) { return vec->w; } static inline void vmathSoaV4SetElem( VmathSoaVector4 *result, int idx, vec_float4 value ) { *(&result->x + idx) = value; } static inline vec_float4 vmathSoaV4GetElem( const VmathSoaVector4 *vec, int idx ) { return *(&vec->x + idx); } static inline void vmathSoaV4Add( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = vec_add( vec0->x, vec1->x ); result->y = vec_add( vec0->y, vec1->y ); result->z = vec_add( vec0->z, vec1->z ); result->w = vec_add( vec0->w, vec1->w ); } static inline void vmathSoaV4Sub( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = vec_sub( vec0->x, vec1->x ); result->y = vec_sub( vec0->y, vec1->y ); result->z = vec_sub( vec0->z, vec1->z ); result->w = vec_sub( vec0->w, vec1->w ); } static inline void vmathSoaV4ScalarMul( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar ) { result->x = vec_madd( vec->x, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( vec->y, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( vec->z, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->w = vec_madd( vec->w, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaV4ScalarDiv( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar ) { result->x = divf4( vec->x, scalar ); result->y = divf4( vec->y, scalar ); result->z = divf4( vec->z, scalar ); result->w = divf4( vec->w, scalar ); } static inline void vmathSoaV4Neg( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = negatef4( vec->x ); result->y = negatef4( vec->y ); result->z = negatef4( vec->z ); result->w = negatef4( vec->w ); } static inline void vmathSoaV4MulPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = vec_madd( vec0->x, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( vec0->y, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( vec0->z, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->w = vec_madd( vec0->w, vec1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaV4DivPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = divf4( vec0->x, vec1->x ); result->y = divf4( vec0->y, vec1->y ); result->z = divf4( vec0->z, vec1->z ); result->w = divf4( vec0->w, vec1->w ); } static inline void vmathSoaV4RecipPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->x ); result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->y ); result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->z ); result->w = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec->w ); } static inline void vmathSoaV4SqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = sqrtf4( vec->x ); result->y = sqrtf4( vec->y ); result->z = sqrtf4( vec->z ); result->w = sqrtf4( vec->w ); } static inline void vmathSoaV4RsqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->x ) ); result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->y ) ); result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->z ) ); result->w = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec->w ) ); } static inline void vmathSoaV4AbsPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = fabsf4( vec->x ); result->y = fabsf4( vec->y ); result->z = fabsf4( vec->z ); result->w = fabsf4( vec->w ); } static inline void vmathSoaV4CopySignPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = copysignf4( vec0->x, vec1->x ); result->y = copysignf4( vec0->y, vec1->y ); result->z = copysignf4( vec0->z, vec1->z ); result->w = copysignf4( vec0->w, vec1->w ); } static inline void vmathSoaV4MaxPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = fmaxf4( vec0->x, vec1->x ); result->y = fmaxf4( vec0->y, vec1->y ); result->z = fmaxf4( vec0->z, vec1->z ); result->w = fmaxf4( vec0->w, vec1->w ); } static inline vec_float4 vmathSoaV4MaxElem( const VmathSoaVector4 *vec ) { vec_float4 result; result = fmaxf4( vec->x, vec->y ); result = fmaxf4( vec->z, result ); result = fmaxf4( vec->w, result ); return result; } static inline void vmathSoaV4MinPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = fminf4( vec0->x, vec1->x ); result->y = fminf4( vec0->y, vec1->y ); result->z = fminf4( vec0->z, vec1->z ); result->w = fminf4( vec0->w, vec1->w ); } static inline vec_float4 vmathSoaV4MinElem( const VmathSoaVector4 *vec ) { vec_float4 result; result = fminf4( vec->x, vec->y ); result = fminf4( vec->z, result ); result = fminf4( vec->w, result ); return result; } static inline vec_float4 vmathSoaV4Sum( const VmathSoaVector4 *vec ) { vec_float4 result; result = vec_add( vec->x, vec->y ); result = vec_add( result, vec->z ); result = vec_add( result, vec->w ); return result; } static inline vec_float4 vmathSoaV4Dot( const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { vec_float4 result; result = vec_madd( vec0->x, vec1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( vec0->y, vec1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec0->z, vec1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec0->w, vec1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } static inline vec_float4 vmathSoaV4LengthSqr( const VmathSoaVector4 *vec ) { vec_float4 result; result = vec_madd( vec->x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( vec->y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec->z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec->w, vec->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } static inline vec_float4 vmathSoaV4Length( const VmathSoaVector4 *vec ) { return sqrtf4( vmathSoaV4LengthSqr( vec ) ); } static inline void vmathSoaV4Normalize( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { vec_float4 lenSqr, lenInv; lenSqr = vmathSoaV4LengthSqr( vec ); lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) ); result->x = vec_madd( vec->x, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( vec->y, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( vec->z, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->w = vec_madd( vec->w, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaV4Select( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1, vec_uint4 select1 ) { result->x = vec_sel( vec0->x, vec1->x, select1 ); result->y = vec_sel( vec0->y, vec1->y, select1 ); result->z = vec_sel( vec0->z, vec1->z, select1 ); result->w = vec_sel( vec0->w, vec1->w, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaV4Print( const VmathSoaVector4 *vec ) { VmathVector4 vec0, vec1, vec2, vec3; vmathSoaV4Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathV4Print( &vec0 ); printf("slot 1:\n"); vmathV4Print( &vec1 ); printf("slot 2:\n"); vmathV4Print( &vec2 ); printf("slot 3:\n"); vmathV4Print( &vec3 ); } static inline void vmathSoaV4Prints( const VmathSoaVector4 *vec, const char *name ) { VmathVector4 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vmathSoaV4Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathV4Print( &vec0 ); printf("slot 1:\n"); vmathV4Print( &vec1 ); printf("slot 2:\n"); vmathV4Print( &vec2 ); printf("slot 3:\n"); vmathV4Print( &vec3 ); } #endif static inline void vmathSoaP3Copy( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; } static inline void vmathSoaP3MakeFromElems( VmathSoaPoint3 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z ) { result->x = _x; result->y = _y; result->z = _z; } static inline void vmathSoaP3MakeFromV3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathSoaP3MakeFromScalar( VmathSoaPoint3 *result, vec_float4 scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; } static inline void vmathSoaP3MakeFromAos( VmathSoaPoint3 *result, const VmathPoint3 *pnt ) { vec_float4 vec128 = pnt->vec128; result->x = vec_splat( vec128, 0 ); result->y = vec_splat( vec128, 1 ); result->z = vec_splat( vec128, 2 ); } static inline void vmathSoaP3MakeFrom4Aos( VmathSoaPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( pnt0->vec128, pnt2->vec128 ); tmp1 = vec_mergeh( pnt1->vec128, pnt3->vec128 ); tmp2 = vec_mergel( pnt0->vec128, pnt2->vec128 ); tmp3 = vec_mergel( pnt1->vec128, pnt3->vec128 ); result->x = vec_mergeh( tmp0, tmp1 ); result->y = vec_mergel( tmp0, tmp1 ); result->z = vec_mergeh( tmp2, tmp3 ); } static inline void vmathSoaP3Lerp( VmathSoaPoint3 *result, vec_float4 t, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { VmathSoaVector3 tmpV3_0, tmpV3_1; vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 ); vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathSoaP3AddV3( result, pnt0, &tmpV3_1 ); } static inline void vmathSoaP3Get4Aos( const VmathSoaPoint3 *pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 ) { vec_float4 tmp0, tmp1; tmp0 = vec_mergeh( pnt->x, pnt->z ); tmp1 = vec_mergel( pnt->x, pnt->z ); vmathP3MakeFrom128( result0, vec_mergeh( tmp0, pnt->y ) ); vmathP3MakeFrom128( result1, vec_perm( tmp0, pnt->y, _VECTORMATH_PERM_ZBWX ) ); vmathP3MakeFrom128( result2, vec_perm( tmp1, pnt->y, _VECTORMATH_PERM_XCYX ) ); vmathP3MakeFrom128( result3, vec_perm( tmp1, pnt->y, _VECTORMATH_PERM_ZDWX ) ); } static inline void vmathSoaP3LoadXYZArray( VmathSoaPoint3 *vec, const vec_float4 *threeQuads ) { vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyxy = vec_sld( yzxy, xyzx, 8 ); zxzx = vec_sld( xyzx, zxyz, 8 ); yzyz = vec_sld( zxyz, yzxy, 8 ); vmathSoaP3SetX( vec, vec_perm( xyxy, zxzx, _VECTORMATH_PERM_ZBXD ) ); vmathSoaP3SetY( vec, vec_perm( xyxy, yzyz, _VECTORMATH_PERM_WCYA ) ); vmathSoaP3SetZ( vec, vec_perm( zxzx, yzyz, _VECTORMATH_PERM_XDZB ) ); } static inline void vmathSoaP3StoreXYZArray( const VmathSoaPoint3 *vec, vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz; xyxy = vec_perm( vec->x, vec->y, _VECTORMATH_PERM_ZCXA ); zxzx = vec_perm( vec->z, vec->x, _VECTORMATH_PERM_XBZD ); yzyz = vec_perm( vec->y, vec->z, _VECTORMATH_PERM_WDYB ); xyzx = vec_sld( xyxy, zxzx, 8 ); yzxy = vec_sld( yzyz, xyxy, 8 ); zxyz = vec_sld( zxzx, yzyz, 8 ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } static inline void vmathSoaP3StoreHalfFloats( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_ushort8 *threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; vmathSoaP3StoreXYZArray( pnt0, xyz0 ); vmathSoaP3StoreXYZArray( pnt1, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } static inline void vmathSoaP3SetX( VmathSoaPoint3 *result, vec_float4 _x ) { result->x = _x; } static inline vec_float4 vmathSoaP3GetX( const VmathSoaPoint3 *pnt ) { return pnt->x; } static inline void vmathSoaP3SetY( VmathSoaPoint3 *result, vec_float4 _y ) { result->y = _y; } static inline vec_float4 vmathSoaP3GetY( const VmathSoaPoint3 *pnt ) { return pnt->y; } static inline void vmathSoaP3SetZ( VmathSoaPoint3 *result, vec_float4 _z ) { result->z = _z; } static inline vec_float4 vmathSoaP3GetZ( const VmathSoaPoint3 *pnt ) { return pnt->z; } static inline void vmathSoaP3SetElem( VmathSoaPoint3 *result, int idx, vec_float4 value ) { *(&result->x + idx) = value; } static inline vec_float4 vmathSoaP3GetElem( const VmathSoaPoint3 *pnt, int idx ) { return *(&pnt->x + idx); } static inline void vmathSoaP3Sub( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = vec_sub( pnt0->x, pnt1->x ); result->y = vec_sub( pnt0->y, pnt1->y ); result->z = vec_sub( pnt0->z, pnt1->z ); } static inline void vmathSoaP3AddV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec1 ) { result->x = vec_add( pnt->x, vec1->x ); result->y = vec_add( pnt->y, vec1->y ); result->z = vec_add( pnt->z, vec1->z ); } static inline void vmathSoaP3SubV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec1 ) { result->x = vec_sub( pnt->x, vec1->x ); result->y = vec_sub( pnt->y, vec1->y ); result->z = vec_sub( pnt->z, vec1->z ); } static inline void vmathSoaP3MulPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = vec_madd( pnt0->x, pnt1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->y = vec_madd( pnt0->y, pnt1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result->z = vec_madd( pnt0->z, pnt1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); } static inline void vmathSoaP3DivPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = divf4( pnt0->x, pnt1->x ); result->y = divf4( pnt0->y, pnt1->y ); result->z = divf4( pnt0->z, pnt1->z ); } static inline void vmathSoaP3RecipPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt->x ); result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt->y ); result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt->z ); } static inline void vmathSoaP3SqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = sqrtf4( pnt->x ); result->y = sqrtf4( pnt->y ); result->z = sqrtf4( pnt->z ); } static inline void vmathSoaP3RsqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt->x ) ); result->y = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt->y ) ); result->z = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt->z ) ); } static inline void vmathSoaP3AbsPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = fabsf4( pnt->x ); result->y = fabsf4( pnt->y ); result->z = fabsf4( pnt->z ); } static inline void vmathSoaP3CopySignPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = copysignf4( pnt0->x, pnt1->x ); result->y = copysignf4( pnt0->y, pnt1->y ); result->z = copysignf4( pnt0->z, pnt1->z ); } static inline void vmathSoaP3MaxPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = fmaxf4( pnt0->x, pnt1->x ); result->y = fmaxf4( pnt0->y, pnt1->y ); result->z = fmaxf4( pnt0->z, pnt1->z ); } static inline vec_float4 vmathSoaP3MaxElem( const VmathSoaPoint3 *pnt ) { vec_float4 result; result = fmaxf4( pnt->x, pnt->y ); result = fmaxf4( pnt->z, result ); return result; } static inline void vmathSoaP3MinPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = fminf4( pnt0->x, pnt1->x ); result->y = fminf4( pnt0->y, pnt1->y ); result->z = fminf4( pnt0->z, pnt1->z ); } static inline vec_float4 vmathSoaP3MinElem( const VmathSoaPoint3 *pnt ) { vec_float4 result; result = fminf4( pnt->x, pnt->y ); result = fminf4( pnt->z, result ); return result; } static inline vec_float4 vmathSoaP3Sum( const VmathSoaPoint3 *pnt ) { vec_float4 result; result = vec_add( pnt->x, pnt->y ); result = vec_add( result, pnt->z ); return result; } static inline void vmathSoaP3Scale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, vec_float4 scaleVal ) { VmathSoaPoint3 tmpP3_0; vmathSoaP3MakeFromScalar( &tmpP3_0, scaleVal ); vmathSoaP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline void vmathSoaP3NonUniformScale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *scaleVec ) { VmathSoaPoint3 tmpP3_0; vmathSoaP3MakeFromV3( &tmpP3_0, scaleVec ); vmathSoaP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline vec_float4 vmathSoaP3Projection( const VmathSoaPoint3 *pnt, const VmathSoaVector3 *unitVec ) { vec_float4 result; result = vec_madd( pnt->x, unitVec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( pnt->y, unitVec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( pnt->z, unitVec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } static inline vec_float4 vmathSoaP3DistSqrFromOrigin( const VmathSoaPoint3 *pnt ) { VmathSoaVector3 tmpV3_0; vmathSoaV3MakeFromP3( &tmpV3_0, pnt ); return vmathSoaV3LengthSqr( &tmpV3_0 ); } static inline vec_float4 vmathSoaP3DistFromOrigin( const VmathSoaPoint3 *pnt ) { VmathSoaVector3 tmpV3_0; vmathSoaV3MakeFromP3( &tmpV3_0, pnt ); return vmathSoaV3Length( &tmpV3_0 ); } static inline vec_float4 vmathSoaP3DistSqr( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { VmathSoaVector3 tmpV3_0; vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathSoaV3LengthSqr( &tmpV3_0 ); } static inline vec_float4 vmathSoaP3Dist( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { VmathSoaVector3 tmpV3_0; vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathSoaV3Length( &tmpV3_0 ); } static inline void vmathSoaP3Select( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_uint4 select1 ) { result->x = vec_sel( pnt0->x, pnt1->x, select1 ); result->y = vec_sel( pnt0->y, pnt1->y, select1 ); result->z = vec_sel( pnt0->z, pnt1->z, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaP3Print( const VmathSoaPoint3 *pnt ) { VmathPoint3 vec0, vec1, vec2, vec3; vmathSoaP3Get4Aos( pnt, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathP3Print( &vec0 ); printf("slot 1:\n"); vmathP3Print( &vec1 ); printf("slot 2:\n"); vmathP3Print( &vec2 ); printf("slot 3:\n"); vmathP3Print( &vec3 ); } static inline void vmathSoaP3Prints( const VmathSoaPoint3 *pnt, const char *name ) { VmathPoint3 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vmathSoaP3Get4Aos( pnt, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathP3Print( &vec0 ); printf("slot 1:\n"); vmathP3Print( &vec1 ); printf("slot 2:\n"); vmathP3Print( &vec2 ); printf("slot 3:\n"); vmathP3Print( &vec3 ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/vec_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_SOA_V_C_H #define _VECTORMATH_VEC_SOA_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for permutes, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_PERM_X 0x00010203 #define _VECTORMATH_PERM_Y 0x04050607 #define _VECTORMATH_PERM_Z 0x08090a0b #define _VECTORMATH_PERM_W 0x0c0d0e0f #define _VECTORMATH_PERM_A 0x10111213 #define _VECTORMATH_PERM_B 0x14151617 #define _VECTORMATH_PERM_C 0x18191a1b #define _VECTORMATH_PERM_D 0x1c1d1e1f #define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_ZDWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_ZCXA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_XBZD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_WDYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_WCYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B }) #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathSoaVector3 vmathSoaV3MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z ) { VmathSoaVector3 result; vmathSoaV3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathSoaVector3 vmathSoaV3MakeFromP3_V( VmathSoaPoint3 pnt ) { VmathSoaVector3 result; vmathSoaV3MakeFromP3(&result, &pnt); return result; } static inline VmathSoaVector3 vmathSoaV3MakeFromScalar_V( vec_float4 scalar ) { VmathSoaVector3 result; vmathSoaV3MakeFromScalar(&result, scalar); return result; } static inline VmathSoaVector3 vmathSoaV3MakeFromAos_V( VmathVector3 vec ) { VmathSoaVector3 result; vmathSoaV3MakeFromAos(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3MakeFrom4Aos_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3 ) { VmathSoaVector3 result; vmathSoaV3MakeFrom4Aos(&result, &vec0, &vec1, &vec2, &vec3); return result; } static inline VmathSoaVector3 vmathSoaV3MakeXAxis_V( ) { VmathSoaVector3 result; vmathSoaV3MakeXAxis(&result); return result; } static inline VmathSoaVector3 vmathSoaV3MakeYAxis_V( ) { VmathSoaVector3 result; vmathSoaV3MakeYAxis(&result); return result; } static inline VmathSoaVector3 vmathSoaV3MakeZAxis_V( ) { VmathSoaVector3 result; vmathSoaV3MakeZAxis(&result); return result; } static inline VmathSoaVector3 vmathSoaV3Lerp_V( vec_float4 t, VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3Slerp_V( vec_float4 t, VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 ) { VmathSoaVector3 result; vmathSoaV3Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline void vmathSoaV3Get4Aos_V( VmathSoaVector3 vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 ) { vmathSoaV3Get4Aos(&vec, result0, result1, result2, result3); } static inline void vmathSoaV3LoadXYZArray_V( VmathSoaVector3 *vec, const vec_float4 *threeQuads ) { vmathSoaV3LoadXYZArray(vec, threeQuads); } static inline void vmathSoaV3StoreXYZArray_V( VmathSoaVector3 vec, vec_float4 *threeQuads ) { vmathSoaV3StoreXYZArray(&vec, threeQuads); } static inline void vmathSoaV3StoreHalfFloats_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_ushort8 *threeQuads ) { vmathSoaV3StoreHalfFloats(&vec0, &vec1, threeQuads); } static inline void vmathSoaV3SetX_V( VmathSoaVector3 *result, vec_float4 _x ) { vmathSoaV3SetX(result, _x); } static inline vec_float4 vmathSoaV3GetX_V( VmathSoaVector3 vec ) { return vmathSoaV3GetX(&vec); } static inline void vmathSoaV3SetY_V( VmathSoaVector3 *result, vec_float4 _y ) { vmathSoaV3SetY(result, _y); } static inline vec_float4 vmathSoaV3GetY_V( VmathSoaVector3 vec ) { return vmathSoaV3GetY(&vec); } static inline void vmathSoaV3SetZ_V( VmathSoaVector3 *result, vec_float4 _z ) { vmathSoaV3SetZ(result, _z); } static inline vec_float4 vmathSoaV3GetZ_V( VmathSoaVector3 vec ) { return vmathSoaV3GetZ(&vec); } static inline void vmathSoaV3SetElem_V( VmathSoaVector3 *result, int idx, vec_float4 value ) { vmathSoaV3SetElem(result, idx, value); } static inline vec_float4 vmathSoaV3GetElem_V( VmathSoaVector3 vec, int idx ) { return vmathSoaV3GetElem(&vec, idx); } static inline VmathSoaVector3 vmathSoaV3Add_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3Add(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3Sub_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3Sub(&result, &vec0, &vec1); return result; } static inline VmathSoaPoint3 vmathSoaV3AddP3_V( VmathSoaVector3 vec, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaV3AddP3(&result, &vec, &pnt1); return result; } static inline VmathSoaVector3 vmathSoaV3ScalarMul_V( VmathSoaVector3 vec, vec_float4 scalar ) { VmathSoaVector3 result; vmathSoaV3ScalarMul(&result, &vec, scalar); return result; } static inline VmathSoaVector3 vmathSoaV3ScalarDiv_V( VmathSoaVector3 vec, vec_float4 scalar ) { VmathSoaVector3 result; vmathSoaV3ScalarDiv(&result, &vec, scalar); return result; } static inline VmathSoaVector3 vmathSoaV3Neg_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3Neg(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3MulPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3DivPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3RecipPerElem_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3RecipPerElem(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3SqrtPerElem_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3SqrtPerElem(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3RsqrtPerElem_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3RsqrtPerElem(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3AbsPerElem_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3AbsPerElem(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3CopySignPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3MaxPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3MaxPerElem(&result, &vec0, &vec1); return result; } static inline vec_float4 vmathSoaV3MaxElem_V( VmathSoaVector3 vec ) { return vmathSoaV3MaxElem(&vec); } static inline VmathSoaVector3 vmathSoaV3MinPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3MinPerElem(&result, &vec0, &vec1); return result; } static inline vec_float4 vmathSoaV3MinElem_V( VmathSoaVector3 vec ) { return vmathSoaV3MinElem(&vec); } static inline vec_float4 vmathSoaV3Sum_V( VmathSoaVector3 vec ) { return vmathSoaV3Sum(&vec); } static inline vec_float4 vmathSoaV3Dot_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { return vmathSoaV3Dot(&vec0, &vec1); } static inline vec_float4 vmathSoaV3LengthSqr_V( VmathSoaVector3 vec ) { return vmathSoaV3LengthSqr(&vec); } static inline vec_float4 vmathSoaV3Length_V( VmathSoaVector3 vec ) { return vmathSoaV3Length(&vec); } static inline VmathSoaVector3 vmathSoaV3Normalize_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3Normalize(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3Cross_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3Cross(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3Select_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_uint4 select1 ) { VmathSoaVector3 result; vmathSoaV3Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaV3Print_V( VmathSoaVector3 vec ) { vmathSoaV3Print(&vec); } static inline void vmathSoaV3Prints_V( VmathSoaVector3 vec, const char *name ) { vmathSoaV3Prints(&vec, name); } #endif static inline VmathSoaVector4 vmathSoaV4MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { VmathSoaVector4 result; vmathSoaV4MakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 _w ) { VmathSoaVector4 result; vmathSoaV4MakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromV3_V( VmathSoaVector3 vec ) { VmathSoaVector4 result; vmathSoaV4MakeFromV3(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromP3_V( VmathSoaPoint3 pnt ) { VmathSoaVector4 result; vmathSoaV4MakeFromP3(&result, &pnt); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromQ_V( VmathSoaQuat quat ) { VmathSoaVector4 result; vmathSoaV4MakeFromQ(&result, &quat); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromScalar_V( vec_float4 scalar ) { VmathSoaVector4 result; vmathSoaV4MakeFromScalar(&result, scalar); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromAos_V( VmathVector4 vec ) { VmathSoaVector4 result; vmathSoaV4MakeFromAos(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFrom4Aos_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3 ) { VmathSoaVector4 result; vmathSoaV4MakeFrom4Aos(&result, &vec0, &vec1, &vec2, &vec3); return result; } static inline VmathSoaVector4 vmathSoaV4MakeXAxis_V( ) { VmathSoaVector4 result; vmathSoaV4MakeXAxis(&result); return result; } static inline VmathSoaVector4 vmathSoaV4MakeYAxis_V( ) { VmathSoaVector4 result; vmathSoaV4MakeYAxis(&result); return result; } static inline VmathSoaVector4 vmathSoaV4MakeZAxis_V( ) { VmathSoaVector4 result; vmathSoaV4MakeZAxis(&result); return result; } static inline VmathSoaVector4 vmathSoaV4MakeWAxis_V( ) { VmathSoaVector4 result; vmathSoaV4MakeWAxis(&result); return result; } static inline VmathSoaVector4 vmathSoaV4Lerp_V( vec_float4 t, VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4Slerp_V( vec_float4 t, VmathSoaVector4 unitVec0, VmathSoaVector4 unitVec1 ) { VmathSoaVector4 result; vmathSoaV4Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline void vmathSoaV4Get4Aos_V( VmathSoaVector4 vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 ) { vmathSoaV4Get4Aos(&vec, result0, result1, result2, result3); } static inline void vmathSoaV4StoreHalfFloats_V( VmathSoaVector4 vec, vec_ushort8 *twoQuads ) { vmathSoaV4StoreHalfFloats(&vec, twoQuads); } static inline void vmathSoaV4SetXYZ_V( VmathSoaVector4 *result, VmathSoaVector3 vec ) { vmathSoaV4SetXYZ(result, &vec); } static inline VmathSoaVector3 vmathSoaV4GetXYZ_V( VmathSoaVector4 vec ) { VmathSoaVector3 result; vmathSoaV4GetXYZ(&result, &vec); return result; } static inline void vmathSoaV4SetX_V( VmathSoaVector4 *result, vec_float4 _x ) { vmathSoaV4SetX(result, _x); } static inline vec_float4 vmathSoaV4GetX_V( VmathSoaVector4 vec ) { return vmathSoaV4GetX(&vec); } static inline void vmathSoaV4SetY_V( VmathSoaVector4 *result, vec_float4 _y ) { vmathSoaV4SetY(result, _y); } static inline vec_float4 vmathSoaV4GetY_V( VmathSoaVector4 vec ) { return vmathSoaV4GetY(&vec); } static inline void vmathSoaV4SetZ_V( VmathSoaVector4 *result, vec_float4 _z ) { vmathSoaV4SetZ(result, _z); } static inline vec_float4 vmathSoaV4GetZ_V( VmathSoaVector4 vec ) { return vmathSoaV4GetZ(&vec); } static inline void vmathSoaV4SetW_V( VmathSoaVector4 *result, vec_float4 _w ) { vmathSoaV4SetW(result, _w); } static inline vec_float4 vmathSoaV4GetW_V( VmathSoaVector4 vec ) { return vmathSoaV4GetW(&vec); } static inline void vmathSoaV4SetElem_V( VmathSoaVector4 *result, int idx, vec_float4 value ) { vmathSoaV4SetElem(result, idx, value); } static inline vec_float4 vmathSoaV4GetElem_V( VmathSoaVector4 vec, int idx ) { return vmathSoaV4GetElem(&vec, idx); } static inline VmathSoaVector4 vmathSoaV4Add_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4Add(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4Sub_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4Sub(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4ScalarMul_V( VmathSoaVector4 vec, vec_float4 scalar ) { VmathSoaVector4 result; vmathSoaV4ScalarMul(&result, &vec, scalar); return result; } static inline VmathSoaVector4 vmathSoaV4ScalarDiv_V( VmathSoaVector4 vec, vec_float4 scalar ) { VmathSoaVector4 result; vmathSoaV4ScalarDiv(&result, &vec, scalar); return result; } static inline VmathSoaVector4 vmathSoaV4Neg_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4Neg(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4MulPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4DivPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4RecipPerElem_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4RecipPerElem(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4SqrtPerElem_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4SqrtPerElem(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4RsqrtPerElem_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4RsqrtPerElem(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4AbsPerElem_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4AbsPerElem(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4CopySignPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4MaxPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4MaxPerElem(&result, &vec0, &vec1); return result; } static inline vec_float4 vmathSoaV4MaxElem_V( VmathSoaVector4 vec ) { return vmathSoaV4MaxElem(&vec); } static inline VmathSoaVector4 vmathSoaV4MinPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4MinPerElem(&result, &vec0, &vec1); return result; } static inline vec_float4 vmathSoaV4MinElem_V( VmathSoaVector4 vec ) { return vmathSoaV4MinElem(&vec); } static inline vec_float4 vmathSoaV4Sum_V( VmathSoaVector4 vec ) { return vmathSoaV4Sum(&vec); } static inline vec_float4 vmathSoaV4Dot_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { return vmathSoaV4Dot(&vec0, &vec1); } static inline vec_float4 vmathSoaV4LengthSqr_V( VmathSoaVector4 vec ) { return vmathSoaV4LengthSqr(&vec); } static inline vec_float4 vmathSoaV4Length_V( VmathSoaVector4 vec ) { return vmathSoaV4Length(&vec); } static inline VmathSoaVector4 vmathSoaV4Normalize_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4Normalize(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4Select_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1, vec_uint4 select1 ) { VmathSoaVector4 result; vmathSoaV4Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaV4Print_V( VmathSoaVector4 vec ) { vmathSoaV4Print(&vec); } static inline void vmathSoaV4Prints_V( VmathSoaVector4 vec, const char *name ) { vmathSoaV4Prints(&vec, name); } #endif static inline VmathSoaPoint3 vmathSoaP3MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z ) { VmathSoaPoint3 result; vmathSoaP3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathSoaPoint3 vmathSoaP3MakeFromV3_V( VmathSoaVector3 vec ) { VmathSoaPoint3 result; vmathSoaP3MakeFromV3(&result, &vec); return result; } static inline VmathSoaPoint3 vmathSoaP3MakeFromScalar_V( vec_float4 scalar ) { VmathSoaPoint3 result; vmathSoaP3MakeFromScalar(&result, scalar); return result; } static inline VmathSoaPoint3 vmathSoaP3MakeFromAos_V( VmathPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3MakeFromAos(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3MakeFrom4Aos_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3 ) { VmathSoaPoint3 result; vmathSoaP3MakeFrom4Aos(&result, &pnt0, &pnt1, &pnt2, &pnt3); return result; } static inline VmathSoaPoint3 vmathSoaP3Lerp_V( vec_float4 t, VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3Lerp(&result, t, &pnt0, &pnt1); return result; } static inline void vmathSoaP3Get4Aos_V( VmathSoaPoint3 pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 ) { vmathSoaP3Get4Aos(&pnt, result0, result1, result2, result3); } static inline void vmathSoaP3LoadXYZArray_V( VmathSoaPoint3 *vec, const vec_float4 *threeQuads ) { vmathSoaP3LoadXYZArray(vec, threeQuads); } static inline void vmathSoaP3StoreXYZArray_V( VmathSoaPoint3 vec, vec_float4 *threeQuads ) { vmathSoaP3StoreXYZArray(&vec, threeQuads); } static inline void vmathSoaP3StoreHalfFloats_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_ushort8 *threeQuads ) { vmathSoaP3StoreHalfFloats(&pnt0, &pnt1, threeQuads); } static inline void vmathSoaP3SetX_V( VmathSoaPoint3 *result, vec_float4 _x ) { vmathSoaP3SetX(result, _x); } static inline vec_float4 vmathSoaP3GetX_V( VmathSoaPoint3 pnt ) { return vmathSoaP3GetX(&pnt); } static inline void vmathSoaP3SetY_V( VmathSoaPoint3 *result, vec_float4 _y ) { vmathSoaP3SetY(result, _y); } static inline vec_float4 vmathSoaP3GetY_V( VmathSoaPoint3 pnt ) { return vmathSoaP3GetY(&pnt); } static inline void vmathSoaP3SetZ_V( VmathSoaPoint3 *result, vec_float4 _z ) { vmathSoaP3SetZ(result, _z); } static inline vec_float4 vmathSoaP3GetZ_V( VmathSoaPoint3 pnt ) { return vmathSoaP3GetZ(&pnt); } static inline void vmathSoaP3SetElem_V( VmathSoaPoint3 *result, int idx, vec_float4 value ) { vmathSoaP3SetElem(result, idx, value); } static inline vec_float4 vmathSoaP3GetElem_V( VmathSoaPoint3 pnt, int idx ) { return vmathSoaP3GetElem(&pnt, idx); } static inline VmathSoaVector3 vmathSoaP3Sub_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaVector3 result; vmathSoaP3Sub(&result, &pnt0, &pnt1); return result; } static inline VmathSoaPoint3 vmathSoaP3AddV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec1 ) { VmathSoaPoint3 result; vmathSoaP3AddV3(&result, &pnt, &vec1); return result; } static inline VmathSoaPoint3 vmathSoaP3SubV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec1 ) { VmathSoaPoint3 result; vmathSoaP3SubV3(&result, &pnt, &vec1); return result; } static inline VmathSoaPoint3 vmathSoaP3MulPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3MulPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathSoaPoint3 vmathSoaP3DivPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3DivPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathSoaPoint3 vmathSoaP3RecipPerElem_V( VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3RecipPerElem(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3SqrtPerElem_V( VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3SqrtPerElem(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3RsqrtPerElem_V( VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3RsqrtPerElem(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3AbsPerElem_V( VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3AbsPerElem(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3CopySignPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3CopySignPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathSoaPoint3 vmathSoaP3MaxPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3MaxPerElem(&result, &pnt0, &pnt1); return result; } static inline vec_float4 vmathSoaP3MaxElem_V( VmathSoaPoint3 pnt ) { return vmathSoaP3MaxElem(&pnt); } static inline VmathSoaPoint3 vmathSoaP3MinPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3MinPerElem(&result, &pnt0, &pnt1); return result; } static inline vec_float4 vmathSoaP3MinElem_V( VmathSoaPoint3 pnt ) { return vmathSoaP3MinElem(&pnt); } static inline vec_float4 vmathSoaP3Sum_V( VmathSoaPoint3 pnt ) { return vmathSoaP3Sum(&pnt); } static inline VmathSoaPoint3 vmathSoaP3Scale_V( VmathSoaPoint3 pnt, vec_float4 scaleVal ) { VmathSoaPoint3 result; vmathSoaP3Scale(&result, &pnt, scaleVal); return result; } static inline VmathSoaPoint3 vmathSoaP3NonUniformScale_V( VmathSoaPoint3 pnt, VmathSoaVector3 scaleVec ) { VmathSoaPoint3 result; vmathSoaP3NonUniformScale(&result, &pnt, &scaleVec); return result; } static inline vec_float4 vmathSoaP3Projection_V( VmathSoaPoint3 pnt, VmathSoaVector3 unitVec ) { return vmathSoaP3Projection(&pnt, &unitVec); } static inline vec_float4 vmathSoaP3DistSqrFromOrigin_V( VmathSoaPoint3 pnt ) { return vmathSoaP3DistSqrFromOrigin(&pnt); } static inline vec_float4 vmathSoaP3DistFromOrigin_V( VmathSoaPoint3 pnt ) { return vmathSoaP3DistFromOrigin(&pnt); } static inline vec_float4 vmathSoaP3DistSqr_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { return vmathSoaP3DistSqr(&pnt0, &pnt1); } static inline vec_float4 vmathSoaP3Dist_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { return vmathSoaP3Dist(&pnt0, &pnt1); } static inline VmathSoaPoint3 vmathSoaP3Select_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_uint4 select1 ) { VmathSoaPoint3 result; vmathSoaP3Select(&result, &pnt0, &pnt1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaP3Print_V( VmathSoaPoint3 pnt ) { vmathSoaP3Print(&pnt); } static inline void vmathSoaP3Prints_V( VmathSoaPoint3 pnt, const char *name ) { vmathSoaP3Prints(&pnt, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/ppu/c/vec_types.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Single token vector data types for the PowerPC SIMD/Vector Multi-media eXtension */ #ifndef _VEC_TYPES_H_ #define _VEC_TYPES_H_ 1 #define qword vector unsigned char #define vec_uchar16 vector unsigned char #define vec_char16 vector signed char #define vec_bchar16 vector bool char #define vec_ushort8 vector unsigned short #define vec_short8 vector signed short #define vec_bshort8 vector bool short #define vec_pixel8 vector pixel #define vec_uint4 vector unsigned int #define vec_int4 vector signed int #define vec_bint4 vector bool int #define vec_float4 vector float #define vec_ullong2 vector bool char #define vec_llong2 vector bool short #define vec_double2 vector bool int #endif /* _VEC_TYPES_H_ */ ================================================ FILE: samples/vectormath/ppu/c/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_C_PPU_H #define _VECTORMATH_AOS_C_PPU_H #include #include #include #include "vec_types.h" #ifdef _VECTORMATH_DEBUG #include #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_AOS_C_TYPES_H #define _VECTORMATH_AOS_C_TYPES_H /* A 3-D vector in array-of-structures format */ typedef struct _VmathVector3 { vec_float4 vec128; } VmathVector3; /* A 4-D vector in array-of-structures format */ typedef struct _VmathVector4 { vec_float4 vec128; } VmathVector4; /* A 3-D point in array-of-structures format */ typedef struct _VmathPoint3 { vec_float4 vec128; } VmathPoint3; /* A quaternion in array-of-structures format */ typedef struct _VmathQuat { vec_float4 vec128; } VmathQuat; /* A 3x3 matrix in array-of-structures format */ typedef struct _VmathMatrix3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; } VmathMatrix3; /* A 4x4 matrix in array-of-structures format */ typedef struct _VmathMatrix4 { VmathVector4 col0; VmathVector4 col1; VmathVector4 col2; VmathVector4 col3; } VmathMatrix4; /* A 3x4 transformation matrix in array-of-structures format */ typedef struct _VmathTransform3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; VmathVector3 col3; } VmathTransform3; #endif /* * Copy a 3-D vector */ static inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec ); /* * Construct a 3-D vector from x, y, and z elements */ static inline void vmathV3MakeFromElems( VmathVector3 *result, float x, float y, float z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar ); /* * Set vector float data in a 3-D vector */ static inline void vmathV3MakeFrom128( VmathVector3 *result, vec_float4 vf4 ); /* * Get vector float data from a 3-D vector */ static inline vec_float4 vmathV3Get128( const VmathVector3 *vec ); /* * Set the x element of a 3-D vector */ static inline void vmathV3SetX( VmathVector3 *result, float x ); /* * Set the y element of a 3-D vector */ static inline void vmathV3SetY( VmathVector3 *result, float y ); /* * Set the z element of a 3-D vector */ static inline void vmathV3SetZ( VmathVector3 *result, float z ); /* * Get the x element of a 3-D vector */ static inline float vmathV3GetX( const VmathVector3 *vec ); /* * Get the y element of a 3-D vector */ static inline float vmathV3GetY( const VmathVector3 *vec ); /* * Get the z element of a 3-D vector */ static inline float vmathV3GetZ( const VmathVector3 *vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathV3SetElem( VmathVector3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline float vmathV3GetElem( const VmathVector3 *vec, int idx ); /* * Add two 3-D vectors */ static inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt ); /* * Multiply a 3-D vector by a scalar */ static inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar ); /* * Divide a 3-D vector by a scalar */ static inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar ); /* * Negate all elements of a 3-D vector */ static inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec ); /* * Construct x axis */ static inline void vmathV3MakeXAxis( VmathVector3 *result ); /* * Construct y axis */ static inline void vmathV3MakeYAxis( VmathVector3 *result ); /* * Construct z axis */ static inline void vmathV3MakeZAxis( VmathVector3 *result ); /* * Multiply two 3-D vectors per element */ static inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Maximum of two 3-D vectors per element */ static inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Minimum of two 3-D vectors per element */ static inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Maximum element of a 3-D vector */ static inline float vmathV3MaxElem( const VmathVector3 *vec ); /* * Minimum element of a 3-D vector */ static inline float vmathV3MinElem( const VmathVector3 *vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline float vmathV3Sum( const VmathVector3 *vec ); /* * Compute the dot product of two 3-D vectors */ static inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline float vmathV3LengthSqr( const VmathVector3 *vec ); /* * Compute the length of a 3-D vector */ static inline float vmathV3Length( const VmathVector3 *vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute cross product of two 3-D vectors */ static inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Outer product of two 3-D vectors */ static inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix * NOTE: * Slower than column post-multiply. */ static inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ); /* * Cross-product matrix of a 3-D vector */ static inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ); /* * Conditionally select between two 3-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 ); /* * Store x, y, and z elements of a 3-D vector in the first three words of a quadword. * The value of the fourth word (the word with the highest address) remains unchanged */ static inline void vmathV3StoreXYZ( const VmathVector3 *vec, vec_float4 *quad ); /* * Load four three-float 3-D vectors, stored in three quadwords */ static inline void vmathV3LoadXYZArray( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads ); /* * Store four 3-D vectors in three quadwords */ static inline void vmathV3StoreXYZArray( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, vec_float4 *threeQuads ); /* * Store eight 3-D vectors as half-floats */ static 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 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Print( const VmathVector3 *vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Prints( const VmathVector3 *vec, const char *name ); #endif /* * Copy a 4-D vector */ static inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec ); /* * Construct a 4-D vector from x, y, z, and w elements */ static inline void vmathV4MakeFromElems( VmathVector4 *result, float x, float y, float z, float w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar ); /* * Set vector float data in a 4-D vector */ static inline void vmathV4MakeFrom128( VmathVector4 *result, vec_float4 vf4 ); /* * Get vector float data from a 4-D vector */ static inline vec_float4 vmathV4Get128( const VmathVector4 *vec ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec ); /* * Set the x element of a 4-D vector */ static inline void vmathV4SetX( VmathVector4 *result, float x ); /* * Set the y element of a 4-D vector */ static inline void vmathV4SetY( VmathVector4 *result, float y ); /* * Set the z element of a 4-D vector */ static inline void vmathV4SetZ( VmathVector4 *result, float z ); /* * Set the w element of a 4-D vector */ static inline void vmathV4SetW( VmathVector4 *result, float w ); /* * Get the x element of a 4-D vector */ static inline float vmathV4GetX( const VmathVector4 *vec ); /* * Get the y element of a 4-D vector */ static inline float vmathV4GetY( const VmathVector4 *vec ); /* * Get the z element of a 4-D vector */ static inline float vmathV4GetZ( const VmathVector4 *vec ); /* * Get the w element of a 4-D vector */ static inline float vmathV4GetW( const VmathVector4 *vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathV4SetElem( VmathVector4 *result, int idx, float value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline float vmathV4GetElem( const VmathVector4 *vec, int idx ); /* * Add two 4-D vectors */ static inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar ); /* * Divide a 4-D vector by a scalar */ static inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar ); /* * Negate all elements of a 4-D vector */ static inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec ); /* * Construct x axis */ static inline void vmathV4MakeXAxis( VmathVector4 *result ); /* * Construct y axis */ static inline void vmathV4MakeYAxis( VmathVector4 *result ); /* * Construct z axis */ static inline void vmathV4MakeZAxis( VmathVector4 *result ); /* * Construct w axis */ static inline void vmathV4MakeWAxis( VmathVector4 *result ); /* * Multiply two 4-D vectors per element */ static inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Maximum of two 4-D vectors per element */ static inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Minimum of two 4-D vectors per element */ static inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Maximum element of a 4-D vector */ static inline float vmathV4MaxElem( const VmathVector4 *vec ); /* * Minimum element of a 4-D vector */ static inline float vmathV4MinElem( const VmathVector4 *vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline float vmathV4Sum( const VmathVector4 *vec ); /* * Compute the dot product of two 4-D vectors */ static inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline float vmathV4LengthSqr( const VmathVector4 *vec ); /* * Compute the length of a 4-D vector */ static inline float vmathV4Length( const VmathVector4 *vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec ); /* * Outer product of two 4-D vectors */ static inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 ); /* * Conditionally select between two 4-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 ); /* * Store four 4-D vectors as half-floats */ static inline void vmathV4StoreHalfFloats( const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3, vec_ushort8 *twoQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Print( const VmathVector4 *vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Prints( const VmathVector4 *vec, const char *name ); #endif /* * Copy a 3-D point */ static inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Construct a 3-D point from x, y, and z elements */ static inline void vmathP3MakeFromElems( VmathPoint3 *result, float x, float y, float z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar ); /* * Set vector float data in a 3-D point */ static inline void vmathP3MakeFrom128( VmathPoint3 *result, vec_float4 vf4 ); /* * Get vector float data from a 3-D point */ static inline vec_float4 vmathP3Get128( const VmathPoint3 *pnt ); /* * Set the x element of a 3-D point */ static inline void vmathP3SetX( VmathPoint3 *result, float x ); /* * Set the y element of a 3-D point */ static inline void vmathP3SetY( VmathPoint3 *result, float y ); /* * Set the z element of a 3-D point */ static inline void vmathP3SetZ( VmathPoint3 *result, float z ); /* * Get the x element of a 3-D point */ static inline float vmathP3GetX( const VmathPoint3 *pnt ); /* * Get the y element of a 3-D point */ static inline float vmathP3GetY( const VmathPoint3 *pnt ); /* * Get the z element of a 3-D point */ static inline float vmathP3GetZ( const VmathPoint3 *pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec ); /* * Multiply two 3-D points per element */ static inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Maximum of two 3-D points per element */ static inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Minimum of two 3-D points per element */ static inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Maximum element of a 3-D point */ static inline float vmathP3MaxElem( const VmathPoint3 *pnt ); /* * Minimum element of a 3-D point */ static inline float vmathP3MinElem( const VmathPoint3 *pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline float vmathP3Sum( const VmathPoint3 *pnt ); /* * Apply uniform scale to a 3-D point */ static inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt ); /* * Compute the square of the distance between two 3-D points */ static inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Compute the distance between two 3-D points */ static inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Conditionally select between two 3-D points * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 ); /* * Store x, y, and z elements of a 3-D point in the first three words of a quadword. * The value of the fourth word (the word with the highest address) remains unchanged */ static inline void vmathP3StoreXYZ( const VmathPoint3 *pnt, vec_float4 *quad ); /* * Load four three-float 3-D points, stored in three quadwords */ static inline void vmathP3LoadXYZArray( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads ); /* * Store four 3-D points in three quadwords */ static inline void vmathP3StoreXYZArray( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, vec_float4 *threeQuads ); /* * Store eight 3-D points as half-floats */ static 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 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Print( const VmathPoint3 *pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name ); #endif /* * Copy a quaternion */ static inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat ); /* * Construct a quaternion from x, y, z, and w elements */ static inline void vmathQMakeFromElems( VmathQuat *result, float x, float y, float z, float w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline void vmathQMakeFromScalar( VmathQuat *result, float scalar ); /* * Set vector float data in a quaternion */ static inline void vmathQMakeFrom128( VmathQuat *result, vec_float4 vf4 ); /* * Get vector float data from a quaternion */ static inline vec_float4 vmathQGet128( const VmathQuat *quat ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec ); /* * Get the x, y, and z elements of a quaternion */ static inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat ); /* * Set the x element of a quaternion */ static inline void vmathQSetX( VmathQuat *result, float x ); /* * Set the y element of a quaternion */ static inline void vmathQSetY( VmathQuat *result, float y ); /* * Set the z element of a quaternion */ static inline void vmathQSetZ( VmathQuat *result, float z ); /* * Set the w element of a quaternion */ static inline void vmathQSetW( VmathQuat *result, float w ); /* * Get the x element of a quaternion */ static inline float vmathQGetX( const VmathQuat *quat ); /* * Get the y element of a quaternion */ static inline float vmathQGetY( const VmathQuat *quat ); /* * Get the z element of a quaternion */ static inline float vmathQGetZ( const VmathQuat *quat ); /* * Get the w element of a quaternion */ static inline float vmathQGetW( const VmathQuat *quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathQSetElem( VmathQuat *result, int idx, float value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline float vmathQGetElem( const VmathQuat *quat, int idx ); /* * Add two quaternions */ static inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Subtract a quaternion from another quaternion */ static inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Multiply two quaternions */ static inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Multiply a quaternion by a scalar */ static inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar ); /* * Divide a quaternion by a scalar */ static inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar ); /* * Negate all elements of a quaternion */ static inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat ); /* * Construct an identity quaternion */ static inline void vmathQMakeIdentity( VmathQuat *result ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline void vmathQMakeRotationX( VmathQuat *result, float radians ); /* * Construct a quaternion to rotate around the y axis */ static inline void vmathQMakeRotationY( VmathQuat *result, float radians ); /* * Construct a quaternion to rotate around the z axis */ static inline void vmathQMakeRotationZ( VmathQuat *result, float radians ); /* * Compute the conjugate of a quaternion */ static inline void vmathQConj( VmathQuat *result, const VmathQuat *quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline void vmathQRotate( VmathVector3 *result, const VmathQuat *unitQuat, const VmathVector3 *vec ); /* * Compute the dot product of two quaternions */ static inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Compute the norm of a quaternion */ static inline float vmathQNorm( const VmathQuat *quat ); /* * Compute the length of a quaternion */ static inline float vmathQLength( const VmathQuat *quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 ); /* * Conditionally select between two quaternions * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrint( const VmathQuat *quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrints( const VmathQuat *quat, const char *name ); #endif /* * Copy a 3x3 matrix */ static inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Construct a 3x3 matrix containing the specified columns */ static inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *col2 ); /* * Get column 0 of a 3x3 matrix */ static inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Get column 1 of a 3x3 matrix */ static inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Get column 2 of a 3x3 matrix */ static inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row ); /* * Add two 3x3 matrices */ static inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec ); /* * Multiply two 3x3 matrices */ static inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Construct an identity 3x3 matrix */ static inline void vmathM3MakeIdentity( VmathMatrix3 *result ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat ); /* * Multiply two 3x3 matrices per element */ static inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Transpose of a 3x3 matrix */ static inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Determinant of a 3x3 matrix */ static inline float vmathM3Determinant( const VmathMatrix3 *mat ); /* * Conditionally select between two 3x3 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Print( const VmathMatrix3 *mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name ); #endif /* * Copy a 4x4 matrix */ static inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Construct a 4x4 matrix containing the specified columns */ static inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *col0, const VmathVector4 *col1, const VmathVector4 *col2, const VmathVector4 *col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *col3 ); /* * Get column 0 of a 4x4 matrix */ static inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 1 of a 4x4 matrix */ static inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 2 of a 4x4 matrix */ static inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 3 of a 4x4 matrix */ static inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row ); /* * Add two 4x4 matrices */ static inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt ); /* * Multiply two 4x4 matrices */ static inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm ); /* * Construct an identity 4x4 matrix */ static inline void vmathM4MakeIdentity( VmathMatrix4 *result ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec ); /* * Construct a perspective projection matrix */ static inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ); /* * Construct an orthographic projection matrix */ static inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat ); /* * Multiply two 4x4 matrices per element */ static inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Transpose of a 4x4 matrix */ static inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Determinant of a 4x4 matrix */ static inline float vmathM4Determinant( const VmathMatrix4 *mat ); /* * Conditionally select between two 4x4 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Print( const VmathMatrix4 *mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name ); #endif /* * Copy a 3x4 transformation matrix */ static inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2, const VmathVector3 *col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm ); /* * Set translation component */ static inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt ); /* * Multiply two 3x4 transformation matrices */ static inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline void vmathT3MakeIdentity( VmathTransform3 *result ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Conditionally select between two 3x4 transformation matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Print( const VmathTransform3 *tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vec_aos.h" #include "quat_aos.h" #include "mat_aos.h" #endif ================================================ FILE: samples/vectormath/ppu/c/vectormath_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_C_V_PPU_H #define _VECTORMATH_AOS_C_V_PPU_H #include #include #include "vec_types.h" #ifdef _VECTORMATH_DEBUG #include #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_AOS_C_TYPES_H #define _VECTORMATH_AOS_C_TYPES_H /* A 3-D vector in array-of-structures format */ typedef struct _VmathVector3 { vec_float4 vec128; } VmathVector3; /* A 4-D vector in array-of-structures format */ typedef struct _VmathVector4 { vec_float4 vec128; } VmathVector4; /* A 3-D point in array-of-structures format */ typedef struct _VmathPoint3 { vec_float4 vec128; } VmathPoint3; /* A quaternion in array-of-structures format */ typedef struct _VmathQuat { vec_float4 vec128; } VmathQuat; /* A 3x3 matrix in array-of-structures format */ typedef struct _VmathMatrix3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; } VmathMatrix3; /* A 4x4 matrix in array-of-structures format */ typedef struct _VmathMatrix4 { VmathVector4 col0; VmathVector4 col1; VmathVector4 col2; VmathVector4 col3; } VmathMatrix4; /* A 3x4 transformation matrix in array-of-structures format */ typedef struct _VmathTransform3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; VmathVector3 col3; } VmathTransform3; #endif /* * Construct a 3-D vector from x, y, and z elements */ static inline VmathVector3 vmathV3MakeFromElems_V( float x, float y, float z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline VmathVector3 vmathV3MakeFromScalar_V( float scalar ); /* * Set vector float data in a 3-D vector */ static inline VmathVector3 vmathV3MakeFrom128_V( vec_float4 vf4 ); /* * Get vector float data from a 3-D vector */ static inline vec_float4 vmathV3Get128_V( VmathVector3 vec ); /* * Set the x element of a 3-D vector */ static inline void vmathV3SetX_V( VmathVector3 *result, float x ); /* * Set the y element of a 3-D vector */ static inline void vmathV3SetY_V( VmathVector3 *result, float y ); /* * Set the z element of a 3-D vector */ static inline void vmathV3SetZ_V( VmathVector3 *result, float z ); /* * Get the x element of a 3-D vector */ static inline float vmathV3GetX_V( VmathVector3 vec ); /* * Get the y element of a 3-D vector */ static inline float vmathV3GetY_V( VmathVector3 vec ); /* * Get the z element of a 3-D vector */ static inline float vmathV3GetZ_V( VmathVector3 vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline float vmathV3GetElem_V( VmathVector3 vec, int idx ); /* * Add two 3-D vectors */ static inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt ); /* * Multiply a 3-D vector by a scalar */ static inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar ); /* * Divide a 3-D vector by a scalar */ static inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar ); /* * Negate all elements of a 3-D vector */ static inline VmathVector3 vmathV3Neg_V( VmathVector3 vec ); /* * Construct x axis */ static inline VmathVector3 vmathV3MakeXAxis_V( ); /* * Construct y axis */ static inline VmathVector3 vmathV3MakeYAxis_V( ); /* * Construct z axis */ static inline VmathVector3 vmathV3MakeZAxis_V( ); /* * Multiply two 3-D vectors per element */ static inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Maximum of two 3-D vectors per element */ static inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Minimum of two 3-D vectors per element */ static inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Maximum element of a 3-D vector */ static inline float vmathV3MaxElem_V( VmathVector3 vec ); /* * Minimum element of a 3-D vector */ static inline float vmathV3MinElem_V( VmathVector3 vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline float vmathV3Sum_V( VmathVector3 vec ); /* * Compute the dot product of two 3-D vectors */ static inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline float vmathV3LengthSqr_V( VmathVector3 vec ); /* * Compute the length of a 3-D vector */ static inline float vmathV3Length_V( VmathVector3 vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec ); /* * Compute cross product of two 3-D vectors */ static inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Outer product of two 3-D vectors */ static inline VmathMatrix3 vmathV3Outer_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix * NOTE: * Slower than column post-multiply. */ static inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat ); /* * Cross-product matrix of a 3-D vector */ static inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 ); /* * Conditionally select between two 3-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 ); /* * Store x, y, and z elements of a 3-D vector in the first three words of a quadword. * The value of the fourth word (the word with the highest address) remains unchanged */ static inline void vmathV3StoreXYZ_V( VmathVector3 vec, vec_float4 *quad ); /* * Load four three-float 3-D vectors, stored in three quadwords */ static inline void vmathV3LoadXYZArray_V( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads ); /* * Store four 3-D vectors in three quadwords */ static inline void vmathV3StoreXYZArray_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, vec_float4 *threeQuads ); /* * Store eight 3-D vectors as half-floats */ static inline void vmathV3StoreHalfFloats_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, VmathVector3 vec4, VmathVector3 vec5, VmathVector3 vec6, VmathVector3 vec7, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Print_V( VmathVector3 vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Prints_V( VmathVector3 vec, const char *name ); #endif /* * Construct a 4-D vector from x, y, z, and w elements */ static inline VmathVector4 vmathV4MakeFromElems_V( float x, float y, float z, float w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline VmathVector4 vmathV4MakeFromScalar_V( float scalar ); /* * Set vector float data in a 4-D vector */ static inline VmathVector4 vmathV4MakeFrom128_V( vec_float4 vf4 ); /* * Get vector float data from a 4-D vector */ static inline vec_float4 vmathV4Get128_V( VmathVector4 vec ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec ); /* * Set the x element of a 4-D vector */ static inline void vmathV4SetX_V( VmathVector4 *result, float x ); /* * Set the y element of a 4-D vector */ static inline void vmathV4SetY_V( VmathVector4 *result, float y ); /* * Set the z element of a 4-D vector */ static inline void vmathV4SetZ_V( VmathVector4 *result, float z ); /* * Set the w element of a 4-D vector */ static inline void vmathV4SetW_V( VmathVector4 *result, float w ); /* * Get the x element of a 4-D vector */ static inline float vmathV4GetX_V( VmathVector4 vec ); /* * Get the y element of a 4-D vector */ static inline float vmathV4GetY_V( VmathVector4 vec ); /* * Get the z element of a 4-D vector */ static inline float vmathV4GetZ_V( VmathVector4 vec ); /* * Get the w element of a 4-D vector */ static inline float vmathV4GetW_V( VmathVector4 vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline float vmathV4GetElem_V( VmathVector4 vec, int idx ); /* * Add two 4-D vectors */ static inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar ); /* * Divide a 4-D vector by a scalar */ static inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar ); /* * Negate all elements of a 4-D vector */ static inline VmathVector4 vmathV4Neg_V( VmathVector4 vec ); /* * Construct x axis */ static inline VmathVector4 vmathV4MakeXAxis_V( ); /* * Construct y axis */ static inline VmathVector4 vmathV4MakeYAxis_V( ); /* * Construct z axis */ static inline VmathVector4 vmathV4MakeZAxis_V( ); /* * Construct w axis */ static inline VmathVector4 vmathV4MakeWAxis_V( ); /* * Multiply two 4-D vectors per element */ static inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Maximum of two 4-D vectors per element */ static inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Minimum of two 4-D vectors per element */ static inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Maximum element of a 4-D vector */ static inline float vmathV4MaxElem_V( VmathVector4 vec ); /* * Minimum element of a 4-D vector */ static inline float vmathV4MinElem_V( VmathVector4 vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline float vmathV4Sum_V( VmathVector4 vec ); /* * Compute the dot product of two 4-D vectors */ static inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline float vmathV4LengthSqr_V( VmathVector4 vec ); /* * Compute the length of a 4-D vector */ static inline float vmathV4Length_V( VmathVector4 vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec ); /* * Outer product of two 4-D vectors */ static inline VmathMatrix4 vmathV4Outer_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 ); /* * Conditionally select between two 4-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 ); /* * Store four 4-D vectors as half-floats */ static inline void vmathV4StoreHalfFloats_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3, vec_ushort8 *twoQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Print_V( VmathVector4 vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Prints_V( VmathVector4 vec, const char *name ); #endif /* * Construct a 3-D point from x, y, and z elements */ static inline VmathPoint3 vmathP3MakeFromElems_V( float x, float y, float z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar ); /* * Set vector float data in a 3-D point */ static inline VmathPoint3 vmathP3MakeFrom128_V( vec_float4 vf4 ); /* * Get vector float data from a 3-D point */ static inline vec_float4 vmathP3Get128_V( VmathPoint3 pnt ); /* * Set the x element of a 3-D point */ static inline void vmathP3SetX_V( VmathPoint3 *result, float x ); /* * Set the y element of a 3-D point */ static inline void vmathP3SetY_V( VmathPoint3 *result, float y ); /* * Set the z element of a 3-D point */ static inline void vmathP3SetZ_V( VmathPoint3 *result, float z ); /* * Get the x element of a 3-D point */ static inline float vmathP3GetX_V( VmathPoint3 pnt ); /* * Get the y element of a 3-D point */ static inline float vmathP3GetY_V( VmathPoint3 pnt ); /* * Get the z element of a 3-D point */ static inline float vmathP3GetZ_V( VmathPoint3 pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec ); /* * Multiply two 3-D points per element */ static inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Maximum of two 3-D points per element */ static inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Minimum of two 3-D points per element */ static inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Maximum element of a 3-D point */ static inline float vmathP3MaxElem_V( VmathPoint3 pnt ); /* * Minimum element of a 3-D point */ static inline float vmathP3MinElem_V( VmathPoint3 pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline float vmathP3Sum_V( VmathPoint3 pnt ); /* * Apply uniform scale to a 3-D point */ static inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt ); /* * Compute the square of the distance between two 3-D points */ static inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Compute the distance between two 3-D points */ static inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Conditionally select between two 3-D points * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 ); /* * Store x, y, and z elements of a 3-D point in the first three words of a quadword. * The value of the fourth word (the word with the highest address) remains unchanged */ static inline void vmathP3StoreXYZ_V( VmathPoint3 pnt, vec_float4 *quad ); /* * Load four three-float 3-D points, stored in three quadwords */ static inline void vmathP3LoadXYZArray_V( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads ); /* * Store four 3-D points in three quadwords */ static inline void vmathP3StoreXYZArray_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, vec_float4 *threeQuads ); /* * Store eight 3-D points as half-floats */ static inline void vmathP3StoreHalfFloats_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, VmathPoint3 pnt4, VmathPoint3 pnt5, VmathPoint3 pnt6, VmathPoint3 pnt7, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Print_V( VmathPoint3 pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name ); #endif /* * Construct a quaternion from x, y, z, and w elements */ static inline VmathQuat vmathQMakeFromElems_V( float x, float y, float z, float w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline VmathQuat vmathQMakeFromScalar_V( float scalar ); /* * Set vector float data in a quaternion */ static inline VmathQuat vmathQMakeFrom128_V( vec_float4 vf4 ); /* * Get vector float data from a quaternion */ static inline vec_float4 vmathQGet128_V( VmathQuat quat ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec ); /* * Get the x, y, and z elements of a quaternion */ static inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat ); /* * Set the x element of a quaternion */ static inline void vmathQSetX_V( VmathQuat *result, float x ); /* * Set the y element of a quaternion */ static inline void vmathQSetY_V( VmathQuat *result, float y ); /* * Set the z element of a quaternion */ static inline void vmathQSetZ_V( VmathQuat *result, float z ); /* * Set the w element of a quaternion */ static inline void vmathQSetW_V( VmathQuat *result, float w ); /* * Get the x element of a quaternion */ static inline float vmathQGetX_V( VmathQuat quat ); /* * Get the y element of a quaternion */ static inline float vmathQGetY_V( VmathQuat quat ); /* * Get the z element of a quaternion */ static inline float vmathQGetZ_V( VmathQuat quat ); /* * Get the w element of a quaternion */ static inline float vmathQGetW_V( VmathQuat quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathQSetElem_V( VmathQuat *result, int idx, float value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline float vmathQGetElem_V( VmathQuat quat, int idx ); /* * Add two quaternions */ static inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 ); /* * Subtract a quaternion from another quaternion */ static inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 ); /* * Multiply two quaternions */ static inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 ); /* * Multiply a quaternion by a scalar */ static inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar ); /* * Divide a quaternion by a scalar */ static inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar ); /* * Negate all elements of a quaternion */ static inline VmathQuat vmathQNeg_V( VmathQuat quat ); /* * Construct an identity quaternion */ static inline VmathQuat vmathQMakeIdentity_V( ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline VmathQuat vmathQMakeRotationX_V( float radians ); /* * Construct a quaternion to rotate around the y axis */ static inline VmathQuat vmathQMakeRotationY_V( float radians ); /* * Construct a quaternion to rotate around the z axis */ static inline VmathQuat vmathQMakeRotationZ_V( float radians ); /* * Compute the conjugate of a quaternion */ static inline VmathQuat vmathQConj_V( VmathQuat quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline VmathVector3 vmathQRotate_V( VmathQuat unitQuat, VmathVector3 vec ); /* * Compute the dot product of two quaternions */ static inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 ); /* * Compute the norm of a quaternion */ static inline float vmathQNorm_V( VmathQuat quat ); /* * Compute the length of a quaternion */ static inline float vmathQLength_V( VmathQuat quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline VmathQuat vmathQNormalize_V( VmathQuat quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 ); /* * Conditionally select between two quaternions * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrint_V( VmathQuat quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrints_V( VmathQuat quat, const char *name ); #endif /* * Construct a 3x3 matrix containing the specified columns */ static inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 col2 ); /* * Get column 0 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat ); /* * Get column 1 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat ); /* * Get column 2 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row ); /* * Add two 3x3 matrices */ static inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec ); /* * Multiply two 3x3 matrices */ static inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Construct an identity 3x3 matrix */ static inline VmathMatrix3 vmathM3MakeIdentity_V( ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline VmathMatrix3 vmathM3MakeRotationX_V( float radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline VmathMatrix3 vmathM3MakeRotationY_V( float radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat ); /* * Multiply two 3x3 matrices per element */ static inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat ); /* * Transpose of a 3x3 matrix */ static inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat ); /* * Determinant of a 3x3 matrix */ static inline float vmathM3Determinant_V( VmathMatrix3 mat ); /* * Conditionally select between two 3x3 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Print_V( VmathMatrix3 mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name ); #endif /* * Construct a 4x4 matrix containing the specified columns */ static inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 col0, VmathVector4 col1, VmathVector4 col2, VmathVector4 col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 col3 ); /* * Get column 0 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat ); /* * Get column 1 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat ); /* * Get column 2 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat ); /* * Get column 3 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row ); /* * Add two 4x4 matrices */ static inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt ); /* * Multiply two 4x4 matrices */ static inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm ); /* * Construct an identity 4x4 matrix */ static inline VmathMatrix4 vmathM4MakeIdentity_V( ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline VmathMatrix4 vmathM4MakeRotationX_V( float radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline VmathMatrix4 vmathM4MakeRotationY_V( float radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec ); /* * Construct a perspective projection matrix */ static inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar ); /* * Construct an orthographic projection matrix */ static inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat ); /* * Multiply two 4x4 matrices per element */ static inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat ); /* * Transpose of a 4x4 matrix */ static inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat ); /* * Determinant of a 4x4 matrix */ static inline float vmathM4Determinant_V( VmathMatrix4 mat ); /* * Conditionally select between two 4x4 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Print_V( VmathMatrix4 mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name ); #endif /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2, VmathVector3 col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm ); /* * Set translation component */ static inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt ); /* * Multiply two 3x4 transformation matrices */ static inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline VmathTransform3 vmathT3MakeIdentity_V( ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline VmathTransform3 vmathT3MakeRotationX_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline VmathTransform3 vmathT3MakeRotationY_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline VmathTransform3 vmathT3MakeRotationZ_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm ); /* * Conditionally select between two 3x4 transformation matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. * However, the transfer of select1 to a VMX register may use more processing time than a branch. */ static inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Print_V( VmathTransform3 tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vectormath_aos.h" #include "vec_aos_v.h" #include "quat_aos_v.h" #include "mat_aos_v.h" #endif ================================================ FILE: samples/vectormath/ppu/c/vectormath_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_C_PPU_H #define _VECTORMATH_SOA_C_PPU_H #include #include #include "vectormath_aos.h" #ifdef _VECTORMATH_DEBUG #include #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_SOA_C_TYPES_H #define _VECTORMATH_SOA_C_TYPES_H /* A set of four 3-D vectors in structure-of-arrays format */ typedef struct _VmathSoaVector3 { vec_float4 x; vec_float4 y; vec_float4 z; } VmathSoaVector3; /* A set of four 4-D vectors in structure-of-arrays format */ typedef struct _VmathSoaVector4 { vec_float4 x; vec_float4 y; vec_float4 z; vec_float4 w; } VmathSoaVector4; /* A set of four 3-D points in structure-of-arrays format */ typedef struct _VmathSoaPoint3 { vec_float4 x; vec_float4 y; vec_float4 z; } VmathSoaPoint3; /* A set of four quaternions in structure-of-arrays format */ typedef struct _VmathSoaQuat { vec_float4 x; vec_float4 y; vec_float4 z; vec_float4 w; } VmathSoaQuat; /* A set of four 3x3 matrices in structure-of-arrays format */ typedef struct _VmathSoaMatrix3 { VmathSoaVector3 col0; VmathSoaVector3 col1; VmathSoaVector3 col2; } VmathSoaMatrix3; /* A set of four 4x4 matrices in structure-of-arrays format */ typedef struct _VmathSoaMatrix4 { VmathSoaVector4 col0; VmathSoaVector4 col1; VmathSoaVector4 col2; VmathSoaVector4 col3; } VmathSoaMatrix4; /* A set of four 3x4 transformation matrices in structure-of-arrays format */ typedef struct _VmathSoaTransform3 { VmathSoaVector3 col0; VmathSoaVector3 col1; VmathSoaVector3 col2; VmathSoaVector3 col3; } VmathSoaTransform3; #endif /* * Copy a 3-D vector */ static inline void vmathSoaV3Copy( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Construct a 3-D vector from x, y, and z elements */ static inline void vmathSoaV3MakeFromElems( VmathSoaVector3 *result, vec_float4 x, vec_float4 y, vec_float4 z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline void vmathSoaV3MakeFromP3( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline void vmathSoaV3MakeFromScalar( VmathSoaVector3 *result, vec_float4 scalar ); /* * Replicate an AoS 3-D vector */ static inline void vmathSoaV3MakeFromAos( VmathSoaVector3 *result, const VmathVector3 *vec ); /* * Insert four AoS 3-D vectors */ static inline void vmathSoaV3MakeFrom4Aos( VmathSoaVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3 ); /* * Extract four AoS 3-D vectors */ static inline void vmathSoaV3Get4Aos( const VmathSoaVector3 *vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 ); /* * Set the x element of a 3-D vector */ static inline void vmathSoaV3SetX( VmathSoaVector3 *result, vec_float4 x ); /* * Set the y element of a 3-D vector */ static inline void vmathSoaV3SetY( VmathSoaVector3 *result, vec_float4 y ); /* * Set the z element of a 3-D vector */ static inline void vmathSoaV3SetZ( VmathSoaVector3 *result, vec_float4 z ); /* * Get the x element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetX( const VmathSoaVector3 *vec ); /* * Get the y element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetY( const VmathSoaVector3 *vec ); /* * Get the z element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetZ( const VmathSoaVector3 *vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathSoaV3SetElem( VmathSoaVector3 *result, int idx, vec_float4 value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline vec_float4 vmathSoaV3GetElem( const VmathSoaVector3 *vec, int idx ); /* * Add two 3-D vectors */ static inline void vmathSoaV3Add( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline void vmathSoaV3Sub( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline void vmathSoaV3AddP3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec, const VmathSoaPoint3 *pnt ); /* * Multiply a 3-D vector by a scalar */ static inline void vmathSoaV3ScalarMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar ); /* * Divide a 3-D vector by a scalar */ static inline void vmathSoaV3ScalarDiv( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar ); /* * Negate all elements of a 3-D vector */ static inline void vmathSoaV3Neg( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Construct x axis */ static inline void vmathSoaV3MakeXAxis( VmathSoaVector3 *result ); /* * Construct y axis */ static inline void vmathSoaV3MakeYAxis( VmathSoaVector3 *result ); /* * Construct z axis */ static inline void vmathSoaV3MakeZAxis( VmathSoaVector3 *result ); /* * Multiply two 3-D vectors per element */ static inline void vmathSoaV3MulPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathSoaV3DivPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathSoaV3RecipPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathSoaV3SqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathSoaV3RsqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline void vmathSoaV3AbsPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline void vmathSoaV3CopySignPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Maximum of two 3-D vectors per element */ static inline void vmathSoaV3MaxPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Minimum of two 3-D vectors per element */ static inline void vmathSoaV3MinPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Maximum element of a 3-D vector */ static inline vec_float4 vmathSoaV3MaxElem( const VmathSoaVector3 *vec ); /* * Minimum element of a 3-D vector */ static inline vec_float4 vmathSoaV3MinElem( const VmathSoaVector3 *vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline vec_float4 vmathSoaV3Sum( const VmathSoaVector3 *vec ); /* * Compute the dot product of two 3-D vectors */ static inline vec_float4 vmathSoaV3Dot( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline vec_float4 vmathSoaV3LengthSqr( const VmathSoaVector3 *vec ); /* * Compute the length of a 3-D vector */ static inline vec_float4 vmathSoaV3Length( const VmathSoaVector3 *vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathSoaV3Normalize( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Compute cross product of two 3-D vectors */ static inline void vmathSoaV3Cross( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Outer product of two 3-D vectors */ static inline void vmathSoaV3Outer( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix */ static inline void vmathSoaV3RowMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat ); /* * Cross-product matrix of a 3-D vector */ static inline void vmathSoaV3CrossMatrix( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline void vmathSoaV3CrossMatrixMul( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathSoaV3Lerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathSoaV3Slerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 ); /* * Conditionally select between two 3-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaV3Select( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_uint4 select1 ); /* * Load four three-float 3-D vectors, stored in three quadwords */ static inline void vmathSoaV3LoadXYZArray( VmathSoaVector3 *vec, const vec_float4 *threeQuads ); /* * Store four slots of an SoA 3-D vector in three quadwords */ static inline void vmathSoaV3StoreXYZArray( const VmathSoaVector3 *vec, vec_float4 *threeQuads ); /* * Store eight slots of two SoA 3-D vectors as half-floats */ static inline void vmathSoaV3StoreHalfFloats( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV3Print( const VmathSoaVector3 *vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV3Prints( const VmathSoaVector3 *vec, const char *name ); #endif /* * Copy a 4-D vector */ static inline void vmathSoaV4Copy( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Construct a 4-D vector from x, y, z, and w elements */ static inline void vmathSoaV4MakeFromElems( VmathSoaVector4 *result, vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline void vmathSoaV4MakeFromV3Scalar( VmathSoaVector4 *result, const VmathSoaVector3 *xyz, vec_float4 w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline void vmathSoaV4MakeFromV3( VmathSoaVector4 *result, const VmathSoaVector3 *vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline void vmathSoaV4MakeFromP3( VmathSoaVector4 *result, const VmathSoaPoint3 *pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline void vmathSoaV4MakeFromQ( VmathSoaVector4 *result, const VmathSoaQuat *quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline void vmathSoaV4MakeFromScalar( VmathSoaVector4 *result, vec_float4 scalar ); /* * Replicate an AoS 4-D vector */ static inline void vmathSoaV4MakeFromAos( VmathSoaVector4 *result, const VmathVector4 *vec ); /* * Insert four AoS 4-D vectors */ static inline void vmathSoaV4MakeFrom4Aos( VmathSoaVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3 ); /* * Extract four AoS 4-D vectors */ static inline void vmathSoaV4Get4Aos( const VmathSoaVector4 *vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathSoaV4SetXYZ( VmathSoaVector4 *result, const VmathSoaVector3 *vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline void vmathSoaV4GetXYZ( VmathSoaVector3 *result, const VmathSoaVector4 *vec ); /* * Set the x element of a 4-D vector */ static inline void vmathSoaV4SetX( VmathSoaVector4 *result, vec_float4 x ); /* * Set the y element of a 4-D vector */ static inline void vmathSoaV4SetY( VmathSoaVector4 *result, vec_float4 y ); /* * Set the z element of a 4-D vector */ static inline void vmathSoaV4SetZ( VmathSoaVector4 *result, vec_float4 z ); /* * Set the w element of a 4-D vector */ static inline void vmathSoaV4SetW( VmathSoaVector4 *result, vec_float4 w ); /* * Get the x element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetX( const VmathSoaVector4 *vec ); /* * Get the y element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetY( const VmathSoaVector4 *vec ); /* * Get the z element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetZ( const VmathSoaVector4 *vec ); /* * Get the w element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetW( const VmathSoaVector4 *vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathSoaV4SetElem( VmathSoaVector4 *result, int idx, vec_float4 value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline vec_float4 vmathSoaV4GetElem( const VmathSoaVector4 *vec, int idx ); /* * Add two 4-D vectors */ static inline void vmathSoaV4Add( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline void vmathSoaV4Sub( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline void vmathSoaV4ScalarMul( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar ); /* * Divide a 4-D vector by a scalar */ static inline void vmathSoaV4ScalarDiv( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar ); /* * Negate all elements of a 4-D vector */ static inline void vmathSoaV4Neg( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Construct x axis */ static inline void vmathSoaV4MakeXAxis( VmathSoaVector4 *result ); /* * Construct y axis */ static inline void vmathSoaV4MakeYAxis( VmathSoaVector4 *result ); /* * Construct z axis */ static inline void vmathSoaV4MakeZAxis( VmathSoaVector4 *result ); /* * Construct w axis */ static inline void vmathSoaV4MakeWAxis( VmathSoaVector4 *result ); /* * Multiply two 4-D vectors per element */ static inline void vmathSoaV4MulPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathSoaV4DivPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathSoaV4RecipPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathSoaV4SqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathSoaV4RsqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline void vmathSoaV4AbsPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline void vmathSoaV4CopySignPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Maximum of two 4-D vectors per element */ static inline void vmathSoaV4MaxPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Minimum of two 4-D vectors per element */ static inline void vmathSoaV4MinPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Maximum element of a 4-D vector */ static inline vec_float4 vmathSoaV4MaxElem( const VmathSoaVector4 *vec ); /* * Minimum element of a 4-D vector */ static inline vec_float4 vmathSoaV4MinElem( const VmathSoaVector4 *vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline vec_float4 vmathSoaV4Sum( const VmathSoaVector4 *vec ); /* * Compute the dot product of two 4-D vectors */ static inline vec_float4 vmathSoaV4Dot( const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline vec_float4 vmathSoaV4LengthSqr( const VmathSoaVector4 *vec ); /* * Compute the length of a 4-D vector */ static inline vec_float4 vmathSoaV4Length( const VmathSoaVector4 *vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathSoaV4Normalize( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Outer product of two 4-D vectors */ static inline void vmathSoaV4Outer( VmathSoaMatrix4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathSoaV4Lerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathSoaV4Slerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *unitVec0, const VmathSoaVector4 *unitVec1 ); /* * Conditionally select between two 4-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaV4Select( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1, vec_uint4 select1 ); /* * Store four slots of an SoA 4-D vector as half-floats */ static inline void vmathSoaV4StoreHalfFloats( const VmathSoaVector4 *vec, vec_ushort8 *twoQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV4Print( const VmathSoaVector4 *vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV4Prints( const VmathSoaVector4 *vec, const char *name ); #endif /* * Copy a 3-D point */ static inline void vmathSoaP3Copy( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Construct a 3-D point from x, y, and z elements */ static inline void vmathSoaP3MakeFromElems( VmathSoaPoint3 *result, vec_float4 x, vec_float4 y, vec_float4 z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline void vmathSoaP3MakeFromV3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline void vmathSoaP3MakeFromScalar( VmathSoaPoint3 *result, vec_float4 scalar ); /* * Replicate an AoS 3-D point */ static inline void vmathSoaP3MakeFromAos( VmathSoaPoint3 *result, const VmathPoint3 *pnt ); /* * Insert four AoS 3-D points */ static inline void vmathSoaP3MakeFrom4Aos( VmathSoaPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3 ); /* * Extract four AoS 3-D points */ static inline void vmathSoaP3Get4Aos( const VmathSoaPoint3 *pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 ); /* * Set the x element of a 3-D point */ static inline void vmathSoaP3SetX( VmathSoaPoint3 *result, vec_float4 x ); /* * Set the y element of a 3-D point */ static inline void vmathSoaP3SetY( VmathSoaPoint3 *result, vec_float4 y ); /* * Set the z element of a 3-D point */ static inline void vmathSoaP3SetZ( VmathSoaPoint3 *result, vec_float4 z ); /* * Get the x element of a 3-D point */ static inline vec_float4 vmathSoaP3GetX( const VmathSoaPoint3 *pnt ); /* * Get the y element of a 3-D point */ static inline vec_float4 vmathSoaP3GetY( const VmathSoaPoint3 *pnt ); /* * Get the z element of a 3-D point */ static inline vec_float4 vmathSoaP3GetZ( const VmathSoaPoint3 *pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathSoaP3SetElem( VmathSoaPoint3 *result, int idx, vec_float4 value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline vec_float4 vmathSoaP3GetElem( const VmathSoaPoint3 *pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline void vmathSoaP3Sub( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline void vmathSoaP3AddV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline void vmathSoaP3SubV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec ); /* * Multiply two 3-D points per element */ static inline void vmathSoaP3MulPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathSoaP3DivPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathSoaP3RecipPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathSoaP3SqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathSoaP3RsqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline void vmathSoaP3AbsPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline void vmathSoaP3CopySignPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Maximum of two 3-D points per element */ static inline void vmathSoaP3MaxPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Minimum of two 3-D points per element */ static inline void vmathSoaP3MinPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Maximum element of a 3-D point */ static inline vec_float4 vmathSoaP3MaxElem( const VmathSoaPoint3 *pnt ); /* * Minimum element of a 3-D point */ static inline vec_float4 vmathSoaP3MinElem( const VmathSoaPoint3 *pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline vec_float4 vmathSoaP3Sum( const VmathSoaPoint3 *pnt ); /* * Apply uniform scale to a 3-D point */ static inline void vmathSoaP3Scale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, vec_float4 scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline void vmathSoaP3NonUniformScale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline vec_float4 vmathSoaP3Projection( const VmathSoaPoint3 *pnt, const VmathSoaVector3 *unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline vec_float4 vmathSoaP3DistSqrFromOrigin( const VmathSoaPoint3 *pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline vec_float4 vmathSoaP3DistFromOrigin( const VmathSoaPoint3 *pnt ); /* * Compute the square of the distance between two 3-D points */ static inline vec_float4 vmathSoaP3DistSqr( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Compute the distance between two 3-D points */ static inline vec_float4 vmathSoaP3Dist( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathSoaP3Lerp( VmathSoaPoint3 *result, vec_float4 t, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Conditionally select between two 3-D points * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaP3Select( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_uint4 select1 ); /* * Load four three-float 3-D points, stored in three quadwords */ static inline void vmathSoaP3LoadXYZArray( VmathSoaPoint3 *pnt, const vec_float4 *threeQuads ); /* * Store four slots of an SoA 3-D point in three quadwords */ static inline void vmathSoaP3StoreXYZArray( const VmathSoaPoint3 *pnt, vec_float4 *threeQuads ); /* * Store eight slots of two SoA 3-D points as half-floats */ static inline void vmathSoaP3StoreHalfFloats( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaP3Print( const VmathSoaPoint3 *pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaP3Prints( const VmathSoaPoint3 *pnt, const char *name ); #endif /* * Copy a quaternion */ static inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat ); /* * Construct a quaternion from x, y, z, and w elements */ static inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline void vmathSoaQMakeFromM3( VmathSoaQuat *result, const VmathSoaMatrix3 *rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar ); /* * Replicate an AoS quaternion */ static inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat ); /* * Insert four AoS quaternions */ static inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 ); /* * Extract four AoS quaternions */ static inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec ); /* * Get the x, y, and z elements of a quaternion */ static inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat ); /* * Set the x element of a quaternion */ static inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 x ); /* * Set the y element of a quaternion */ static inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 y ); /* * Set the z element of a quaternion */ static inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 z ); /* * Set the w element of a quaternion */ static inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 w ); /* * Get the x element of a quaternion */ static inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat ); /* * Get the y element of a quaternion */ static inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat ); /* * Get the z element of a quaternion */ static inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat ); /* * Get the w element of a quaternion */ static inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx ); /* * Add two quaternions */ static inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Subtract a quaternion from another quaternion */ static inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Multiply two quaternions */ static inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Multiply a quaternion by a scalar */ static inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar ); /* * Divide a quaternion by a scalar */ static inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar ); /* * Negate all elements of a quaternion */ static inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat ); /* * Construct an identity quaternion */ static inline void vmathSoaQMakeIdentity( VmathSoaQuat *result ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians ); /* * Construct a quaternion to rotate around the y axis */ static inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians ); /* * Construct a quaternion to rotate around the z axis */ static inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians ); /* * Compute the conjugate of a quaternion */ static inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *vec ); /* * Compute the dot product of two quaternions */ static inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Compute the norm of a quaternion */ static inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat ); /* * Compute the length of a quaternion */ static inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 ); /* * Conditionally select between two quaternions * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaQPrint( const VmathSoaQuat *quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name ); #endif /* * Copy a 3x3 matrix */ static inline void vmathSoaM3Copy( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Construct a 3x3 matrix containing the specified columns */ static inline void vmathSoaM3MakeFromCols( VmathSoaMatrix3 *result, const VmathSoaVector3 *col0, const VmathSoaVector3 *col1, const VmathSoaVector3 *col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline void vmathSoaM3MakeFromQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline void vmathSoaM3MakeFromScalar( VmathSoaMatrix3 *result, vec_float4 scalar ); /* * Replicate an AoS 3x3 matrix */ static inline void vmathSoaM3MakeFromAos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat ); /* * Insert four AoS 3x3 matrices */ static inline void vmathSoaM3MakeFrom4Aos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, const VmathMatrix3 *mat2, const VmathMatrix3 *mat3 ); /* * Extract four AoS 3x3 matrices */ static inline void vmathSoaM3Get4Aos( const VmathSoaMatrix3 *mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathSoaM3SetCol0( VmathSoaMatrix3 *result, const VmathSoaVector3 *col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathSoaM3SetCol1( VmathSoaMatrix3 *result, const VmathSoaVector3 *col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathSoaM3SetCol2( VmathSoaMatrix3 *result, const VmathSoaVector3 *col2 ); /* * Get column 0 of a 3x3 matrix */ static inline void vmathSoaM3GetCol0( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ); /* * Get column 1 of a 3x3 matrix */ static inline void vmathSoaM3GetCol1( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ); /* * Get column 2 of a 3x3 matrix */ static inline void vmathSoaM3GetCol2( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3SetCol( VmathSoaMatrix3 *result, int col, const VmathSoaVector3 *vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3SetRow( VmathSoaMatrix3 *result, int row, const VmathSoaVector3 *vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3GetCol( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3GetRow( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathSoaM3SetElem( VmathSoaMatrix3 *result, int col, int row, vec_float4 val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline vec_float4 vmathSoaM3GetElem( const VmathSoaMatrix3 *mat, int col, int row ); /* * Add two 3x3 matrices */ static inline void vmathSoaM3Add( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline void vmathSoaM3Sub( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline void vmathSoaM3Neg( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline void vmathSoaM3ScalarMul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, vec_float4 scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline void vmathSoaM3MulV3( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *vec ); /* * Multiply two 3x3 matrices */ static inline void vmathSoaM3Mul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ); /* * Construct an identity 3x3 matrix */ static inline void vmathSoaM3MakeIdentity( VmathSoaMatrix3 *result ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline void vmathSoaM3MakeRotationX( VmathSoaMatrix3 *result, vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline void vmathSoaM3MakeRotationY( VmathSoaMatrix3 *result, vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline void vmathSoaM3MakeRotationZ( VmathSoaMatrix3 *result, vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline void vmathSoaM3MakeRotationZYX( VmathSoaMatrix3 *result, const VmathSoaVector3 *radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline void vmathSoaM3MakeRotationAxis( VmathSoaMatrix3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathSoaM3MakeRotationQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline void vmathSoaM3MakeScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaM3AppendScale( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaM3PrependScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix3 *mat ); /* * Multiply two 3x3 matrices per element */ static inline void vmathSoaM3MulPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline void vmathSoaM3AbsPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Transpose of a 3x3 matrix */ static inline void vmathSoaM3Transpose( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathSoaM3Inverse( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Determinant of a 3x3 matrix */ static inline vec_float4 vmathSoaM3Determinant( const VmathSoaMatrix3 *mat ); /* * Conditionally select between two 3x3 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaM3Select( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM3Print( const VmathSoaMatrix3 *mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM3Prints( const VmathSoaMatrix3 *mat, const char *name ); #endif /* * Copy a 4x4 matrix */ static inline void vmathSoaM4Copy( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Construct a 4x4 matrix containing the specified columns */ static inline void vmathSoaM4MakeFromCols( VmathSoaMatrix4 *result, const VmathSoaVector4 *col0, const VmathSoaVector4 *col1, const VmathSoaVector4 *col2, const VmathSoaVector4 *col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline void vmathSoaM4MakeFromT3( VmathSoaMatrix4 *result, const VmathSoaTransform3 *mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathSoaM4MakeFromM3V3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathSoaM4MakeFromQV3( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline void vmathSoaM4MakeFromScalar( VmathSoaMatrix4 *result, vec_float4 scalar ); /* * Replicate an AoS 4x4 matrix */ static inline void vmathSoaM4MakeFromAos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat ); /* * Insert four AoS 4x4 matrices */ static inline void vmathSoaM4MakeFrom4Aos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, const VmathMatrix4 *mat2, const VmathMatrix4 *mat3 ); /* * Extract four AoS 4x4 matrices */ static inline void vmathSoaM4Get4Aos( const VmathSoaMatrix4 *mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathSoaM4SetUpper3x3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline void vmathSoaM4GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaMatrix4 *mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathSoaM4SetTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline void vmathSoaM4GetTranslation( VmathSoaVector3 *result, const VmathSoaMatrix4 *mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathSoaM4SetCol0( VmathSoaMatrix4 *result, const VmathSoaVector4 *col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathSoaM4SetCol1( VmathSoaMatrix4 *result, const VmathSoaVector4 *col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathSoaM4SetCol2( VmathSoaMatrix4 *result, const VmathSoaVector4 *col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathSoaM4SetCol3( VmathSoaMatrix4 *result, const VmathSoaVector4 *col3 ); /* * Get column 0 of a 4x4 matrix */ static inline void vmathSoaM4GetCol0( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ); /* * Get column 1 of a 4x4 matrix */ static inline void vmathSoaM4GetCol1( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ); /* * Get column 2 of a 4x4 matrix */ static inline void vmathSoaM4GetCol2( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ); /* * Get column 3 of a 4x4 matrix */ static inline void vmathSoaM4GetCol3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4SetCol( VmathSoaMatrix4 *result, int col, const VmathSoaVector4 *vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4SetRow( VmathSoaMatrix4 *result, int row, const VmathSoaVector4 *vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4GetCol( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4GetRow( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathSoaM4SetElem( VmathSoaMatrix4 *result, int col, int row, vec_float4 val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline vec_float4 vmathSoaM4GetElem( const VmathSoaMatrix4 *mat, int col, int row ); /* * Add two 4x4 matrices */ static inline void vmathSoaM4Add( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline void vmathSoaM4Sub( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline void vmathSoaM4Neg( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline void vmathSoaM4ScalarMul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, vec_float4 scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline void vmathSoaM4MulV4( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector4 *vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline void vmathSoaM4MulV3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline void vmathSoaM4MulP3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaPoint3 *pnt ); /* * Multiply two 4x4 matrices */ static inline void vmathSoaM4Mul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline void vmathSoaM4MulT3( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaTransform3 *tfrm ); /* * Construct an identity 4x4 matrix */ static inline void vmathSoaM4MakeIdentity( VmathSoaMatrix4 *result ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline void vmathSoaM4MakeRotationX( VmathSoaMatrix4 *result, vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline void vmathSoaM4MakeRotationY( VmathSoaMatrix4 *result, vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline void vmathSoaM4MakeRotationZ( VmathSoaMatrix4 *result, vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline void vmathSoaM4MakeRotationZYX( VmathSoaMatrix4 *result, const VmathSoaVector3 *radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline void vmathSoaM4MakeRotationAxis( VmathSoaMatrix4 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathSoaM4MakeRotationQ( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline void vmathSoaM4MakeScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline void vmathSoaM4MakeTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline void vmathSoaM4MakeLookAt( VmathSoaMatrix4 *result, const VmathSoaPoint3 *eyePos, const VmathSoaPoint3 *lookAtPos, const VmathSoaVector3 *upVec ); /* * Construct a perspective projection matrix */ static inline void vmathSoaM4MakePerspective( VmathSoaMatrix4 *result, vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline void vmathSoaM4MakeFrustum( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); /* * Construct an orthographic projection matrix */ static inline void vmathSoaM4MakeOrthographic( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaM4AppendScale( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaM4PrependScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix4 *mat ); /* * Multiply two 4x4 matrices per element */ static inline void vmathSoaM4MulPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline void vmathSoaM4AbsPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Transpose of a 4x4 matrix */ static inline void vmathSoaM4Transpose( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathSoaM4Inverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline void vmathSoaM4AffineInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline void vmathSoaM4OrthoInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Determinant of a 4x4 matrix */ static inline vec_float4 vmathSoaM4Determinant( const VmathSoaMatrix4 *mat ); /* * Conditionally select between two 4x4 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaM4Select( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM4Print( const VmathSoaMatrix4 *mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM4Prints( const VmathSoaMatrix4 *mat, const char *name ); #endif /* * Copy a 3x4 transformation matrix */ static inline void vmathSoaT3Copy( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ); /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline void vmathSoaT3MakeFromCols( VmathSoaTransform3 *result, const VmathSoaVector3 *col0, const VmathSoaVector3 *col1, const VmathSoaVector3 *col2, const VmathSoaVector3 *col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathSoaT3MakeFromM3V3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm, const VmathSoaVector3 *translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathSoaT3MakeFromQV3( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline void vmathSoaT3MakeFromScalar( VmathSoaTransform3 *result, vec_float4 scalar ); /* * Replicate an AoS 3x4 transformation matrix */ static inline void vmathSoaT3MakeFromAos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm ); /* * Insert four AoS 3x4 transformation matrices */ static inline void vmathSoaT3MakeFrom4Aos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, const VmathTransform3 *tfrm2, const VmathTransform3 *tfrm3 ); /* * Extract four AoS 3x4 transformation matrices */ static inline void vmathSoaT3Get4Aos( const VmathSoaTransform3 *tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathSoaT3SetUpper3x3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline void vmathSoaT3GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaTransform3 *tfrm ); /* * Set translation component */ static inline void vmathSoaT3SetTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline void vmathSoaT3GetTranslation( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol0( VmathSoaTransform3 *result, const VmathSoaVector3 *col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol1( VmathSoaTransform3 *result, const VmathSoaVector3 *col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol2( VmathSoaTransform3 *result, const VmathSoaVector3 *col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol3( VmathSoaTransform3 *result, const VmathSoaVector3 *col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline void vmathSoaT3GetCol0( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline void vmathSoaT3GetCol1( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline void vmathSoaT3GetCol2( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline void vmathSoaT3GetCol3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3SetCol( VmathSoaTransform3 *result, int col, const VmathSoaVector3 *vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3SetRow( VmathSoaTransform3 *result, int row, const VmathSoaVector4 *vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3GetCol( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3GetRow( VmathSoaVector4 *result, const VmathSoaTransform3 *tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathSoaT3SetElem( VmathSoaTransform3 *result, int col, int row, vec_float4 val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline vec_float4 vmathSoaT3GetElem( const VmathSoaTransform3 *tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline void vmathSoaT3MulV3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline void vmathSoaT3MulP3( VmathSoaPoint3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaPoint3 *pnt ); /* * Multiply two 3x4 transformation matrices */ static inline void vmathSoaT3Mul( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline void vmathSoaT3MakeIdentity( VmathSoaTransform3 *result ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline void vmathSoaT3MakeRotationX( VmathSoaTransform3 *result, vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline void vmathSoaT3MakeRotationY( VmathSoaTransform3 *result, vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline void vmathSoaT3MakeRotationZ( VmathSoaTransform3 *result, vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline void vmathSoaT3MakeRotationZYX( VmathSoaTransform3 *result, const VmathSoaVector3 *radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline void vmathSoaT3MakeRotationAxis( VmathSoaTransform3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathSoaT3MakeRotationQ( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline void vmathSoaT3MakeScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline void vmathSoaT3MakeTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaT3AppendScale( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaT3PrependScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaTransform3 *tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline void vmathSoaT3MulPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline void vmathSoaT3AbsPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline void vmathSoaT3Inverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline void vmathSoaT3OrthoInverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ); /* * Conditionally select between two 3x4 transformation matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaT3Select( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaT3Print( const VmathSoaTransform3 *tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaT3Prints( const VmathSoaTransform3 *tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vec_soa.h" #include "quat_soa.h" #include "mat_soa.h" #endif ================================================ FILE: samples/vectormath/ppu/c/vectormath_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_C_V_PPU_H #define _VECTORMATH_SOA_C_V_PPU_H #include #include #include "vectormath_aos_v.h" #ifdef _VECTORMATH_DEBUG #include #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_SOA_C_TYPES_H #define _VECTORMATH_SOA_C_TYPES_H /* A set of four 3-D vectors in structure-of-arrays format */ typedef struct _VmathSoaVector3 { vec_float4 x; vec_float4 y; vec_float4 z; } VmathSoaVector3; /* A set of four 4-D vectors in structure-of-arrays format */ typedef struct _VmathSoaVector4 { vec_float4 x; vec_float4 y; vec_float4 z; vec_float4 w; } VmathSoaVector4; /* A set of four 3-D points in structure-of-arrays format */ typedef struct _VmathSoaPoint3 { vec_float4 x; vec_float4 y; vec_float4 z; } VmathSoaPoint3; /* A set of four quaternions in structure-of-arrays format */ typedef struct _VmathSoaQuat { vec_float4 x; vec_float4 y; vec_float4 z; vec_float4 w; } VmathSoaQuat; /* A set of four 3x3 matrices in structure-of-arrays format */ typedef struct _VmathSoaMatrix3 { VmathSoaVector3 col0; VmathSoaVector3 col1; VmathSoaVector3 col2; } VmathSoaMatrix3; /* A set of four 4x4 matrices in structure-of-arrays format */ typedef struct _VmathSoaMatrix4 { VmathSoaVector4 col0; VmathSoaVector4 col1; VmathSoaVector4 col2; VmathSoaVector4 col3; } VmathSoaMatrix4; /* A set of four 3x4 transformation matrices in structure-of-arrays format */ typedef struct _VmathSoaTransform3 { VmathSoaVector3 col0; VmathSoaVector3 col1; VmathSoaVector3 col2; VmathSoaVector3 col3; } VmathSoaTransform3; #endif /* * Construct a 3-D vector from x, y, and z elements */ static inline VmathSoaVector3 vmathSoaV3MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline VmathSoaVector3 vmathSoaV3MakeFromP3_V( VmathSoaPoint3 pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline VmathSoaVector3 vmathSoaV3MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 3-D vector */ static inline VmathSoaVector3 vmathSoaV3MakeFromAos_V( VmathVector3 vec ); /* * Insert four AoS 3-D vectors */ static inline VmathSoaVector3 vmathSoaV3MakeFrom4Aos_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3 ); /* * Extract four AoS 3-D vectors */ static inline void vmathSoaV3Get4Aos_V( VmathSoaVector3 vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 ); /* * Set the x element of a 3-D vector */ static inline void vmathSoaV3SetX_V( VmathSoaVector3 *result, vec_float4 x ); /* * Set the y element of a 3-D vector */ static inline void vmathSoaV3SetY_V( VmathSoaVector3 *result, vec_float4 y ); /* * Set the z element of a 3-D vector */ static inline void vmathSoaV3SetZ_V( VmathSoaVector3 *result, vec_float4 z ); /* * Get the x element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetX_V( VmathSoaVector3 vec ); /* * Get the y element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetY_V( VmathSoaVector3 vec ); /* * Get the z element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetZ_V( VmathSoaVector3 vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathSoaV3SetElem_V( VmathSoaVector3 *result, int idx, vec_float4 value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline vec_float4 vmathSoaV3GetElem_V( VmathSoaVector3 vec, int idx ); /* * Add two 3-D vectors */ static inline VmathSoaVector3 vmathSoaV3Add_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline VmathSoaVector3 vmathSoaV3Sub_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline VmathSoaPoint3 vmathSoaV3AddP3_V( VmathSoaVector3 vec, VmathSoaPoint3 pnt ); /* * Multiply a 3-D vector by a scalar */ static inline VmathSoaVector3 vmathSoaV3ScalarMul_V( VmathSoaVector3 vec, vec_float4 scalar ); /* * Divide a 3-D vector by a scalar */ static inline VmathSoaVector3 vmathSoaV3ScalarDiv_V( VmathSoaVector3 vec, vec_float4 scalar ); /* * Negate all elements of a 3-D vector */ static inline VmathSoaVector3 vmathSoaV3Neg_V( VmathSoaVector3 vec ); /* * Construct x axis */ static inline VmathSoaVector3 vmathSoaV3MakeXAxis_V( ); /* * Construct y axis */ static inline VmathSoaVector3 vmathSoaV3MakeYAxis_V( ); /* * Construct z axis */ static inline VmathSoaVector3 vmathSoaV3MakeZAxis_V( ); /* * Multiply two 3-D vectors per element */ static inline VmathSoaVector3 vmathSoaV3MulPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathSoaVector3 vmathSoaV3DivPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathSoaVector3 vmathSoaV3RecipPerElem_V( VmathSoaVector3 vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathSoaVector3 vmathSoaV3SqrtPerElem_V( VmathSoaVector3 vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathSoaVector3 vmathSoaV3RsqrtPerElem_V( VmathSoaVector3 vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline VmathSoaVector3 vmathSoaV3AbsPerElem_V( VmathSoaVector3 vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline VmathSoaVector3 vmathSoaV3CopySignPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Maximum of two 3-D vectors per element */ static inline VmathSoaVector3 vmathSoaV3MaxPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Minimum of two 3-D vectors per element */ static inline VmathSoaVector3 vmathSoaV3MinPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Maximum element of a 3-D vector */ static inline vec_float4 vmathSoaV3MaxElem_V( VmathSoaVector3 vec ); /* * Minimum element of a 3-D vector */ static inline vec_float4 vmathSoaV3MinElem_V( VmathSoaVector3 vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline vec_float4 vmathSoaV3Sum_V( VmathSoaVector3 vec ); /* * Compute the dot product of two 3-D vectors */ static inline vec_float4 vmathSoaV3Dot_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline vec_float4 vmathSoaV3LengthSqr_V( VmathSoaVector3 vec ); /* * Compute the length of a 3-D vector */ static inline vec_float4 vmathSoaV3Length_V( VmathSoaVector3 vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathSoaVector3 vmathSoaV3Normalize_V( VmathSoaVector3 vec ); /* * Compute cross product of two 3-D vectors */ static inline VmathSoaVector3 vmathSoaV3Cross_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Outer product of two 3-D vectors */ static inline VmathSoaMatrix3 vmathSoaV3Outer_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix */ static inline VmathSoaVector3 vmathSoaV3RowMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat ); /* * Cross-product matrix of a 3-D vector */ static inline VmathSoaMatrix3 vmathSoaV3CrossMatrix_V( VmathSoaVector3 vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline VmathSoaMatrix3 vmathSoaV3CrossMatrixMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathSoaVector3 vmathSoaV3Lerp_V( vec_float4 t, VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathSoaVector3 vmathSoaV3Slerp_V( vec_float4 t, VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 ); /* * Conditionally select between two 3-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaVector3 vmathSoaV3Select_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_uint4 select1 ); /* * Load four three-float 3-D vectors, stored in three quadwords */ static inline void vmathSoaV3LoadXYZArray_V( VmathSoaVector3 *vec, const vec_float4 *threeQuads ); /* * Store four slots of an SoA 3-D vector in three quadwords */ static inline void vmathSoaV3StoreXYZArray_V( VmathSoaVector3 vec, vec_float4 *threeQuads ); /* * Store eight slots of two SoA 3-D vectors as half-floats */ static inline void vmathSoaV3StoreHalfFloats_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV3Print_V( VmathSoaVector3 vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV3Prints_V( VmathSoaVector3 vec, const char *name ); #endif /* * Construct a 4-D vector from x, y, z, and w elements */ static inline VmathSoaVector4 vmathSoaV4MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline VmathSoaVector4 vmathSoaV4MakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline VmathSoaVector4 vmathSoaV4MakeFromV3_V( VmathSoaVector3 vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline VmathSoaVector4 vmathSoaV4MakeFromP3_V( VmathSoaPoint3 pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline VmathSoaVector4 vmathSoaV4MakeFromQ_V( VmathSoaQuat quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline VmathSoaVector4 vmathSoaV4MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 4-D vector */ static inline VmathSoaVector4 vmathSoaV4MakeFromAos_V( VmathVector4 vec ); /* * Insert four AoS 4-D vectors */ static inline VmathSoaVector4 vmathSoaV4MakeFrom4Aos_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3 ); /* * Extract four AoS 4-D vectors */ static inline void vmathSoaV4Get4Aos_V( VmathSoaVector4 vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathSoaV4SetXYZ_V( VmathSoaVector4 *result, VmathSoaVector3 vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline VmathSoaVector3 vmathSoaV4GetXYZ_V( VmathSoaVector4 vec ); /* * Set the x element of a 4-D vector */ static inline void vmathSoaV4SetX_V( VmathSoaVector4 *result, vec_float4 x ); /* * Set the y element of a 4-D vector */ static inline void vmathSoaV4SetY_V( VmathSoaVector4 *result, vec_float4 y ); /* * Set the z element of a 4-D vector */ static inline void vmathSoaV4SetZ_V( VmathSoaVector4 *result, vec_float4 z ); /* * Set the w element of a 4-D vector */ static inline void vmathSoaV4SetW_V( VmathSoaVector4 *result, vec_float4 w ); /* * Get the x element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetX_V( VmathSoaVector4 vec ); /* * Get the y element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetY_V( VmathSoaVector4 vec ); /* * Get the z element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetZ_V( VmathSoaVector4 vec ); /* * Get the w element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetW_V( VmathSoaVector4 vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathSoaV4SetElem_V( VmathSoaVector4 *result, int idx, vec_float4 value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline vec_float4 vmathSoaV4GetElem_V( VmathSoaVector4 vec, int idx ); /* * Add two 4-D vectors */ static inline VmathSoaVector4 vmathSoaV4Add_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline VmathSoaVector4 vmathSoaV4Sub_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline VmathSoaVector4 vmathSoaV4ScalarMul_V( VmathSoaVector4 vec, vec_float4 scalar ); /* * Divide a 4-D vector by a scalar */ static inline VmathSoaVector4 vmathSoaV4ScalarDiv_V( VmathSoaVector4 vec, vec_float4 scalar ); /* * Negate all elements of a 4-D vector */ static inline VmathSoaVector4 vmathSoaV4Neg_V( VmathSoaVector4 vec ); /* * Construct x axis */ static inline VmathSoaVector4 vmathSoaV4MakeXAxis_V( ); /* * Construct y axis */ static inline VmathSoaVector4 vmathSoaV4MakeYAxis_V( ); /* * Construct z axis */ static inline VmathSoaVector4 vmathSoaV4MakeZAxis_V( ); /* * Construct w axis */ static inline VmathSoaVector4 vmathSoaV4MakeWAxis_V( ); /* * Multiply two 4-D vectors per element */ static inline VmathSoaVector4 vmathSoaV4MulPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathSoaVector4 vmathSoaV4DivPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathSoaVector4 vmathSoaV4RecipPerElem_V( VmathSoaVector4 vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathSoaVector4 vmathSoaV4SqrtPerElem_V( VmathSoaVector4 vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathSoaVector4 vmathSoaV4RsqrtPerElem_V( VmathSoaVector4 vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline VmathSoaVector4 vmathSoaV4AbsPerElem_V( VmathSoaVector4 vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline VmathSoaVector4 vmathSoaV4CopySignPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Maximum of two 4-D vectors per element */ static inline VmathSoaVector4 vmathSoaV4MaxPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Minimum of two 4-D vectors per element */ static inline VmathSoaVector4 vmathSoaV4MinPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Maximum element of a 4-D vector */ static inline vec_float4 vmathSoaV4MaxElem_V( VmathSoaVector4 vec ); /* * Minimum element of a 4-D vector */ static inline vec_float4 vmathSoaV4MinElem_V( VmathSoaVector4 vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline vec_float4 vmathSoaV4Sum_V( VmathSoaVector4 vec ); /* * Compute the dot product of two 4-D vectors */ static inline vec_float4 vmathSoaV4Dot_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline vec_float4 vmathSoaV4LengthSqr_V( VmathSoaVector4 vec ); /* * Compute the length of a 4-D vector */ static inline vec_float4 vmathSoaV4Length_V( VmathSoaVector4 vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathSoaVector4 vmathSoaV4Normalize_V( VmathSoaVector4 vec ); /* * Outer product of two 4-D vectors */ static inline VmathSoaMatrix4 vmathSoaV4Outer_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathSoaVector4 vmathSoaV4Lerp_V( vec_float4 t, VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathSoaVector4 vmathSoaV4Slerp_V( vec_float4 t, VmathSoaVector4 unitVec0, VmathSoaVector4 unitVec1 ); /* * Conditionally select between two 4-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaVector4 vmathSoaV4Select_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1, vec_uint4 select1 ); /* * Store four slots of an SoA 4-D vector as half-floats */ static inline void vmathSoaV4StoreHalfFloats_V( VmathSoaVector4 vec, vec_ushort8 *twoQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV4Print_V( VmathSoaVector4 vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV4Prints_V( VmathSoaVector4 vec, const char *name ); #endif /* * Construct a 3-D point from x, y, and z elements */ static inline VmathSoaPoint3 vmathSoaP3MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline VmathSoaPoint3 vmathSoaP3MakeFromV3_V( VmathSoaVector3 vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline VmathSoaPoint3 vmathSoaP3MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 3-D point */ static inline VmathSoaPoint3 vmathSoaP3MakeFromAos_V( VmathPoint3 pnt ); /* * Insert four AoS 3-D points */ static inline VmathSoaPoint3 vmathSoaP3MakeFrom4Aos_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3 ); /* * Extract four AoS 3-D points */ static inline void vmathSoaP3Get4Aos_V( VmathSoaPoint3 pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 ); /* * Set the x element of a 3-D point */ static inline void vmathSoaP3SetX_V( VmathSoaPoint3 *result, vec_float4 x ); /* * Set the y element of a 3-D point */ static inline void vmathSoaP3SetY_V( VmathSoaPoint3 *result, vec_float4 y ); /* * Set the z element of a 3-D point */ static inline void vmathSoaP3SetZ_V( VmathSoaPoint3 *result, vec_float4 z ); /* * Get the x element of a 3-D point */ static inline vec_float4 vmathSoaP3GetX_V( VmathSoaPoint3 pnt ); /* * Get the y element of a 3-D point */ static inline vec_float4 vmathSoaP3GetY_V( VmathSoaPoint3 pnt ); /* * Get the z element of a 3-D point */ static inline vec_float4 vmathSoaP3GetZ_V( VmathSoaPoint3 pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathSoaP3SetElem_V( VmathSoaPoint3 *result, int idx, vec_float4 value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline vec_float4 vmathSoaP3GetElem_V( VmathSoaPoint3 pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline VmathSoaVector3 vmathSoaP3Sub_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline VmathSoaPoint3 vmathSoaP3AddV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline VmathSoaPoint3 vmathSoaP3SubV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec ); /* * Multiply two 3-D points per element */ static inline VmathSoaPoint3 vmathSoaP3MulPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathSoaPoint3 vmathSoaP3DivPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathSoaPoint3 vmathSoaP3RecipPerElem_V( VmathSoaPoint3 pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathSoaPoint3 vmathSoaP3SqrtPerElem_V( VmathSoaPoint3 pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathSoaPoint3 vmathSoaP3RsqrtPerElem_V( VmathSoaPoint3 pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline VmathSoaPoint3 vmathSoaP3AbsPerElem_V( VmathSoaPoint3 pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline VmathSoaPoint3 vmathSoaP3CopySignPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Maximum of two 3-D points per element */ static inline VmathSoaPoint3 vmathSoaP3MaxPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Minimum of two 3-D points per element */ static inline VmathSoaPoint3 vmathSoaP3MinPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Maximum element of a 3-D point */ static inline vec_float4 vmathSoaP3MaxElem_V( VmathSoaPoint3 pnt ); /* * Minimum element of a 3-D point */ static inline vec_float4 vmathSoaP3MinElem_V( VmathSoaPoint3 pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline vec_float4 vmathSoaP3Sum_V( VmathSoaPoint3 pnt ); /* * Apply uniform scale to a 3-D point */ static inline VmathSoaPoint3 vmathSoaP3Scale_V( VmathSoaPoint3 pnt, vec_float4 scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline VmathSoaPoint3 vmathSoaP3NonUniformScale_V( VmathSoaPoint3 pnt, VmathSoaVector3 scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline vec_float4 vmathSoaP3Projection_V( VmathSoaPoint3 pnt, VmathSoaVector3 unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline vec_float4 vmathSoaP3DistSqrFromOrigin_V( VmathSoaPoint3 pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline vec_float4 vmathSoaP3DistFromOrigin_V( VmathSoaPoint3 pnt ); /* * Compute the square of the distance between two 3-D points */ static inline vec_float4 vmathSoaP3DistSqr_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Compute the distance between two 3-D points */ static inline vec_float4 vmathSoaP3Dist_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathSoaPoint3 vmathSoaP3Lerp_V( vec_float4 t, VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Conditionally select between two 3-D points * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaPoint3 vmathSoaP3Select_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_uint4 select1 ); /* * Load four three-float 3-D points, stored in three quadwords */ static inline void vmathSoaP3LoadXYZArray_V( VmathSoaPoint3 *pnt, const vec_float4 *threeQuads ); /* * Store four slots of an SoA 3-D point in three quadwords */ static inline void vmathSoaP3StoreXYZArray_V( VmathSoaPoint3 pnt, vec_float4 *threeQuads ); /* * Store eight slots of two SoA 3-D points as half-floats */ static inline void vmathSoaP3StoreHalfFloats_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaP3Print_V( VmathSoaPoint3 pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaP3Prints_V( VmathSoaPoint3 pnt, const char *name ); #endif /* * Construct a quaternion from x, y, z, and w elements */ static inline VmathSoaQuat vmathSoaQMakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline VmathSoaQuat vmathSoaQMakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline VmathSoaQuat vmathSoaQMakeFromV4_V( VmathSoaVector4 vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline VmathSoaQuat vmathSoaQMakeFromM3_V( VmathSoaMatrix3 rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline VmathSoaQuat vmathSoaQMakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS quaternion */ static inline VmathSoaQuat vmathSoaQMakeFromAos_V( VmathQuat quat ); /* * Insert four AoS quaternions */ static inline VmathSoaQuat vmathSoaQMakeFrom4Aos_V( VmathQuat quat0, VmathQuat quat1, VmathQuat quat2, VmathQuat quat3 ); /* * Extract four AoS quaternions */ static inline void vmathSoaQGet4Aos_V( VmathSoaQuat quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathSoaQSetXYZ_V( VmathSoaQuat *result, VmathSoaVector3 vec ); /* * Get the x, y, and z elements of a quaternion */ static inline VmathSoaVector3 vmathSoaQGetXYZ_V( VmathSoaQuat quat ); /* * Set the x element of a quaternion */ static inline void vmathSoaQSetX_V( VmathSoaQuat *result, vec_float4 x ); /* * Set the y element of a quaternion */ static inline void vmathSoaQSetY_V( VmathSoaQuat *result, vec_float4 y ); /* * Set the z element of a quaternion */ static inline void vmathSoaQSetZ_V( VmathSoaQuat *result, vec_float4 z ); /* * Set the w element of a quaternion */ static inline void vmathSoaQSetW_V( VmathSoaQuat *result, vec_float4 w ); /* * Get the x element of a quaternion */ static inline vec_float4 vmathSoaQGetX_V( VmathSoaQuat quat ); /* * Get the y element of a quaternion */ static inline vec_float4 vmathSoaQGetY_V( VmathSoaQuat quat ); /* * Get the z element of a quaternion */ static inline vec_float4 vmathSoaQGetZ_V( VmathSoaQuat quat ); /* * Get the w element of a quaternion */ static inline vec_float4 vmathSoaQGetW_V( VmathSoaQuat quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathSoaQSetElem_V( VmathSoaQuat *result, int idx, vec_float4 value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline vec_float4 vmathSoaQGetElem_V( VmathSoaQuat quat, int idx ); /* * Add two quaternions */ static inline VmathSoaQuat vmathSoaQAdd_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Subtract a quaternion from another quaternion */ static inline VmathSoaQuat vmathSoaQSub_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Multiply two quaternions */ static inline VmathSoaQuat vmathSoaQMul_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Multiply a quaternion by a scalar */ static inline VmathSoaQuat vmathSoaQScalarMul_V( VmathSoaQuat quat, vec_float4 scalar ); /* * Divide a quaternion by a scalar */ static inline VmathSoaQuat vmathSoaQScalarDiv_V( VmathSoaQuat quat, vec_float4 scalar ); /* * Negate all elements of a quaternion */ static inline VmathSoaQuat vmathSoaQNeg_V( VmathSoaQuat quat ); /* * Construct an identity quaternion */ static inline VmathSoaQuat vmathSoaQMakeIdentity_V( ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline VmathSoaQuat vmathSoaQMakeRotationArc_V( VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline VmathSoaQuat vmathSoaQMakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline VmathSoaQuat vmathSoaQMakeRotationX_V( vec_float4 radians ); /* * Construct a quaternion to rotate around the y axis */ static inline VmathSoaQuat vmathSoaQMakeRotationY_V( vec_float4 radians ); /* * Construct a quaternion to rotate around the z axis */ static inline VmathSoaQuat vmathSoaQMakeRotationZ_V( vec_float4 radians ); /* * Compute the conjugate of a quaternion */ static inline VmathSoaQuat vmathSoaQConj_V( VmathSoaQuat quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline VmathSoaVector3 vmathSoaQRotate_V( VmathSoaQuat unitQuat, VmathSoaVector3 vec ); /* * Compute the dot product of two quaternions */ static inline vec_float4 vmathSoaQDot_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Compute the norm of a quaternion */ static inline vec_float4 vmathSoaQNorm_V( VmathSoaQuat quat ); /* * Compute the length of a quaternion */ static inline vec_float4 vmathSoaQLength_V( VmathSoaQuat quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline VmathSoaQuat vmathSoaQNormalize_V( VmathSoaQuat quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathSoaQuat vmathSoaQLerp_V( vec_float4 t, VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline VmathSoaQuat vmathSoaQSlerp_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline VmathSoaQuat vmathSoaQSquad_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1, VmathSoaQuat unitQuat2, VmathSoaQuat unitQuat3 ); /* * Conditionally select between two quaternions * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaQuat vmathSoaQSelect_V( VmathSoaQuat quat0, VmathSoaQuat quat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaQPrint_V( VmathSoaQuat quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaQPrints_V( VmathSoaQuat quat, const char *name ); #endif /* * Construct a 3x3 matrix containing the specified columns */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromCols_V( VmathSoaVector3 col0, VmathSoaVector3 col1, VmathSoaVector3 col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromQ_V( VmathSoaQuat unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromAos_V( VmathMatrix3 mat ); /* * Insert four AoS 3x3 matrices */ static inline VmathSoaMatrix3 vmathSoaM3MakeFrom4Aos_V( VmathMatrix3 mat0, VmathMatrix3 mat1, VmathMatrix3 mat2, VmathMatrix3 mat3 ); /* * Extract four AoS 3x3 matrices */ static inline void vmathSoaM3Get4Aos_V( VmathSoaMatrix3 mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathSoaM3SetCol0_V( VmathSoaMatrix3 *result, VmathSoaVector3 col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathSoaM3SetCol1_V( VmathSoaMatrix3 *result, VmathSoaVector3 col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathSoaM3SetCol2_V( VmathSoaMatrix3 *result, VmathSoaVector3 col2 ); /* * Get column 0 of a 3x3 matrix */ static inline VmathSoaVector3 vmathSoaM3GetCol0_V( VmathSoaMatrix3 mat ); /* * Get column 1 of a 3x3 matrix */ static inline VmathSoaVector3 vmathSoaM3GetCol1_V( VmathSoaMatrix3 mat ); /* * Get column 2 of a 3x3 matrix */ static inline VmathSoaVector3 vmathSoaM3GetCol2_V( VmathSoaMatrix3 mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3SetCol_V( VmathSoaMatrix3 *result, int col, VmathSoaVector3 vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3SetRow_V( VmathSoaMatrix3 *result, int row, VmathSoaVector3 vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline VmathSoaVector3 vmathSoaM3GetCol_V( VmathSoaMatrix3 mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline VmathSoaVector3 vmathSoaM3GetRow_V( VmathSoaMatrix3 mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathSoaM3SetElem_V( VmathSoaMatrix3 *result, int col, int row, vec_float4 val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline vec_float4 vmathSoaM3GetElem_V( VmathSoaMatrix3 mat, int col, int row ); /* * Add two 3x3 matrices */ static inline VmathSoaMatrix3 vmathSoaM3Add_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3Sub_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3Neg_V( VmathSoaMatrix3 mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline VmathSoaMatrix3 vmathSoaM3ScalarMul_V( VmathSoaMatrix3 mat, vec_float4 scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline VmathSoaVector3 vmathSoaM3MulV3_V( VmathSoaMatrix3 mat, VmathSoaVector3 vec ); /* * Multiply two 3x3 matrices */ static inline VmathSoaMatrix3 vmathSoaM3Mul_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ); /* * Construct an identity 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3MakeIdentity_V( ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationX_V( vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationY_V( vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationZ_V( vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationQ_V( VmathSoaQuat unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline VmathSoaMatrix3 vmathSoaM3MakeScale_V( VmathSoaVector3 scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaMatrix3 vmathSoaM3AppendScale_V( VmathSoaMatrix3 mat, VmathSoaVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaMatrix3 vmathSoaM3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix3 mat ); /* * Multiply two 3x3 matrices per element */ static inline VmathSoaMatrix3 vmathSoaM3MulPerElem_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline VmathSoaMatrix3 vmathSoaM3AbsPerElem_V( VmathSoaMatrix3 mat ); /* * Transpose of a 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3Transpose_V( VmathSoaMatrix3 mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathSoaMatrix3 vmathSoaM3Inverse_V( VmathSoaMatrix3 mat ); /* * Determinant of a 3x3 matrix */ static inline vec_float4 vmathSoaM3Determinant_V( VmathSoaMatrix3 mat ); /* * Conditionally select between two 3x3 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaMatrix3 vmathSoaM3Select_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM3Print_V( VmathSoaMatrix3 mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM3Prints_V( VmathSoaMatrix3 mat, const char *name ); #endif /* * Construct a 4x4 matrix containing the specified columns */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromCols_V( VmathSoaVector4 col0, VmathSoaVector4 col1, VmathSoaVector4 col2, VmathSoaVector4 col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromT3_V( VmathSoaTransform3 mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromM3V3_V( VmathSoaMatrix3 mat, VmathSoaVector3 translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromAos_V( VmathMatrix4 mat ); /* * Insert four AoS 4x4 matrices */ static inline VmathSoaMatrix4 vmathSoaM4MakeFrom4Aos_V( VmathMatrix4 mat0, VmathMatrix4 mat1, VmathMatrix4 mat2, VmathMatrix4 mat3 ); /* * Extract four AoS 4x4 matrices */ static inline void vmathSoaM4Get4Aos_V( VmathSoaMatrix4 mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathSoaM4SetUpper3x3_V( VmathSoaMatrix4 *result, VmathSoaMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline VmathSoaMatrix3 vmathSoaM4GetUpper3x3_V( VmathSoaMatrix4 mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathSoaM4SetTranslation_V( VmathSoaMatrix4 *result, VmathSoaVector3 translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline VmathSoaVector3 vmathSoaM4GetTranslation_V( VmathSoaMatrix4 mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathSoaM4SetCol0_V( VmathSoaMatrix4 *result, VmathSoaVector4 col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathSoaM4SetCol1_V( VmathSoaMatrix4 *result, VmathSoaVector4 col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathSoaM4SetCol2_V( VmathSoaMatrix4 *result, VmathSoaVector4 col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathSoaM4SetCol3_V( VmathSoaMatrix4 *result, VmathSoaVector4 col3 ); /* * Get column 0 of a 4x4 matrix */ static inline VmathSoaVector4 vmathSoaM4GetCol0_V( VmathSoaMatrix4 mat ); /* * Get column 1 of a 4x4 matrix */ static inline VmathSoaVector4 vmathSoaM4GetCol1_V( VmathSoaMatrix4 mat ); /* * Get column 2 of a 4x4 matrix */ static inline VmathSoaVector4 vmathSoaM4GetCol2_V( VmathSoaMatrix4 mat ); /* * Get column 3 of a 4x4 matrix */ static inline VmathSoaVector4 vmathSoaM4GetCol3_V( VmathSoaMatrix4 mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4SetCol_V( VmathSoaMatrix4 *result, int col, VmathSoaVector4 vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4SetRow_V( VmathSoaMatrix4 *result, int row, VmathSoaVector4 vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline VmathSoaVector4 vmathSoaM4GetCol_V( VmathSoaMatrix4 mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline VmathSoaVector4 vmathSoaM4GetRow_V( VmathSoaMatrix4 mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathSoaM4SetElem_V( VmathSoaMatrix4 *result, int col, int row, vec_float4 val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline vec_float4 vmathSoaM4GetElem_V( VmathSoaMatrix4 mat, int col, int row ); /* * Add two 4x4 matrices */ static inline VmathSoaMatrix4 vmathSoaM4Add_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4Sub_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4Neg_V( VmathSoaMatrix4 mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline VmathSoaMatrix4 vmathSoaM4ScalarMul_V( VmathSoaMatrix4 mat, vec_float4 scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline VmathSoaVector4 vmathSoaM4MulV4_V( VmathSoaMatrix4 mat, VmathSoaVector4 vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline VmathSoaVector4 vmathSoaM4MulV3_V( VmathSoaMatrix4 mat, VmathSoaVector3 vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline VmathSoaVector4 vmathSoaM4MulP3_V( VmathSoaMatrix4 mat, VmathSoaPoint3 pnt ); /* * Multiply two 4x4 matrices */ static inline VmathSoaMatrix4 vmathSoaM4Mul_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline VmathSoaMatrix4 vmathSoaM4MulT3_V( VmathSoaMatrix4 mat, VmathSoaTransform3 tfrm ); /* * Construct an identity 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakeIdentity_V( ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationX_V( vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationY_V( vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationZ_V( vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationQ_V( VmathSoaQuat unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline VmathSoaMatrix4 vmathSoaM4MakeScale_V( VmathSoaVector3 scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline VmathSoaMatrix4 vmathSoaM4MakeTranslation_V( VmathSoaVector3 translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline VmathSoaMatrix4 vmathSoaM4MakeLookAt_V( VmathSoaPoint3 eyePos, VmathSoaPoint3 lookAtPos, VmathSoaVector3 upVec ); /* * Construct a perspective projection matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakePerspective_V( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline VmathSoaMatrix4 vmathSoaM4MakeFrustum_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); /* * Construct an orthographic projection matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakeOrthographic_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaMatrix4 vmathSoaM4AppendScale_V( VmathSoaMatrix4 mat, VmathSoaVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaMatrix4 vmathSoaM4PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix4 mat ); /* * Multiply two 4x4 matrices per element */ static inline VmathSoaMatrix4 vmathSoaM4MulPerElem_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline VmathSoaMatrix4 vmathSoaM4AbsPerElem_V( VmathSoaMatrix4 mat ); /* * Transpose of a 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4Transpose_V( VmathSoaMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathSoaMatrix4 vmathSoaM4Inverse_V( VmathSoaMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline VmathSoaMatrix4 vmathSoaM4AffineInverse_V( VmathSoaMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline VmathSoaMatrix4 vmathSoaM4OrthoInverse_V( VmathSoaMatrix4 mat ); /* * Determinant of a 4x4 matrix */ static inline vec_float4 vmathSoaM4Determinant_V( VmathSoaMatrix4 mat ); /* * Conditionally select between two 4x4 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaMatrix4 vmathSoaM4Select_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM4Print_V( VmathSoaMatrix4 mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM4Prints_V( VmathSoaMatrix4 mat, const char *name ); #endif /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline VmathSoaTransform3 vmathSoaT3MakeFromCols_V( VmathSoaVector3 col0, VmathSoaVector3 col1, VmathSoaVector3 col2, VmathSoaVector3 col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline VmathSoaTransform3 vmathSoaT3MakeFromM3V3_V( VmathSoaMatrix3 tfrm, VmathSoaVector3 translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline VmathSoaTransform3 vmathSoaT3MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline VmathSoaTransform3 vmathSoaT3MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 3x4 transformation matrix */ static inline VmathSoaTransform3 vmathSoaT3MakeFromAos_V( VmathTransform3 tfrm ); /* * Insert four AoS 3x4 transformation matrices */ static inline VmathSoaTransform3 vmathSoaT3MakeFrom4Aos_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, VmathTransform3 tfrm2, VmathTransform3 tfrm3 ); /* * Extract four AoS 3x4 transformation matrices */ static inline void vmathSoaT3Get4Aos_V( VmathSoaTransform3 tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathSoaT3SetUpper3x3_V( VmathSoaTransform3 *result, VmathSoaMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline VmathSoaMatrix3 vmathSoaT3GetUpper3x3_V( VmathSoaTransform3 tfrm ); /* * Set translation component */ static inline void vmathSoaT3SetTranslation_V( VmathSoaTransform3 *result, VmathSoaVector3 translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetTranslation_V( VmathSoaTransform3 tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol0_V( VmathSoaTransform3 *result, VmathSoaVector3 col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol1_V( VmathSoaTransform3 *result, VmathSoaVector3 col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol2_V( VmathSoaTransform3 *result, VmathSoaVector3 col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol3_V( VmathSoaTransform3 *result, VmathSoaVector3 col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetCol0_V( VmathSoaTransform3 tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetCol1_V( VmathSoaTransform3 tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetCol2_V( VmathSoaTransform3 tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetCol3_V( VmathSoaTransform3 tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3SetCol_V( VmathSoaTransform3 *result, int col, VmathSoaVector3 vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3SetRow_V( VmathSoaTransform3 *result, int row, VmathSoaVector4 vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline VmathSoaVector3 vmathSoaT3GetCol_V( VmathSoaTransform3 tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline VmathSoaVector4 vmathSoaT3GetRow_V( VmathSoaTransform3 tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathSoaT3SetElem_V( VmathSoaTransform3 *result, int col, int row, vec_float4 val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline vec_float4 vmathSoaT3GetElem_V( VmathSoaTransform3 tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline VmathSoaVector3 vmathSoaT3MulV3_V( VmathSoaTransform3 tfrm, VmathSoaVector3 vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline VmathSoaPoint3 vmathSoaT3MulP3_V( VmathSoaTransform3 tfrm, VmathSoaPoint3 pnt ); /* * Multiply two 3x4 transformation matrices */ static inline VmathSoaTransform3 vmathSoaT3Mul_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline VmathSoaTransform3 vmathSoaT3MakeIdentity_V( ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationX_V( vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationY_V( vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationZ_V( vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationQ_V( VmathSoaQuat unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline VmathSoaTransform3 vmathSoaT3MakeScale_V( VmathSoaVector3 scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline VmathSoaTransform3 vmathSoaT3MakeTranslation_V( VmathSoaVector3 translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaTransform3 vmathSoaT3AppendScale_V( VmathSoaTransform3 tfrm, VmathSoaVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaTransform3 vmathSoaT3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaTransform3 tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline VmathSoaTransform3 vmathSoaT3MulPerElem_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline VmathSoaTransform3 vmathSoaT3AbsPerElem_V( VmathSoaTransform3 tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline VmathSoaTransform3 vmathSoaT3Inverse_V( VmathSoaTransform3 tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline VmathSoaTransform3 vmathSoaT3OrthoInverse_V( VmathSoaTransform3 tfrm ); /* * Conditionally select between two 3x4 transformation matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaTransform3 vmathSoaT3Select_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaT3Print_V( VmathSoaTransform3 tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaT3Prints_V( VmathSoaTransform3 tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vectormath_soa.h" #include "vec_soa_v.h" #include "quat_soa_v.h" #include "mat_soa_v.h" #endif ================================================ FILE: samples/vectormath/ppu/cpp/boolInVec.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _BOOLINVEC_H #define _BOOLINVEC_H #include #include #include "../c/vec_types.h" #undef bool namespace Vectormath { class floatInVec; //-------------------------------------------------------------------------------------------------- // boolInVec class // class boolInVec { private: vec_uint4 mData; inline boolInVec(vec_uint4 vec); public: inline boolInVec() {} // matches standard type conversions // inline boolInVec(floatInVec vec); // explicit cast from bool // explicit inline boolInVec(bool scalar); #ifdef _VECTORMATH_NO_SCALAR_CAST // explicit cast to bool // inline bool getAsBool() const; #else // implicit cast to bool // inline operator bool() const; #endif // get vector data // bool value is splatted across all word slots of vector as 0 (false) or -1 (true) // inline vec_uint4 get128() const; // operators // inline const boolInVec operator ! () const; inline boolInVec& operator = (boolInVec vec); inline boolInVec& operator &= (boolInVec vec); inline boolInVec& operator ^= (boolInVec vec); inline boolInVec& operator |= (boolInVec vec); // friend functions // friend inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); friend inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); friend inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); friend inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); friend inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); friend inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); }; //-------------------------------------------------------------------------------------------------- // boolInVec functions // // operators // inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); // select between vec0 and vec1 using boolInVec. // false selects vec0, true selects vec1 // inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); } // namespace Vectormath //-------------------------------------------------------------------------------------------------- // boolInVec implementation // #include "floatInVec.h" namespace Vectormath { inline boolInVec::boolInVec(vec_uint4 vec) { mData = vec; } inline boolInVec::boolInVec(floatInVec vec) { *this = (vec != floatInVec(0.0f)); } inline boolInVec::boolInVec(bool scalar) { #ifdef __GNUC__ if (__builtin_constant_p(scalar)) { const unsigned int mask = -(int)scalar; mData = (vec_uint4){mask, mask, mask, mask}; } else #endif { unsigned int mask = -(int)scalar; vec_uint4 vec = vec_ld(0, &mask); mData = vec_splat(vec_perm(vec, vec, vec_lvsl(0, &mask)), 0); } } #ifdef _VECTORMATH_NO_SCALAR_CAST inline bool boolInVec::getAsBool() const #else inline boolInVec::operator bool() const #endif { return vec_all_gt(mData, ((vec_uint4){0,0,0,0})); } inline vec_uint4 boolInVec::get128() const { return mData; } inline const boolInVec boolInVec::operator ! () const { return boolInVec(vec_nor(mData, mData)); } inline boolInVec& boolInVec::operator = (boolInVec vec) { mData = vec.mData; return *this; } inline boolInVec& boolInVec::operator &= (boolInVec vec) { *this = *this & vec; return *this; } inline boolInVec& boolInVec::operator ^= (boolInVec vec) { *this = *this ^ vec; return *this; } inline boolInVec& boolInVec::operator |= (boolInVec vec) { *this = *this | vec; return *this; } inline const boolInVec operator == (boolInVec vec0, boolInVec vec1) { return boolInVec((vec_uint4)vec_cmpeq(vec0.get128(), vec1.get128())); } inline const boolInVec operator != (boolInVec vec0, boolInVec vec1) { return !(vec0 == vec1); } inline const boolInVec operator & (boolInVec vec0, boolInVec vec1) { return boolInVec(vec_and(vec0.get128(), vec1.get128())); } inline const boolInVec operator | (boolInVec vec0, boolInVec vec1) { return boolInVec(vec_or(vec0.get128(), vec1.get128())); } inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1) { return boolInVec(vec_xor(vec0.get128(), vec1.get128())); } inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1) { return boolInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); } } // namespace Vectormath #endif // boolInVec_h ================================================ FILE: samples/vectormath/ppu/cpp/floatInVec.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _FLOATINVEC_H #define _FLOATINVEC_H #include #include #include #include #include "../c/vec_types.h" #undef bool namespace Vectormath { class boolInVec; //-------------------------------------------------------------------------------------------------- // floatInVec class // class floatInVec { private: vec_float4 mData; inline floatInVec(vec_float4 vec); public: inline floatInVec() {} // matches standard type conversions // inline floatInVec(boolInVec vec); // construct from a slot of vec_float4 // inline floatInVec(vec_float4 vec, int slot); // explicit cast from float // explicit inline floatInVec(float scalar); #ifdef _VECTORMATH_NO_SCALAR_CAST // explicit cast to float // inline float getAsFloat() const; #else // implicit cast to float // inline operator float() const; #endif // get vector data // float value is splatted across all word slots of vector // inline vec_float4 get128() const; // operators // inline const floatInVec operator ++ (int); inline const floatInVec operator -- (int); inline floatInVec& operator ++ (); inline floatInVec& operator -- (); inline const floatInVec operator - () const; inline floatInVec& operator = (floatInVec vec); inline floatInVec& operator *= (floatInVec vec); inline floatInVec& operator /= (floatInVec vec); inline floatInVec& operator += (floatInVec vec); inline floatInVec& operator -= (floatInVec vec); // friend functions // friend inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); friend inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); friend inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); friend inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); friend inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); }; //-------------------------------------------------------------------------------------------------- // floatInVec functions // // operators // inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); // select between vec0 and vec1 using boolInVec. // false selects vec0, true selects vec1 // inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); } // namespace Vectormath //-------------------------------------------------------------------------------------------------- // floatInVec implementation // #include "boolInVec.h" namespace Vectormath { inline floatInVec::floatInVec(vec_float4 vec) { mData = vec; } inline floatInVec::floatInVec(boolInVec vec) { mData = vec_ctf(vec_sub((vec_uint4){0,0,0,0}, vec.get128()), 0); } inline floatInVec::floatInVec(vec_float4 vec, int slot) { #ifdef __GNUC__ if (__builtin_constant_p(slot)) { mData = vec_splat(vec, slot); } else #endif { const vec_uchar16 shiftpattern = vec_lvsl(0, (float *)(size_t)(slot << 2)); mData = vec_splat(vec_perm(vec, vec, shiftpattern), 0); } } inline floatInVec::floatInVec(float scalar) { #ifdef __GNUC__ if (__builtin_constant_p(scalar)) { mData = (vec_float4){scalar, scalar, scalar, scalar}; } else #endif { vec_float4 vec = vec_ld(0, &scalar); mData = vec_splat(vec_perm(vec, vec, vec_lvsl(0, &scalar)), 0); } } #ifdef _VECTORMATH_NO_SCALAR_CAST inline float floatInVec::getAsFloat() const #else inline floatInVec::operator float() const #endif { return *((float *)&mData); } inline vec_float4 floatInVec::get128() const { return mData; } inline const floatInVec floatInVec::operator ++ (int) { vec_float4 olddata = mData; operator ++(); return floatInVec(olddata); } inline const floatInVec floatInVec::operator -- (int) { vec_float4 olddata = mData; operator --(); return floatInVec(olddata); } inline floatInVec& floatInVec::operator ++ () { *this += floatInVec((vec_float4){1.0f,1.0f,1.0f,1.0f}); return *this; } inline floatInVec& floatInVec::operator -- () { *this -= floatInVec((vec_float4){1.0f,1.0f,1.0f,1.0f}); return *this; } inline const floatInVec floatInVec::operator - () const { return floatInVec((vec_float4)vec_xor((vec_uint4)mData, (vec_uint4){0x80000000,0x80000000,0x80000000,0x80000000})); } inline floatInVec& floatInVec::operator = (floatInVec vec) { mData = vec.mData; return *this; } inline floatInVec& floatInVec::operator *= (floatInVec vec) { *this = *this * vec; return *this; } inline floatInVec& floatInVec::operator /= (floatInVec vec) { *this = *this / vec; return *this; } inline floatInVec& floatInVec::operator += (floatInVec vec) { *this = *this + vec; return *this; } inline floatInVec& floatInVec::operator -= (floatInVec vec) { *this = *this - vec; return *this; } inline const floatInVec operator * (floatInVec vec0, floatInVec vec1) { return floatInVec(vec_madd(vec0.get128(), vec1.get128(), (vec_float4){0,0,0,0})); } inline const floatInVec operator / (floatInVec num, floatInVec den) { return floatInVec(divf4(num.get128(), den.get128())); } inline const floatInVec operator + (floatInVec vec0, floatInVec vec1) { return floatInVec(vec_add(vec0.get128(), vec1.get128())); } inline const floatInVec operator - (floatInVec vec0, floatInVec vec1) { return floatInVec(vec_sub(vec0.get128(), vec1.get128())); } inline const boolInVec operator < (floatInVec vec0, floatInVec vec1) { return boolInVec((vec_uint4)vec_cmpgt(vec1.get128(), vec0.get128())); } inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1) { return !(vec0 > vec1); } inline const boolInVec operator > (floatInVec vec0, floatInVec vec1) { return boolInVec((vec_uint4)vec_cmpgt(vec0.get128(), vec1.get128())); } inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1) { return !(vec0 < vec1); } inline const boolInVec operator == (floatInVec vec0, floatInVec vec1) { return boolInVec((vec_uint4)vec_cmpeq(vec0.get128(), vec1.get128())); } inline const boolInVec operator != (floatInVec vec0, floatInVec vec1) { return !(vec0 == vec1); } inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1) { return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); } } // namespace Vectormath #endif // floatInVec_h ================================================ FILE: samples/vectormath/ppu/cpp/mat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_CPP_H #define _VECTORMATH_MAT_AOS_CPP_H namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // Constants // for shuffles, words are labeled [x,y,z,w] [a,b,c,d] #define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z }) #define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y }) #define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C }) #define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PI_OVER_2 1.570796327f //----------------------------------------------------------------------------- // Definitions inline Matrix3::Matrix3( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; } inline Matrix3::Matrix3( float scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); } inline Matrix3::Matrix3( floatInVec scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); } inline Matrix3::Matrix3( Quat unitQuat ) { vec_float4 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; vec_uint4 select_x = _VECTORMATH_MASK_0xF000; vec_uint4 select_z = _VECTORMATH_MASK_0x00F0; xyzw_2 = vec_add( unitQuat.get128(), unitQuat.get128() ); wwww = vec_splat( unitQuat.get128(), 3 ); yzxw = vec_perm( unitQuat.get128(), unitQuat.get128(), _VECTORMATH_PERM_YZXW ); zxyw = vec_perm( unitQuat.get128(), unitQuat.get128(), _VECTORMATH_PERM_ZXYW ); yzxw_2 = vec_perm( xyzw_2, xyzw_2, _VECTORMATH_PERM_YZXW ); zxyw_2 = vec_perm( xyzw_2, xyzw_2, _VECTORMATH_PERM_ZXYW ); tmp0 = vec_madd( yzxw_2, wwww, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp1 = vec_nmsub( yzxw, yzxw_2, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); tmp2 = vec_madd( yzxw, xyzw_2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp0 = vec_madd( zxyw, xyzw_2, tmp0 ); tmp1 = vec_nmsub( zxyw, zxyw_2, tmp1 ); tmp2 = vec_nmsub( zxyw_2, wwww, tmp2 ); tmp3 = vec_sel( tmp0, tmp1, select_x ); tmp4 = vec_sel( tmp1, tmp2, select_x ); tmp5 = vec_sel( tmp2, tmp0, select_x ); mCol0 = Vector3( vec_sel( tmp3, tmp2, select_z ) ); mCol1 = Vector3( vec_sel( tmp4, tmp0, select_z ) ); mCol2 = Vector3( vec_sel( tmp5, tmp1, select_z ) ); } inline Matrix3::Matrix3( Vector3 _col0, Vector3 _col1, Vector3 _col2 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; } inline Matrix3 & Matrix3::setCol0( Vector3 _col0 ) { mCol0 = _col0; return *this; } inline Matrix3 & Matrix3::setCol1( Vector3 _col1 ) { mCol1 = _col1; return *this; } inline Matrix3 & Matrix3::setCol2( Vector3 _col2 ) { mCol2 = _col2; return *this; } inline Matrix3 & Matrix3::setCol( int col, Vector3 vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix3 & Matrix3::setRow( int row, Vector3 vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); return *this; } inline Matrix3 & Matrix3::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline Matrix3 & Matrix3::setElem( int col, int row, floatInVec val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline const floatInVec Matrix3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Matrix3::getCol0( ) const { return mCol0; } inline const Vector3 Matrix3::getCol1( ) const { return mCol1; } inline const Vector3 Matrix3::getCol2( ) const { return mCol2; } inline const Vector3 Matrix3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector3 Matrix3::getRow( int row ) const { return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); } inline Vector3 & Matrix3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Matrix3::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; return *this; } inline const Matrix3 transpose( const Matrix3 & mat ) { vec_float4 tmp0, tmp1, res0, res1, res2; tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); res0 = vec_mergeh( tmp0, mat.getCol1().get128() ); res1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); res2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 inverse( const Matrix3 & mat ) { vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() ); tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() ); tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() ); dot = _vmathVfDot3( tmp2, mat.getCol2().get128() ); dot = vec_splat( dot, 0 ); invdet = recipf4( dot ); tmp3 = vec_mergeh( tmp0, tmp2 ); tmp4 = vec_mergel( tmp0, tmp2 ); inv0 = vec_mergeh( tmp3, tmp1 ); inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); inv0 = vec_madd( inv0, invdet, zero ); inv1 = vec_madd( inv1, invdet, zero ); inv2 = vec_madd( inv2, invdet, zero ); return Matrix3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ) ); } inline const floatInVec determinant( const Matrix3 & mat ) { return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); } inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const { return Matrix3( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ) ); } inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const { return Matrix3( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) { *this = *this + mat; return *this; } inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) { *this = *this - mat; return *this; } inline const Matrix3 Matrix3::operator -( ) const { return Matrix3( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ) ); } inline const Matrix3 absPerElem( const Matrix3 & mat ) { return Matrix3( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ) ); } inline const Matrix3 Matrix3::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Matrix3 Matrix3::operator *( floatInVec scalar ) const { return Matrix3( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ) ); } inline Matrix3 & Matrix3::operator *=( float scalar ) { return *this *= floatInVec(scalar); } inline Matrix3 & Matrix3::operator *=( floatInVec scalar ) { *this = *this * scalar; return *this; } inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) { return floatInVec(scalar) * mat; } inline const Matrix3 operator *( floatInVec scalar, const Matrix3 & mat ) { return mat * scalar; } inline const Vector3 Matrix3::operator *( Vector3 vec ) const { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; xxxx = vec_splat( vec.get128(), 0 ); yyyy = vec_splat( vec.get128(), 1 ); zzzz = vec_splat( vec.get128(), 2 ); res = vec_madd( mCol0.get128(), xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); res = vec_madd( mCol1.get128(), yyyy, res ); res = vec_madd( mCol2.get128(), zzzz, res ); return Vector3( res ); } inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const { return Matrix3( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) { *this = *this * mat; return *this; } inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) { return Matrix3( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ) ); } inline const Matrix3 Matrix3::identity( ) { return Matrix3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationX( float radians ) { return rotationX( floatInVec(radians) ); } inline const Matrix3 Matrix3::rotationX( floatInVec radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = _VECTORMATH_MASK_0x0F00; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); return Matrix3( Vector3::xAxis( ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 Matrix3::rotationY( float radians ) { return rotationY( floatInVec(radians) ); } inline const Matrix3 Matrix3::rotationY( floatInVec radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); return Matrix3( Vector3( res0 ), Vector3::yAxis( ), Vector3( res2 ) ); } inline const Matrix3 Matrix3::rotationZ( float radians ) { return rotationZ( floatInVec(radians) ); } inline const Matrix3 Matrix3::rotationZ( floatInVec radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_y = _VECTORMATH_MASK_0x0F00; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationZYX( Vector3 radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); angles = Vector4( radiansXYZ, 0.0f ).get128(); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F ); Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX ); Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_madd( Z0, Y1, zero ); return Matrix3( Vector3( vec_madd( Z0, Y0, zero ) ), Vector3( vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ) ), Vector3( vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ) ) ); } inline const Matrix3 Matrix3::rotation( float radians, Vector3 unitVec ) { return rotation( floatInVec(radians), unitVec ); } inline const Matrix3 Matrix3::rotation( floatInVec radians, Vector3 unitVec ) { vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); axis = unitVec.get128(); sincosf4( radians.get128(), &s, &c ); xxxx = vec_splat( axis, 0 ); yyyy = vec_splat( axis, 1 ); zzzz = vec_splat( axis, 2 ); oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c ); axisS = vec_madd( axis, s, zero ); negAxisS = negatef4( axisS ); tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); tmp0 = vec_sel( tmp0, c, _VECTORMATH_MASK_0xF000 ); tmp1 = vec_sel( tmp1, c, _VECTORMATH_MASK_0x0F00 ); tmp2 = vec_sel( tmp2, c, _VECTORMATH_MASK_0x00F0 ); return Matrix3( Vector3( vec_madd( vec_madd( axis, xxxx, zero ), oneMinusC, tmp0 ) ), Vector3( vec_madd( vec_madd( axis, yyyy, zero ), oneMinusC, tmp1 ) ), Vector3( vec_madd( vec_madd( axis, zzzz, zero ), oneMinusC, tmp2 ) ) ); } inline const Matrix3 Matrix3::rotation( Quat unitQuat ) { return Matrix3( unitQuat ); } inline const Matrix3 Matrix3::scale( Vector3 scaleVec ) { vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); return Matrix3( Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0xF000 ) ), Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x0F00 ) ), Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x00F0 ) ) ); } inline const Matrix3 appendScale( const Matrix3 & mat, Vector3 scaleVec ) { return Matrix3( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ) ); } inline const Matrix3 prependScale( Vector3 scaleVec, const Matrix3 & mat ) { return Matrix3( mulPerElem( mat.getCol0(), scaleVec ), mulPerElem( mat.getCol1(), scaleVec ), mulPerElem( mat.getCol2(), scaleVec ) ); } inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) { return Matrix3( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ) ); } inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, boolInVec select1 ) { return Matrix3( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix3 & mat ) { print( mat.getRow( 0 ) ); print( mat.getRow( 1 ) ); print( mat.getRow( 2 ) ); } inline void print( const Matrix3 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Matrix4::Matrix4( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; } inline Matrix4::Matrix4( float scalar ) { mCol0 = Vector4( scalar ); mCol1 = Vector4( scalar ); mCol2 = Vector4( scalar ); mCol3 = Vector4( scalar ); } inline Matrix4::Matrix4( floatInVec scalar ) { mCol0 = Vector4( scalar ); mCol1 = Vector4( scalar ); mCol2 = Vector4( scalar ); mCol3 = Vector4( scalar ); } inline Matrix4::Matrix4( const Transform3 & mat ) { mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( mat.getCol3(), 1.0f ); } inline Matrix4::Matrix4( Vector4 _col0, Vector4 _col1, Vector4 _col2, Vector4 _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Matrix4::Matrix4( const Matrix3 & mat, Vector3 translateVec ) { mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( translateVec, 1.0f ); } inline Matrix4::Matrix4( Quat unitQuat, Vector3 translateVec ) { Matrix3 mat; mat = Matrix3( unitQuat ); mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( translateVec, 1.0f ); } inline Matrix4 & Matrix4::setCol0( Vector4 _col0 ) { mCol0 = _col0; return *this; } inline Matrix4 & Matrix4::setCol1( Vector4 _col1 ) { mCol1 = _col1; return *this; } inline Matrix4 & Matrix4::setCol2( Vector4 _col2 ) { mCol2 = _col2; return *this; } inline Matrix4 & Matrix4::setCol3( Vector4 _col3 ) { mCol3 = _col3; return *this; } inline Matrix4 & Matrix4::setCol( int col, Vector4 vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix4 & Matrix4::setRow( int row, Vector4 vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Matrix4 & Matrix4::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline Matrix4 & Matrix4::setElem( int col, int row, floatInVec val ) { Vector4 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline const floatInVec Matrix4::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector4 Matrix4::getCol0( ) const { return mCol0; } inline const Vector4 Matrix4::getCol1( ) const { return mCol1; } inline const Vector4 Matrix4::getCol2( ) const { return mCol2; } inline const Vector4 Matrix4::getCol3( ) const { return mCol3; } inline const Vector4 Matrix4::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Matrix4::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector4 & Matrix4::operator []( int col ) { return *(&mCol0 + col); } inline const Vector4 Matrix4::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; return *this; } inline const Matrix4 transpose( const Matrix4 & mat ) { vec_float4 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); tmp1 = vec_mergeh( mat.getCol1().get128(), mat.getCol3().get128() ); tmp2 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); tmp3 = vec_mergel( mat.getCol1().get128(), mat.getCol3().get128() ); res0 = vec_mergeh( tmp0, tmp1 ); res1 = vec_mergel( tmp0, tmp1 ); res2 = vec_mergeh( tmp2, tmp3 ); res3 = vec_mergel( tmp2, tmp3 ); return Matrix4( Vector4( res0 ), Vector4( res1 ), Vector4( res2 ), Vector4( res3 ) ); } inline const Matrix4 inverse( const Matrix4 & mat ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vector float in0, in1, in2, in3; vector float tmp0, tmp1, tmp2, tmp3; vector float cof0, cof1, cof2, cof3; vector float t0, t1, t2, t3; vector float t01, t02, t03, t12, t23; vector float t1r, t2r; vector float t01r, t02r, t03r, t12r, t23r; vector float t1r3, t1r3r; vector float det, det0, det1, det2, det3, invdet; vector float vzero = (vector float){0.0}; in0 = mat.getCol0().get128(); in1 = mat.getCol1().get128(); in2 = mat.getCol2().get128(); in3 = mat.getCol3().get128(); /* Perform transform of the input matrix of the form: * A B C D * E F G H * I J K L * M N O P * * The pseudo transpose of the input matrix is trans: * A E I M * J N B F * C G K O * L P D H */ tmp0 = vec_perm(in0, in1, _VECTORMATH_PERM_XAZC); /* A E C G */ tmp1 = vec_perm(in2, in3, _VECTORMATH_PERM_XAZC); /* I M K O */ tmp2 = vec_perm(in0, in1, _VECTORMATH_PERM_YBWD); /* B F D H */ tmp3 = vec_perm(in2, in3, _VECTORMATH_PERM_YBWD); /* J N L P */ t0 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_XYAB); /* A E I M */ t1 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_XYAB); /* J N B F */ t2 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_ZWCD); /* C G K O */ t3 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_ZWCD); /* L P D H */ /* Generate a cofactor matrix. The computed cofactors reside in * cof0, cof1, cof2, cof3. */ t23 = vec_madd(t2, t3, vzero); /* CL GP KD OH */ t23 = vec_perm(t23, t23, _VECTORMATH_PERM_YXWZ); /* GP CL OH KD */ cof0 = vec_nmsub(t1, t23, vzero); /* -(JGP NCL FOH BKD) */ cof1 = vec_nmsub(t0, t23, vzero); /* -(AGP ECL IOH MKD) */ t23r = vec_sld(t23, t23, 8); /* OH KD GP CL */ cof0 = vec_madd(t1, t23r, cof0); /* JOH NKD BGP FCL + cof0 */ cof1 = vec_madd(t0, t23r, cof1); /* AOH EKD IGP MCL + cof1 */ cof1 = vec_sld(cof1, cof1, 8); /* IGP MCL AOH EKD - IOH MKD AGP ECL */ t12 = vec_madd(t1, t2, vzero); /* JC NG BK FO */ t12 = vec_perm(t12, t12, _VECTORMATH_PERM_YXWZ); /* NG JC FO BK */ cof0 = vec_madd(t3, t12, cof0); /* LNG PJC DFO HBK + cof0 */ cof3 = vec_madd(t0, t12, vzero); /* ANG EJC IFO MBK */ t12r = vec_sld(t12, t12, 8); /* FO BK NG JC */ cof0 = vec_nmsub(t3, t12r, cof0); /* cof0 - LFO PBK DNG HJC */ cof3 = vec_nmsub(t0, t12r, cof3); /* cof3 - AFO EBK ING MJC */ cof3 = vec_sld(cof3, cof3, 8); /* ING MJC AFO EBK - IFO MBK ANG EJC */ t1r = vec_sld(t1, t1, 8); /* B F J N */ t2r = vec_sld(t2, t2, 8); /* K O C G */ t1r3 = vec_madd(t1r, t3, vzero); /* BL FP JD NH */ t1r3 = vec_perm(t1r3, t1r3, _VECTORMATH_PERM_YXWZ); /* FP BL NH JD */ cof0 = vec_madd(t2r, t1r3, cof0); /* KFP OBL CNH GJD + cof0 */ cof2 = vec_madd(t0, t1r3, vzero); /* AFP EBL INH MJD */ t1r3r = vec_sld(t1r3, t1r3, 8); /* NH JD FP BL */ cof0 = vec_nmsub(t2r, t1r3r, cof0); /* cof0 - KNH OJD CFP GBL */ cof2 = vec_nmsub(t0, t1r3r, cof2); /* cof2 - ANH EJD IFP MBL */ cof2 = vec_sld(cof2, cof2, 8); /* IFP MBL ANH EJD - INH MJD AFP EBL */ t01 = vec_madd(t0, t1, vzero); /* AJ EN IB MF */ t01 = vec_perm(t01, t01, _VECTORMATH_PERM_YXWZ); /* EN AJ MF IB */ cof2 = vec_nmsub(t3, t01, cof2); /* cof2 - LEN PAJ DMF HIB */ cof3 = vec_madd(t2r, t01, cof3); /* KEN OAJ CMF GIB + cof3 */ t01r = vec_sld(t01, t01, 8); /* MF IB EN AJ */ cof2 = vec_madd(t3, t01r, cof2); /* LMF PIB DEN HAJ + cof2 */ cof3 = vec_nmsub(t2r, t01r, cof3); /* cof3 - KMF OIB CEN GAJ */ t03 = vec_madd(t0, t3, vzero); /* AL EP ID MH */ t03 = vec_perm(t03, t03, _VECTORMATH_PERM_YXWZ); /* EP AL MH ID */ cof1 = vec_nmsub(t2r, t03, cof1); /* cof1 - KEP OAL CMH GID */ cof2 = vec_madd(t1, t03, cof2); /* JEP NAL BMH FID + cof2 */ t03r = vec_sld(t03, t03, 8); /* MH ID EP AL */ cof1 = vec_madd(t2r, t03r, cof1); /* KMH OID CEP GAL + cof1 */ cof2 = vec_nmsub(t1, t03r, cof2); /* cof2 - JMH NID BEP FAL */ t02 = vec_madd(t0, t2r, vzero); /* AK EO IC MG */ t02 = vec_perm(t02, t02, _VECTORMATH_PERM_YXWZ); /* E0 AK MG IC */ cof1 = vec_madd(t3, t02, cof1); /* LEO PAK DMG HIC + cof1 */ cof3 = vec_nmsub(t1, t02, cof3); /* cof3 - JEO NAK BMG FIC */ t02r = vec_sld(t02, t02, 8); /* MG IC EO AK */ cof1 = vec_nmsub(t3, t02r, cof1); /* cof1 - LMG PIC DEO HAK */ cof3 = vec_madd(t1, t02r, cof3); /* JMG NIC BEO FAK + cof3 */ /* Compute the determinant of the matrix * * det = sum_across(t0 * cof0); * * We perform a sum across the entire vector so that * we don't have to splat the result when multiplying the * cofactors by the inverse of the determinant. */ det = vec_madd(t0, cof0, vzero); det0 = vec_splat(det, 0); det1 = vec_splat(det, 1); det2 = vec_splat(det, 2); det3 = vec_splat(det, 3); det = vec_add(det0, det1); det2 = vec_add(det2, det3); det = vec_add(det, det2); /* Compute the reciprocal of the determinant. */ invdet = recipf4(det); /* Multiply the cofactors by the reciprocal of the determinant. */ return Matrix4( Vector4( vec_madd(cof0, invdet, vzero) ), Vector4( vec_madd(cof1, invdet, vzero) ), Vector4( vec_madd(cof2, invdet, vzero) ), Vector4( vec_madd(cof3, invdet, vzero) ) ); } inline const Matrix4 affineInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( inverse( affineMat ) ); } inline const Matrix4 orthoInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( orthoInverse( affineMat ) ); } inline const floatInVec determinant( const Matrix4 & mat ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vector float in0, in1, in2, in3; vector float tmp0, tmp1, tmp2, tmp3; vector float cof0; vector float t0, t1, t2, t3; vector float t12, t23; vector float t1r, t2r; vector float t12r, t23r; vector float t1r3, t1r3r; vector float vzero = (vector float){0.0}; in0 = mat.getCol0().get128(); in1 = mat.getCol1().get128(); in2 = mat.getCol2().get128(); in3 = mat.getCol3().get128(); /* Perform transform of the input matrix of the form: * A B C D * E F G H * I J K L * M N O P * * The pseudo transpose of the input matrix is trans: * A E I M * J N B F * C G K O * L P D H */ tmp0 = vec_perm(in0, in1, _VECTORMATH_PERM_XAZC); /* A E C G */ tmp1 = vec_perm(in2, in3, _VECTORMATH_PERM_XAZC); /* I M K O */ tmp2 = vec_perm(in0, in1, _VECTORMATH_PERM_YBWD); /* B F D H */ tmp3 = vec_perm(in2, in3, _VECTORMATH_PERM_YBWD); /* J N L P */ t0 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_XYAB); /* A E I M */ t1 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_XYAB); /* J N B F */ t2 = vec_perm(tmp0, tmp1, _VECTORMATH_PERM_ZWCD); /* C G K O */ t3 = vec_perm(tmp3, tmp2, _VECTORMATH_PERM_ZWCD); /* L P D H */ /* Generate a cofactor matrix. The computed cofactors reside in * cof0, cof1, cof2, cof3. */ t23 = vec_madd(t2, t3, vzero); /* CL GP KD OH */ t23 = vec_perm(t23, t23, _VECTORMATH_PERM_YXWZ); /* GP CL OH KD */ cof0 = vec_nmsub(t1, t23, vzero); /* -(JGP NCL FOH BKD) */ t23r = vec_sld(t23, t23, 8); /* OH KD GP CL */ cof0 = vec_madd(t1, t23r, cof0); /* JOH NKD BGP FCL + cof0 */ t12 = vec_madd(t1, t2, vzero); /* JC NG BK FO */ t12 = vec_perm(t12, t12, _VECTORMATH_PERM_YXWZ); /* NG JC FO BK */ cof0 = vec_madd(t3, t12, cof0); /* LNG PJC DFO HBK + cof0 */ t12r = vec_sld(t12, t12, 8); /* FO BK NG JC */ cof0 = vec_nmsub(t3, t12r, cof0); /* cof0 - LFO PBK DNG HJC */ t1r = vec_sld(t1, t1, 8); /* B F J N */ t2r = vec_sld(t2, t2, 8); /* K O C G */ t1r3 = vec_madd(t1r, t3, vzero); /* BL FP JD NH */ t1r3 = vec_perm(t1r3, t1r3, _VECTORMATH_PERM_YXWZ); /* FP BL NH JD */ cof0 = vec_madd(t2r, t1r3, cof0); /* KFP OBL CNH GJD + cof0 */ t1r3r = vec_sld(t1r3, t1r3, 8); /* NH JD FP BL */ cof0 = vec_nmsub(t2r, t1r3r, cof0); /* cof0 - KNH OJD CFP GBL */ return floatInVec( _vmathVfDot4(t0,cof0), 0 ); } inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const { return Matrix4( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ), ( mCol3 + mat.mCol3 ) ); } inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const { return Matrix4( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ), ( mCol3 - mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) { *this = *this + mat; return *this; } inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) { *this = *this - mat; return *this; } inline const Matrix4 Matrix4::operator -( ) const { return Matrix4( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ), ( -mCol3 ) ); } inline const Matrix4 absPerElem( const Matrix4 & mat ) { return Matrix4( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ), absPerElem( mat.getCol3() ) ); } inline const Matrix4 Matrix4::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Matrix4 Matrix4::operator *( floatInVec scalar ) const { return Matrix4( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ), ( mCol3 * scalar ) ); } inline Matrix4 & Matrix4::operator *=( float scalar ) { return *this *= floatInVec(scalar); } inline Matrix4 & Matrix4::operator *=( floatInVec scalar ) { *this = *this * scalar; return *this; } inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) { return floatInVec(scalar) * mat; } inline const Matrix4 operator *( floatInVec scalar, const Matrix4 & mat ) { return mat * scalar; } inline const Vector4 Matrix4::operator *( Vector4 vec ) const { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz, wwww; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); xxxx = vec_splat( vec.get128(), 0 ); yyyy = vec_splat( vec.get128(), 1 ); zzzz = vec_splat( vec.get128(), 2 ); wwww = vec_splat( vec.get128(), 3 ); tmp0 = vec_madd( mCol0.get128(), xxxx, zero ); tmp1 = vec_madd( mCol1.get128(), yyyy, zero ); tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 ); tmp1 = vec_madd( mCol3.get128(), wwww, tmp1 ); res = vec_add( tmp0, tmp1 ); return Vector4( res ); } inline const Vector4 Matrix4::operator *( Vector3 vec ) const { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; xxxx = vec_splat( vec.get128(), 0 ); yyyy = vec_splat( vec.get128(), 1 ); zzzz = vec_splat( vec.get128(), 2 ); res = vec_madd( mCol0.get128(), xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); res = vec_madd( mCol1.get128(), yyyy, res ); res = vec_madd( mCol2.get128(), zzzz, res ); return Vector4( res ); } inline const Vector4 Matrix4::operator *( Point3 pnt ) const { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); xxxx = vec_splat( pnt.get128(), 0 ); yyyy = vec_splat( pnt.get128(), 1 ); zzzz = vec_splat( pnt.get128(), 2 ); tmp0 = vec_madd( mCol0.get128(), xxxx, zero ); tmp1 = vec_madd( mCol1.get128(), yyyy, zero ); tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 ); tmp1 = vec_add( mCol3.get128(), tmp1 ); res = vec_add( tmp0, tmp1 ); return Vector4( res ); } inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const { return Matrix4( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ), ( *this * mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) { *this = *this * mat; return *this; } inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const { return Matrix4( ( *this * tfrm.getCol0() ), ( *this * tfrm.getCol1() ), ( *this * tfrm.getCol2() ), ( *this * Point3( tfrm.getCol3() ) ) ); } inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) { return Matrix4( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ), mulPerElem( mat0.getCol3(), mat1.getCol3() ) ); } inline const Matrix4 Matrix4::identity( ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) { mCol0.setXYZ( mat3.getCol0() ); mCol1.setXYZ( mat3.getCol1() ); mCol2.setXYZ( mat3.getCol2() ); return *this; } inline const Matrix3 Matrix4::getUpper3x3( ) const { return Matrix3( mCol0.getXYZ( ), mCol1.getXYZ( ), mCol2.getXYZ( ) ); } inline Matrix4 & Matrix4::setTranslation( Vector3 translateVec ) { mCol3.setXYZ( translateVec ); return *this; } inline const Vector3 Matrix4::getTranslation( ) const { return mCol3.getXYZ( ); } inline const Matrix4 Matrix4::rotationX( float radians ) { return rotationX( floatInVec(radians) ); } inline const Matrix4 Matrix4::rotationX( floatInVec radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = _VECTORMATH_MASK_0x0F00; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); return Matrix4( Vector4::xAxis( ), Vector4( res1 ), Vector4( res2 ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationY( float radians ) { return rotationY( floatInVec(radians) ); } inline const Matrix4 Matrix4::rotationY( floatInVec radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); return Matrix4( Vector4( res0 ), Vector4::yAxis( ), Vector4( res2 ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZ( float radians ) { return rotationZ( floatInVec(radians) ); } inline const Matrix4 Matrix4::rotationZ( floatInVec radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_y = _VECTORMATH_MASK_0x0F00; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); return Matrix4( Vector4( res0 ), Vector4( res1 ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZYX( Vector3 radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); angles = Vector4( radiansXYZ, 0.0f ).get128(); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F ); Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX ); Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_madd( Z0, Y1, zero ); return Matrix4( Vector4( vec_madd( Z0, Y0, zero ) ), Vector4( vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ) ), Vector4( vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( float radians, Vector3 unitVec ) { return rotation( floatInVec(radians), unitVec ); } inline const Matrix4 Matrix4::rotation( floatInVec radians, Vector3 unitVec ) { vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2, zeroW; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); axis = unitVec.get128(); sincosf4( radians.get128(), &s, &c ); xxxx = vec_splat( axis, 0 ); yyyy = vec_splat( axis, 1 ); zzzz = vec_splat( axis, 2 ); oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c ); axisS = vec_madd( axis, s, zero ); negAxisS = negatef4( axisS ); tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); tmp0 = vec_sel( tmp0, c, _VECTORMATH_MASK_0xF000 ); tmp1 = vec_sel( tmp1, c, _VECTORMATH_MASK_0x0F00 ); tmp2 = vec_sel( tmp2, c, _VECTORMATH_MASK_0x00F0 ); zeroW = (vec_float4)_VECTORMATH_MASK_0x000F; axis = vec_andc( axis, zeroW ); tmp0 = vec_andc( tmp0, zeroW ); tmp1 = vec_andc( tmp1, zeroW ); tmp2 = vec_andc( tmp2, zeroW ); return Matrix4( Vector4( vec_madd( vec_madd( axis, xxxx, zero ), oneMinusC, tmp0 ) ), Vector4( vec_madd( vec_madd( axis, yyyy, zero ), oneMinusC, tmp1 ) ), Vector4( vec_madd( vec_madd( axis, zzzz, zero ), oneMinusC, tmp2 ) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( Quat unitQuat ) { return Matrix4( Transform3::rotation( unitQuat ) ); } inline const Matrix4 Matrix4::scale( Vector3 scaleVec ) { vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); return Matrix4( Vector4( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0xF000 ) ), Vector4( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x0F00 ) ), Vector4( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x00F0 ) ), Vector4::wAxis( ) ); } inline const Matrix4 appendScale( const Matrix4 & mat, Vector3 scaleVec ) { return Matrix4( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ), mat.getCol3() ); } inline const Matrix4 prependScale( Vector3 scaleVec, const Matrix4 & mat ) { Vector4 scale4; scale4 = Vector4( scaleVec, 1.0f ); return Matrix4( mulPerElem( mat.getCol0(), scale4 ), mulPerElem( mat.getCol1(), scale4 ), mulPerElem( mat.getCol2(), scale4 ), mulPerElem( mat.getCol3(), scale4 ) ); } inline const Matrix4 Matrix4::translation( Vector3 translateVec ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4( translateVec, 1.0f ) ); } inline const Matrix4 Matrix4::lookAt( Point3 eyePos, Point3 lookAtPos, Vector3 upVec ) { Matrix4 m4EyeFrame; Vector3 v3X, v3Y, v3Z; v3Y = normalize( upVec ); v3Z = normalize( ( eyePos - lookAtPos ) ); v3X = normalize( cross( v3Y, v3Z ) ); v3Y = cross( v3Z, v3X ); m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); return orthoInverse( m4EyeFrame ); } inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) { float f, rangeInv; vec_float4 zero, col0, col1, col2, col3; union { vec_float4 v; float s[4]; } tmp; f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f ); rangeInv = 1.0f / ( zNear - zFar ); zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); tmp.v = zero; tmp.s[0] = f / aspect; col0 = tmp.v; tmp.v = zero; tmp.s[1] = f; col1 = tmp.v; tmp.v = zero; tmp.s[2] = ( zNear + zFar ) * rangeInv; tmp.s[3] = -1.0f; col2 = tmp.v; tmp.v = zero; tmp.s[2] = zNear * zFar * rangeInv * 2.0f; col3 = tmp.v; return Matrix4( Vector4( col0 ), Vector4( col1 ), Vector4( col2 ), Vector4( col3 ) ); } inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 lbf, rtn; vec_float4 diff, sum, inv_diff; vec_float4 diagonal, column, near2; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); union { vec_float4 v; float s[4]; } l, f, r, n, b, t; l.s[0] = left; f.s[0] = zFar; r.s[0] = right; n.s[0] = zNear; b.s[0] = bottom; t.s[0] = top; lbf = vec_mergeh( l.v, f.v ); rtn = vec_mergeh( r.v, n.v ); lbf = vec_mergeh( lbf, b.v ); rtn = vec_mergeh( rtn, t.v ); diff = vec_sub( rtn, lbf ); sum = vec_add( rtn, lbf ); inv_diff = recipf4( diff ); near2 = vec_splat( n.v, 0 ); near2 = vec_add( near2, near2 ); diagonal = vec_madd( near2, inv_diff, zero ); column = vec_madd( sum, inv_diff, zero ); return Matrix4( Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0xF000 ) ), Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0x0F00 ) ), Vector4( vec_sel( column, ((vec_float4){-1.0f,-1.0f,-1.0f,-1.0f}), _VECTORMATH_MASK_0x000F ) ), Vector4( vec_sel( zero, vec_madd( diagonal, vec_splat( f.v, 0 ), zero ), _VECTORMATH_MASK_0x00F0 ) ) ); } inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 lbf, rtn; vec_float4 diff, sum, inv_diff, neg_inv_diff; vec_float4 diagonal, column; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); union { vec_float4 v; float s[4]; } l, f, r, n, b, t; l.s[0] = left; f.s[0] = zFar; r.s[0] = right; n.s[0] = zNear; b.s[0] = bottom; t.s[0] = top; lbf = vec_mergeh( l.v, f.v ); rtn = vec_mergeh( r.v, n.v ); lbf = vec_mergeh( lbf, b.v ); rtn = vec_mergeh( rtn, t.v ); diff = vec_sub( rtn, lbf ); sum = vec_add( rtn, lbf ); inv_diff = recipf4( diff ); neg_inv_diff = negatef4( inv_diff ); diagonal = vec_add( inv_diff, inv_diff ); column = vec_madd( sum, vec_sel( neg_inv_diff, inv_diff, _VECTORMATH_MASK_0x00F0 ), zero ); return Matrix4( Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0xF000 ) ), Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0x0F00 ) ), Vector4( vec_sel( zero, diagonal, _VECTORMATH_MASK_0x00F0 ) ), Vector4( vec_sel( column, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), _VECTORMATH_MASK_0x000F ) ) ); } inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) { return Matrix4( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ), select( mat0.getCol3(), mat1.getCol3(), select1 ) ); } inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, boolInVec select1 ) { return Matrix4( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ), select( mat0.getCol3(), mat1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix4 & mat ) { print( mat.getRow( 0 ) ); print( mat.getRow( 1 ) ); print( mat.getRow( 2 ) ); print( mat.getRow( 3 ) ); } inline void print( const Matrix4 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Transform3::Transform3( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; } inline Transform3::Transform3( float scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); mCol3 = Vector3( scalar ); } inline Transform3::Transform3( floatInVec scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); mCol3 = Vector3( scalar ); } inline Transform3::Transform3( Vector3 _col0, Vector3 _col1, Vector3 _col2, Vector3 _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Transform3::Transform3( const Matrix3 & tfrm, Vector3 translateVec ) { this->setUpper3x3( tfrm ); this->setTranslation( translateVec ); } inline Transform3::Transform3( Quat unitQuat, Vector3 translateVec ) { this->setUpper3x3( Matrix3( unitQuat ) ); this->setTranslation( translateVec ); } inline Transform3 & Transform3::setCol0( Vector3 _col0 ) { mCol0 = _col0; return *this; } inline Transform3 & Transform3::setCol1( Vector3 _col1 ) { mCol1 = _col1; return *this; } inline Transform3 & Transform3::setCol2( Vector3 _col2 ) { mCol2 = _col2; return *this; } inline Transform3 & Transform3::setCol3( Vector3 _col3 ) { mCol3 = _col3; return *this; } inline Transform3 & Transform3::setCol( int col, Vector3 vec ) { *(&mCol0 + col) = vec; return *this; } inline Transform3 & Transform3::setRow( int row, Vector4 vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Transform3 & Transform3::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline Transform3 & Transform3::setElem( int col, int row, floatInVec val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline const floatInVec Transform3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Transform3::getCol0( ) const { return mCol0; } inline const Vector3 Transform3::getCol1( ) const { return mCol1; } inline const Vector3 Transform3::getCol2( ) const { return mCol2; } inline const Vector3 Transform3::getCol3( ) const { return mCol3; } inline const Vector3 Transform3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Transform3::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector3 & Transform3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Transform3::operator []( int col ) const { return *(&mCol0 + col); } inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; return *this; } inline const Transform3 inverse( const Transform3 & tfrm ) { vec_float4 inv0, inv1, inv2, inv3; vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; vec_float4 xxxx, yyyy, zzzz; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() ); tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() ); tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() ); inv3 = negatef4( tfrm.getCol3().get128() ); dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() ); dot = vec_splat( dot, 0 ); invdet = recipf4( dot ); tmp3 = vec_mergeh( tmp0, tmp2 ); tmp4 = vec_mergel( tmp0, tmp2 ); inv0 = vec_mergeh( tmp3, tmp1 ); xxxx = vec_splat( inv3, 0 ); inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); yyyy = vec_splat( inv3, 1 ); zzzz = vec_splat( inv3, 2 ); inv3 = vec_madd( inv0, xxxx, zero ); inv3 = vec_madd( inv1, yyyy, inv3 ); inv3 = vec_madd( inv2, zzzz, inv3 ); inv0 = vec_madd( inv0, invdet, zero ); inv1 = vec_madd( inv1, invdet, zero ); inv2 = vec_madd( inv2, invdet, zero ); inv3 = vec_madd( inv3, invdet, zero ); return Transform3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ), Vector3( inv3 ) ); } inline const Transform3 orthoInverse( const Transform3 & tfrm ) { vec_float4 inv0, inv1, inv2, inv3; vec_float4 tmp0, tmp1; vec_float4 xxxx, yyyy, zzzz; tmp0 = vec_mergeh( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); tmp1 = vec_mergel( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); inv3 = negatef4( tfrm.getCol3().get128() ); inv0 = vec_mergeh( tmp0, tfrm.getCol1().get128() ); xxxx = vec_splat( inv3, 0 ); inv1 = vec_perm( tmp0, tfrm.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); inv2 = vec_perm( tmp1, tfrm.getCol1().get128(), _VECTORMATH_PERM_XCYX ); yyyy = vec_splat( inv3, 1 ); zzzz = vec_splat( inv3, 2 ); inv3 = vec_madd( inv0, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); inv3 = vec_madd( inv1, yyyy, inv3 ); inv3 = vec_madd( inv2, zzzz, inv3 ); return Transform3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ), Vector3( inv3 ) ); } inline const Transform3 absPerElem( const Transform3 & tfrm ) { return Transform3( absPerElem( tfrm.getCol0() ), absPerElem( tfrm.getCol1() ), absPerElem( tfrm.getCol2() ), absPerElem( tfrm.getCol3() ) ); } inline const Vector3 Transform3::operator *( Vector3 vec ) const { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; xxxx = vec_splat( vec.get128(), 0 ); yyyy = vec_splat( vec.get128(), 1 ); zzzz = vec_splat( vec.get128(), 2 ); res = vec_madd( mCol0.get128(), xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); res = vec_madd( mCol1.get128(), yyyy, res ); res = vec_madd( mCol2.get128(), zzzz, res ); return Vector3( res ); } inline const Point3 Transform3::operator *( Point3 pnt ) const { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); xxxx = vec_splat( pnt.get128(), 0 ); yyyy = vec_splat( pnt.get128(), 1 ); zzzz = vec_splat( pnt.get128(), 2 ); tmp0 = vec_madd( mCol0.get128(), xxxx, zero ); tmp1 = vec_madd( mCol1.get128(), yyyy, zero ); tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 ); tmp1 = vec_add( mCol3.get128(), tmp1 ); res = vec_add( tmp0, tmp1 ); return Point3( res ); } inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const { return Transform3( ( *this * tfrm.mCol0 ), ( *this * tfrm.mCol1 ), ( *this * tfrm.mCol2 ), Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) ); } inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) { return Transform3( mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) ); } inline const Transform3 Transform3::identity( ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), Vector3( 0.0f ) ); } inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) { mCol0 = tfrm.getCol0(); mCol1 = tfrm.getCol1(); mCol2 = tfrm.getCol2(); return *this; } inline const Matrix3 Transform3::getUpper3x3( ) const { return Matrix3( mCol0, mCol1, mCol2 ); } inline Transform3 & Transform3::setTranslation( Vector3 translateVec ) { mCol3 = translateVec; return *this; } inline const Vector3 Transform3::getTranslation( ) const { return mCol3; } inline const Transform3 Transform3::rotationX( float radians ) { return rotationX( floatInVec(radians) ); } inline const Transform3 Transform3::rotationX( floatInVec radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = _VECTORMATH_MASK_0x0F00; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res1 = vec_sel( zero, c, select_y ); res1 = vec_sel( res1, s, select_z ); res2 = vec_sel( zero, negatef4(s), select_y ); res2 = vec_sel( res2, c, select_z ); return Transform3( Vector3::xAxis( ), Vector3( res1 ), Vector3( res2 ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationY( float radians ) { return rotationY( floatInVec(radians) ); } inline const Transform3 Transform3::rotationY( floatInVec radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_z = _VECTORMATH_MASK_0x00F0; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, negatef4(s), select_z ); res2 = vec_sel( zero, s, select_x ); res2 = vec_sel( res2, c, select_z ); return Transform3( Vector3( res0 ), Vector3::yAxis( ), Vector3( res2 ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationZ( float radians ) { return rotationZ( floatInVec(radians) ); } inline const Transform3 Transform3::rotationZ( floatInVec radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = _VECTORMATH_MASK_0xF000; select_y = _VECTORMATH_MASK_0x0F00; zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); sincosf4( radians.get128(), &s, &c ); res0 = vec_sel( zero, c, select_x ); res0 = vec_sel( res0, s, select_y ); res1 = vec_sel( zero, negatef4(s), select_x ); res1 = vec_sel( res1, c, select_y ); return Transform3( Vector3( res0 ), Vector3( res1 ), Vector3::zAxis( ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationZYX( Vector3 radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); angles = Vector4( radiansXYZ, 0.0f ).get128(); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = vec_mergel( c, s ); Z1 = vec_mergel( negS, c ); Z1 = vec_andc( Z1, (vec_float4)_VECTORMATH_MASK_0x000F ); Y0 = vec_perm( negS, c, _VECTORMATH_PERM_BBYX ); Y1 = vec_perm( c, s, _VECTORMATH_PERM_BBYX ); X0 = vec_splat( s, 0 ); X1 = vec_splat( c, 0 ); tmp = vec_madd( Z0, Y1, zero ); return Transform3( Vector3( vec_madd( Z0, Y0, zero ) ), Vector3( vec_madd( Z1, X1, vec_madd( tmp, X0, zero ) ) ), Vector3( vec_nmsub( Z1, X0, vec_madd( tmp, X1, zero ) ) ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotation( float radians, Vector3 unitVec ) { return rotation( floatInVec(radians), unitVec ); } inline const Transform3 Transform3::rotation( floatInVec radians, Vector3 unitVec ) { return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotation( Quat unitQuat ) { return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::scale( Vector3 scaleVec ) { vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); return Transform3( Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0xF000 ) ), Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x0F00 ) ), Vector3( vec_sel( zero, scaleVec.get128(), _VECTORMATH_MASK_0x00F0 ) ), Vector3( 0.0f ) ); } inline const Transform3 appendScale( const Transform3 & tfrm, Vector3 scaleVec ) { return Transform3( ( tfrm.getCol0() * scaleVec.getX( ) ), ( tfrm.getCol1() * scaleVec.getY( ) ), ( tfrm.getCol2() * scaleVec.getZ( ) ), tfrm.getCol3() ); } inline const Transform3 prependScale( Vector3 scaleVec, const Transform3 & tfrm ) { return Transform3( mulPerElem( tfrm.getCol0(), scaleVec ), mulPerElem( tfrm.getCol1(), scaleVec ), mulPerElem( tfrm.getCol2(), scaleVec ), mulPerElem( tfrm.getCol3(), scaleVec ) ); } inline const Transform3 Transform3::translation( Vector3 translateVec ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), translateVec ); } inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) { return Transform3( select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) ); } inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, boolInVec select1 ) { return Transform3( select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Transform3 & tfrm ) { print( tfrm.getRow( 0 ) ); print( tfrm.getRow( 1 ) ); print( tfrm.getRow( 2 ) ); } inline void print( const Transform3 & tfrm, const char * name ) { printf("%s:\n", name); print( tfrm ); } #endif inline Quat::Quat( const Matrix3 & tfrm ) { vec_float4 res; vec_float4 col0, col1, col2; vec_float4 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; vec_float4 zy_xz_yx, yz_zx_xy, sum, diff; vec_float4 radicand, invSqrt, scale; vec_float4 res0, res1, res2, res3; vec_float4 xx, yy, zz; vec_uint4 select_x = _VECTORMATH_MASK_0xF000; vec_uint4 select_y = _VECTORMATH_MASK_0x0F00; vec_uint4 select_z = _VECTORMATH_MASK_0x00F0; vec_uint4 select_w = _VECTORMATH_MASK_0x000F; vec_float4 zero = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); col0 = tfrm.getCol0().get128(); col1 = tfrm.getCol1().get128(); col2 = tfrm.getCol2().get128(); /* four cases: */ /* trace > 0 */ /* else */ /* xx largest diagonal element */ /* yy largest diagonal element */ /* zz largest diagonal element */ /* compute quaternion for each case */ xx_yy = vec_sel( col0, col1, select_y ); xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX ); yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY ); zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC ); diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); invSqrt = rsqrtf4( radicand ); zy_xz_yx = vec_sel( col0, col1, select_z ); zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX ); yz_zx_xy = vec_sel( col0, col1, select_x ); yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX ); sum = vec_add( zy_xz_yx, yz_zx_xy ); diff = vec_sub( zy_xz_yx, yz_zx_xy ); scale = vec_madd( invSqrt, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), zero ); res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA ); res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB ); res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC ); res3 = diff; res0 = vec_sel( res0, radicand, select_x ); res1 = vec_sel( res1, radicand, select_y ); res2 = vec_sel( res2, radicand, select_z ); res3 = vec_sel( res3, radicand, select_w ); res0 = vec_madd( res0, vec_splat( scale, 0 ), zero ); res1 = vec_madd( res1, vec_splat( scale, 1 ), zero ); res2 = vec_madd( res2, vec_splat( scale, 2 ), zero ); res3 = vec_madd( res3, vec_splat( scale, 3 ), zero ); /* determine case and select answer */ xx = vec_splat( col0, 0 ); yy = vec_splat( col1, 1 ); zz = vec_splat( col2, 2 ); res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) ); res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) ); res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), zero ) ); mVec128 = res; } inline const Matrix3 outer( Vector3 tfrm0, Vector3 tfrm1 ) { return Matrix3( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ) ); } inline const Matrix4 outer( Vector4 tfrm0, Vector4 tfrm1 ) { return Matrix4( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ), ( tfrm0 * tfrm1.getW( ) ) ); } inline const Vector3 rowMul( Vector3 vec, const Matrix3 & mat ) { vec_float4 tmp0, tmp1, mcol0, mcol1, mcol2, res; vec_float4 xxxx, yyyy, zzzz; tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); xxxx = vec_splat( vec.get128(), 0 ); mcol0 = vec_mergeh( tmp0, mat.getCol1().get128() ); mcol1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); mcol2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); yyyy = vec_splat( vec.get128(), 1 ); res = vec_madd( mcol0, xxxx, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); zzzz = vec_splat( vec.get128(), 2 ); res = vec_madd( mcol1, yyyy, res ); res = vec_madd( mcol2, zzzz, res ); return Vector3( res ); } inline const Matrix3 crossMatrix( Vector3 vec ) { vec_float4 neg, res0, res1, res2; neg = negatef4( vec.get128() ); res0 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_XZBX ); res1 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_CXXX ); res2 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_YAXX ); res0 = vec_andc( res0, (vec_float4)_VECTORMATH_MASK_0xF000 ); res1 = vec_andc( res1, (vec_float4)_VECTORMATH_MASK_0x0F00 ); res2 = vec_andc( res2, (vec_float4)_VECTORMATH_MASK_0x00F0 ); return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 crossMatrixMul( Vector3 vec, const Matrix3 & mat ) { return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); } } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/ppu/cpp/mat_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_SOA_CPP_H #define _VECTORMATH_MAT_SOA_CPP_H namespace Vectormath { namespace Soa { //----------------------------------------------------------------------------- // Constants #define _VECTORMATH_PI_OVER_2 1.570796327f //----------------------------------------------------------------------------- // Definitions inline Matrix3::Matrix3( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; } inline Matrix3::Matrix3( vec_float4 scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); } inline Matrix3::Matrix3( const Quat & unitQuat ) { vec_float4 qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; qx = unitQuat.getX(); qy = unitQuat.getY(); qz = unitQuat.getZ(); qw = unitQuat.getW(); qx2 = vec_add( qx, qx ); qy2 = vec_add( qy, qy ); qz2 = vec_add( qz, qz ); qxqx2 = vec_madd( qx, qx2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qxqy2 = vec_madd( qx, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qxqz2 = vec_madd( qx, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qxqw2 = vec_madd( qw, qx2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qyqy2 = vec_madd( qy, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qyqz2 = vec_madd( qy, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qyqw2 = vec_madd( qw, qy2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qzqz2 = vec_madd( qz, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qzqw2 = vec_madd( qw, qz2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); 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 ) ); 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 ) ); 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 ) ); } inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; } inline Matrix3::Matrix3( const Aos::Matrix3 & mat ) { mCol0 = Vector3( mat.getCol0() ); mCol1 = Vector3( mat.getCol1() ); mCol2 = Vector3( mat.getCol2() ); } inline Matrix3::Matrix3( const Aos::Matrix3 & mat0, const Aos::Matrix3 & mat1, const Aos::Matrix3 & mat2, const Aos::Matrix3 & mat3 ) { mCol0 = Vector3( mat0.getCol0(), mat1.getCol0(), mat2.getCol0(), mat3.getCol0() ); mCol1 = Vector3( mat0.getCol1(), mat1.getCol1(), mat2.getCol1(), mat3.getCol1() ); mCol2 = Vector3( mat0.getCol2(), mat1.getCol2(), mat2.getCol2(), mat3.getCol2() ); } inline void Matrix3::get4Aos( Aos::Matrix3 & result0, Aos::Matrix3 & result1, Aos::Matrix3 & result2, Aos::Matrix3 & result3 ) const { Aos::Vector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; mCol0.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol0( tmpV3_0 ); result1.setCol0( tmpV3_1 ); result2.setCol0( tmpV3_2 ); result3.setCol0( tmpV3_3 ); mCol1.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol1( tmpV3_0 ); result1.setCol1( tmpV3_1 ); result2.setCol1( tmpV3_2 ); result3.setCol1( tmpV3_3 ); mCol2.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol2( tmpV3_0 ); result1.setCol2( tmpV3_1 ); result2.setCol2( tmpV3_2 ); result3.setCol2( tmpV3_3 ); } inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) { mCol0 = _col0; return *this; } inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) { mCol1 = _col1; return *this; } inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) { mCol2 = _col2; return *this; } inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); return *this; } inline Matrix3 & Matrix3::setElem( int col, int row, vec_float4 val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline vec_float4 Matrix3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Matrix3::getCol0( ) const { return mCol0; } inline const Vector3 Matrix3::getCol1( ) const { return mCol1; } inline const Vector3 Matrix3::getCol2( ) const { return mCol2; } inline const Vector3 Matrix3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector3 Matrix3::getRow( int row ) const { return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); } inline Vector3 & Matrix3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Matrix3::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; return *this; } inline const Matrix3 transpose( const Matrix3 & mat ) { return Matrix3( Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) ); } inline const Matrix3 inverse( const Matrix3 & mat ) { Vector3 tmp0, tmp1, tmp2; vec_float4 detinv; tmp0 = cross( mat.getCol1(), mat.getCol2() ); tmp1 = cross( mat.getCol2(), mat.getCol0() ); tmp2 = cross( mat.getCol0(), mat.getCol1() ); detinv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), dot( mat.getCol2(), tmp2 ) ); return Matrix3( 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}) ) ), 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}) ) ), 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}) ) ) ); } inline vec_float4 determinant( const Matrix3 & mat ) { return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); } inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const { return Matrix3( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ) ); } inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const { return Matrix3( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) { *this = *this + mat; return *this; } inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) { *this = *this - mat; return *this; } inline const Matrix3 Matrix3::operator -( ) const { return Matrix3( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ) ); } inline const Matrix3 absPerElem( const Matrix3 & mat ) { return Matrix3( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ) ); } inline const Matrix3 Matrix3::operator *( vec_float4 scalar ) const { return Matrix3( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ) ); } inline Matrix3 & Matrix3::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Matrix3 operator *( vec_float4 scalar, const Matrix3 & mat ) { return mat * scalar; } inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const { return Vector3( 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_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_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}) ) ) ); } inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const { return Matrix3( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) { *this = *this * mat; return *this; } inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) { return Matrix3( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ) ); } inline const Matrix3 Matrix3::identity( ) { return Matrix3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationX( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix3( Vector3::xAxis( ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c ) ); } inline const Matrix3 Matrix3::rotationY( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix3( Vector3( c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ) ), Vector3::yAxis( ), Vector3( s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ) ); } inline const Matrix3 Matrix3::rotationZ( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix3( Vector3( c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector3( negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ.getX(), &sX, &cX ); sincosf4( radiansXYZ.getY(), &sY, &cY ); sincosf4( radiansXYZ.getZ(), &sZ, &cZ ); tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); return Matrix3( 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 ) ), 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}) ) ), 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}) ) ) ); } inline const Matrix3 Matrix3::rotation( vec_float4 radians, const Vector3 & unitVec ) { vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx; sincosf4( radians, &s, &c ); x = unitVec.getX(); y = unitVec.getY(); z = unitVec.getZ(); xy = vec_madd( x, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); yz = vec_madd( y, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); zx = vec_madd( z, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c ); return Matrix3( 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}) ) ) ), 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}) ) ) ), 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 ) ) ); } inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) { return Matrix3( unitQuat ); } inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) { return Matrix3( Vector3( scaleVec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getZ() ) ); } inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) { return Matrix3( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ) ); } inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) { return Matrix3( mulPerElem( mat.getCol0(), scaleVec ), mulPerElem( mat.getCol1(), scaleVec ), mulPerElem( mat.getCol2(), scaleVec ) ); } inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, vec_uint4 select1 ) { return Matrix3( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix3 & mat ) { Aos::Matrix3 mat0, mat1, mat2, mat3; mat.get4Aos( mat0, mat1, mat2, mat3 ); printf("slot 0:\n"); print( mat0 ); printf("slot 1:\n"); print( mat1 ); printf("slot 2:\n"); print( mat2 ); printf("slot 3:\n"); print( mat3 ); } inline void print( const Matrix3 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Matrix4::Matrix4( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; } inline Matrix4::Matrix4( vec_float4 scalar ) { mCol0 = Vector4( scalar ); mCol1 = Vector4( scalar ); mCol2 = Vector4( scalar ); mCol3 = Vector4( scalar ); } inline Matrix4::Matrix4( const Transform3 & mat ) { mCol0 = Vector4( mat.getCol0(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol1 = Vector4( mat.getCol1(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol2 = Vector4( mat.getCol2(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol3 = Vector4( mat.getCol3(), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); } inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) { mCol0 = Vector4( mat.getCol0(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol1 = Vector4( mat.getCol1(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol2 = Vector4( mat.getCol2(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol3 = Vector4( translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); } inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) { Matrix3 mat; mat = Matrix3( unitQuat ); mCol0 = Vector4( mat.getCol0(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol1 = Vector4( mat.getCol1(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol2 = Vector4( mat.getCol2(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); mCol3 = Vector4( translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); } inline Matrix4::Matrix4( const Aos::Matrix4 & mat ) { mCol0 = Vector4( mat.getCol0() ); mCol1 = Vector4( mat.getCol1() ); mCol2 = Vector4( mat.getCol2() ); mCol3 = Vector4( mat.getCol3() ); } inline Matrix4::Matrix4( const Aos::Matrix4 & mat0, const Aos::Matrix4 & mat1, const Aos::Matrix4 & mat2, const Aos::Matrix4 & mat3 ) { mCol0 = Vector4( mat0.getCol0(), mat1.getCol0(), mat2.getCol0(), mat3.getCol0() ); mCol1 = Vector4( mat0.getCol1(), mat1.getCol1(), mat2.getCol1(), mat3.getCol1() ); mCol2 = Vector4( mat0.getCol2(), mat1.getCol2(), mat2.getCol2(), mat3.getCol2() ); mCol3 = Vector4( mat0.getCol3(), mat1.getCol3(), mat2.getCol3(), mat3.getCol3() ); } inline void Matrix4::get4Aos( Aos::Matrix4 & result0, Aos::Matrix4 & result1, Aos::Matrix4 & result2, Aos::Matrix4 & result3 ) const { Aos::Vector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; mCol0.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 ); result0.setCol0( tmpV4_0 ); result1.setCol0( tmpV4_1 ); result2.setCol0( tmpV4_2 ); result3.setCol0( tmpV4_3 ); mCol1.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 ); result0.setCol1( tmpV4_0 ); result1.setCol1( tmpV4_1 ); result2.setCol1( tmpV4_2 ); result3.setCol1( tmpV4_3 ); mCol2.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 ); result0.setCol2( tmpV4_0 ); result1.setCol2( tmpV4_1 ); result2.setCol2( tmpV4_2 ); result3.setCol2( tmpV4_3 ); mCol3.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 ); result0.setCol3( tmpV4_0 ); result1.setCol3( tmpV4_1 ); result2.setCol3( tmpV4_2 ); result3.setCol3( tmpV4_3 ); } inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) { mCol0 = _col0; return *this; } inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) { mCol1 = _col1; return *this; } inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) { mCol2 = _col2; return *this; } inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) { mCol3 = _col3; return *this; } inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Matrix4 & Matrix4::setElem( int col, int row, vec_float4 val ) { Vector4 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline vec_float4 Matrix4::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector4 Matrix4::getCol0( ) const { return mCol0; } inline const Vector4 Matrix4::getCol1( ) const { return mCol1; } inline const Vector4 Matrix4::getCol2( ) const { return mCol2; } inline const Vector4 Matrix4::getCol3( ) const { return mCol3; } inline const Vector4 Matrix4::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Matrix4::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector4 & Matrix4::operator []( int col ) { return *(&mCol0 + col); } inline const Vector4 Matrix4::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; return *this; } inline const Matrix4 transpose( const Matrix4 & mat ) { return Matrix4( Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) ); } inline const Matrix4 inverse( const Matrix4 & mat ) { Vector4 res0, res1, res2, res3; 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; mA = mat.getCol0().getX(); mB = mat.getCol0().getY(); mC = mat.getCol0().getZ(); mD = mat.getCol0().getW(); mE = mat.getCol1().getX(); mF = mat.getCol1().getY(); mG = mat.getCol1().getZ(); mH = mat.getCol1().getW(); mI = mat.getCol2().getX(); mJ = mat.getCol2().getY(); mK = mat.getCol2().getZ(); mL = mat.getCol2().getW(); mM = mat.getCol3().getX(); mN = mat.getCol3().getY(); mO = mat.getCol3().getZ(); mP = mat.getCol3().getW(); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ) ); 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}) ) ) ); 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}) ) ) ); 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}) ) ) ); 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}) ) ) ); res1.setX( vec_madd( mI, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res1.setY( vec_madd( mM, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res1.setZ( vec_madd( mA, tmp1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res1.setW( vec_madd( mE, tmp0, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res3.setX( vec_madd( mI, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res3.setY( vec_madd( mM, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res3.setZ( vec_madd( mA, tmp3, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res3.setW( vec_madd( mE, tmp2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res2.setX( vec_madd( mI, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res2.setY( vec_madd( mM, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res2.setZ( vec_madd( mA, tmp5, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); res2.setW( vec_madd( mE, tmp4, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); 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() ) ); return Matrix4( ( res0 * detInv ), ( res1 * detInv ), ( res2 * detInv ), ( res3 * detInv ) ); } inline const Matrix4 affineInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( inverse( affineMat ) ); } inline const Matrix4 orthoInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( orthoInverse( affineMat ) ); } inline vec_float4 determinant( const Matrix4 & mat ) { 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; mA = mat.getCol0().getX(); mB = mat.getCol0().getY(); mC = mat.getCol0().getZ(); mD = mat.getCol0().getW(); mE = mat.getCol1().getX(); mF = mat.getCol1().getY(); mG = mat.getCol1().getZ(); mH = mat.getCol1().getW(); mI = mat.getCol2().getX(); mJ = mat.getCol2().getY(); mK = mat.getCol2().getZ(); mL = mat.getCol2().getW(); mM = mat.getCol3().getX(); mN = mat.getCol3().getY(); mO = mat.getCol3().getZ(); mP = mat.getCol3().getW(); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); } inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const { return Matrix4( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ), ( mCol3 + mat.mCol3 ) ); } inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const { return Matrix4( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ), ( mCol3 - mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) { *this = *this + mat; return *this; } inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) { *this = *this - mat; return *this; } inline const Matrix4 Matrix4::operator -( ) const { return Matrix4( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ), ( -mCol3 ) ); } inline const Matrix4 absPerElem( const Matrix4 & mat ) { return Matrix4( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ), absPerElem( mat.getCol3() ) ); } inline const Matrix4 Matrix4::operator *( vec_float4 scalar ) const { return Matrix4( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ), ( mCol3 * scalar ) ); } inline Matrix4 & Matrix4::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Matrix4 operator *( vec_float4 scalar, const Matrix4 & mat ) { return mat * scalar; } inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const { return Vector4( 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}) ) ), 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}) ) ), 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}) ) ), 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}) ) ) ); } inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const { return Vector4( 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_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_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_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}) ) ) ); } inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const { return Vector4( 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() ), 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() ), 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() ), 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() ) ); } inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const { return Matrix4( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ), ( *this * mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) { *this = *this * mat; return *this; } inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const { return Matrix4( ( *this * tfrm.getCol0() ), ( *this * tfrm.getCol1() ), ( *this * tfrm.getCol2() ), ( *this * Point3( tfrm.getCol3() ) ) ); } inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) { return Matrix4( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ), mulPerElem( mat0.getCol3(), mat1.getCol3() ) ); } inline const Matrix4 Matrix4::identity( ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) { mCol0.setXYZ( mat3.getCol0() ); mCol1.setXYZ( mat3.getCol1() ); mCol2.setXYZ( mat3.getCol2() ); return *this; } inline const Matrix3 Matrix4::getUpper3x3( ) const { return Matrix3( mCol0.getXYZ( ), mCol1.getXYZ( ), mCol2.getXYZ( ) ); } inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) { mCol3.setXYZ( translateVec ); return *this; } inline const Vector3 Matrix4::getTranslation( ) const { return mCol3.getXYZ( ); } inline const Matrix4 Matrix4::rotationX( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix4( Vector4::xAxis( ), Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector4( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationY( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix4( Vector4( c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector4::yAxis( ), Vector4( s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZ( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix4( Vector4( c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector4( negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ.getX(), &sX, &cX ); sincosf4( radiansXYZ.getY(), &sY, &cY ); sincosf4( radiansXYZ.getZ(), &sZ, &cZ ); tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); return Matrix4( 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}) ), 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}) ), 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}) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( vec_float4 radians, const Vector3 & unitVec ) { vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx; sincosf4( radians, &s, &c ); x = unitVec.getX(); y = unitVec.getY(); z = unitVec.getZ(); xy = vec_madd( x, y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); yz = vec_madd( y, z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); zx = vec_madd( z, x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); oneMinusC = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), c ); return Matrix4( 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}) ), 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}) ), 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}) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) { return Matrix4( Transform3::rotation( unitQuat ) ); } inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) { return Matrix4( 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}) ), 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}) ), 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}) ), Vector4::wAxis( ) ); } inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) { return Matrix4( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ), mat.getCol3() ); } inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) { Vector4 scale4; scale4 = Vector4( scaleVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); return Matrix4( mulPerElem( mat.getCol0(), scale4 ), mulPerElem( mat.getCol1(), scale4 ), mulPerElem( mat.getCol2(), scale4 ), mulPerElem( mat.getCol3(), scale4 ) ); } inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4( translateVec, ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ) ); } inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) { Matrix4 m4EyeFrame; Vector3 v3X, v3Y, v3Z; v3Y = normalize( upVec ); v3Z = normalize( ( eyePos - lookAtPos ) ); v3X = normalize( cross( v3Y, v3Z ) ); v3Y = cross( v3Z, v3X ); m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); return orthoInverse( m4EyeFrame ); } inline const Matrix4 Matrix4::perspective( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ) { vec_float4 f, rangeInv; 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}) ) ) ); rangeInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) ); return Matrix4( 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}) ), 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}) ), 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}) ), 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}) ) ); } inline const Matrix4 Matrix4::frustum( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; sum_rl = vec_add( right, left ); sum_tb = vec_add( top, bottom ); sum_nf = vec_add( zNear, zFar ); inv_rl = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( right, left ) ); inv_tb = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( top, bottom ) ); inv_nf = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) ); n2 = vec_add( zNear, zNear ); return Matrix4( 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}) ), 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}) ), 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}) ), 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}) ) ); } inline const Matrix4 Matrix4::orthographic( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; sum_rl = vec_add( right, left ); sum_tb = vec_add( top, bottom ); sum_nf = vec_add( zNear, zFar ); inv_rl = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( right, left ) ); inv_tb = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( top, bottom ) ); inv_nf = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec_sub( zNear, zFar ) ); return Matrix4( 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}) ), 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}) ), 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}) ), 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}) ) ); } inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, vec_uint4 select1 ) { return Matrix4( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ), select( mat0.getCol3(), mat1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix4 & mat ) { Aos::Matrix4 mat0, mat1, mat2, mat3; mat.get4Aos( mat0, mat1, mat2, mat3 ); printf("slot 0:\n"); print( mat0 ); printf("slot 1:\n"); print( mat1 ); printf("slot 2:\n"); print( mat2 ); printf("slot 3:\n"); print( mat3 ); } inline void print( const Matrix4 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Transform3::Transform3( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; } inline Transform3::Transform3( vec_float4 scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); mCol3 = Vector3( scalar ); } inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) { this->setUpper3x3( tfrm ); this->setTranslation( translateVec ); } inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) { this->setUpper3x3( Matrix3( unitQuat ) ); this->setTranslation( translateVec ); } inline Transform3::Transform3( const Aos::Transform3 & tfrm ) { mCol0 = Vector3( tfrm.getCol0() ); mCol1 = Vector3( tfrm.getCol1() ); mCol2 = Vector3( tfrm.getCol2() ); mCol3 = Vector3( tfrm.getCol3() ); } inline Transform3::Transform3( const Aos::Transform3 & tfrm0, const Aos::Transform3 & tfrm1, const Aos::Transform3 & tfrm2, const Aos::Transform3 & tfrm3 ) { mCol0 = Vector3( tfrm0.getCol0(), tfrm1.getCol0(), tfrm2.getCol0(), tfrm3.getCol0() ); mCol1 = Vector3( tfrm0.getCol1(), tfrm1.getCol1(), tfrm2.getCol1(), tfrm3.getCol1() ); mCol2 = Vector3( tfrm0.getCol2(), tfrm1.getCol2(), tfrm2.getCol2(), tfrm3.getCol2() ); mCol3 = Vector3( tfrm0.getCol3(), tfrm1.getCol3(), tfrm2.getCol3(), tfrm3.getCol3() ); } inline void Transform3::get4Aos( Aos::Transform3 & result0, Aos::Transform3 & result1, Aos::Transform3 & result2, Aos::Transform3 & result3 ) const { Aos::Vector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; mCol0.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol0( tmpV3_0 ); result1.setCol0( tmpV3_1 ); result2.setCol0( tmpV3_2 ); result3.setCol0( tmpV3_3 ); mCol1.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol1( tmpV3_0 ); result1.setCol1( tmpV3_1 ); result2.setCol1( tmpV3_2 ); result3.setCol1( tmpV3_3 ); mCol2.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol2( tmpV3_0 ); result1.setCol2( tmpV3_1 ); result2.setCol2( tmpV3_2 ); result3.setCol2( tmpV3_3 ); mCol3.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol3( tmpV3_0 ); result1.setCol3( tmpV3_1 ); result2.setCol3( tmpV3_2 ); result3.setCol3( tmpV3_3 ); } inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) { mCol0 = _col0; return *this; } inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) { mCol1 = _col1; return *this; } inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) { mCol2 = _col2; return *this; } inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) { mCol3 = _col3; return *this; } inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Transform3 & Transform3::setElem( int col, int row, vec_float4 val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline vec_float4 Transform3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Transform3::getCol0( ) const { return mCol0; } inline const Vector3 Transform3::getCol1( ) const { return mCol1; } inline const Vector3 Transform3::getCol2( ) const { return mCol2; } inline const Vector3 Transform3::getCol3( ) const { return mCol3; } inline const Vector3 Transform3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Transform3::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector3 & Transform3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Transform3::operator []( int col ) const { return *(&mCol0 + col); } inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; return *this; } inline const Transform3 inverse( const Transform3 & tfrm ) { Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; vec_float4 detinv; tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); detinv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), dot( tfrm.getCol2(), tmp2 ) ); 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}) ) ); 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}) ) ); 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}) ) ); return Transform3( inv0, inv1, inv2, Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) ); } inline const Transform3 orthoInverse( const Transform3 & tfrm ) { Vector3 inv0, inv1, inv2; inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); return Transform3( inv0, inv1, inv2, Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) ); } inline const Transform3 absPerElem( const Transform3 & tfrm ) { return Transform3( absPerElem( tfrm.getCol0() ), absPerElem( tfrm.getCol1() ), absPerElem( tfrm.getCol2() ), absPerElem( tfrm.getCol3() ) ); } inline const Vector3 Transform3::operator *( const Vector3 & vec ) const { return Vector3( 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_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_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}) ) ) ); } inline const Point3 Transform3::operator *( const Point3 & pnt ) const { return Point3( 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() ), 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() ), 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() ) ); } inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const { return Transform3( ( *this * tfrm.mCol0 ), ( *this * tfrm.mCol1 ), ( *this * tfrm.mCol2 ), Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) ); } inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) { return Transform3( mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) ); } inline const Transform3 Transform3::identity( ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) { mCol0 = tfrm.getCol0(); mCol1 = tfrm.getCol1(); mCol2 = tfrm.getCol2(); return *this; } inline const Matrix3 Transform3::getUpper3x3( ) const { return Matrix3( mCol0, mCol1, mCol2 ); } inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) { mCol3 = translateVec; return *this; } inline const Vector3 Transform3::getTranslation( ) const { return mCol3; } inline const Transform3 Transform3::rotationX( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Transform3( Vector3::xAxis( ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c, s ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ), c ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Transform3 Transform3::rotationY( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Transform3( Vector3( c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), negatef4( s ) ), Vector3::yAxis( ), Vector3( s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Transform3 Transform3::rotationZ( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Transform3( Vector3( c, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector3( negatef4( s ), c, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector3::zAxis( ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ.getX(), &sX, &cX ); sincosf4( radiansXYZ.getY(), &sY, &cY ); sincosf4( radiansXYZ.getZ(), &sZ, &cZ ); tmp0 = vec_madd( cZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmp1 = vec_madd( sZ, sY, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); return Transform3( 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 ) ), 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}) ) ), 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}) ) ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Transform3 Transform3::rotation( vec_float4 radians, const Vector3 & unitVec ) { return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Transform3 Transform3::rotation( const Quat & unitQuat ) { return Transform3( Matrix3( unitQuat ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) { return Transform3( Vector3( scaleVec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), scaleVec.getZ() ), Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) { return Transform3( ( tfrm.getCol0() * scaleVec.getX( ) ), ( tfrm.getCol1() * scaleVec.getY( ) ), ( tfrm.getCol2() * scaleVec.getZ( ) ), tfrm.getCol3() ); } inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) { return Transform3( mulPerElem( tfrm.getCol0(), scaleVec ), mulPerElem( tfrm.getCol1(), scaleVec ), mulPerElem( tfrm.getCol2(), scaleVec ), mulPerElem( tfrm.getCol3(), scaleVec ) ); } inline const Transform3 Transform3::translation( const Vector3 & translateVec ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), translateVec ); } inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, vec_uint4 select1 ) { return Transform3( select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Transform3 & tfrm ) { Aos::Transform3 mat0, mat1, mat2, mat3; tfrm.get4Aos( mat0, mat1, mat2, mat3 ); printf("slot 0:\n"); print( mat0 ); printf("slot 1:\n"); print( mat1 ); printf("slot 2:\n"); print( mat2 ); printf("slot 3:\n"); print( mat3 ); } inline void print( const Transform3 & tfrm, const char * name ) { printf("%s:\n", name); print( tfrm ); } #endif inline Quat::Quat( const Matrix3 & tfrm ) { vec_float4 trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; vec_uint4 negTrace, ZgtX, ZgtY, YgtX; vec_uint4 largestXorY, largestYorZ, largestZorX; xx = tfrm.getCol0().getX(); yx = tfrm.getCol0().getY(); zx = tfrm.getCol0().getZ(); xy = tfrm.getCol1().getX(); yy = tfrm.getCol1().getY(); zy = tfrm.getCol1().getZ(); xz = tfrm.getCol2().getX(); yz = tfrm.getCol2().getY(); zz = tfrm.getCol2().getZ(); trace = vec_add( vec_add( xx, yy ), zz ); negTrace = (vec_uint4)vec_cmpgt( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), trace ); ZgtX = (vec_uint4)vec_cmpgt( zz, xx ); ZgtY = (vec_uint4)vec_cmpgt( zz, yy ); YgtX = (vec_uint4)vec_cmpgt( yy, xx ); largestXorY = vec_andc( negTrace, vec_and( ZgtX, ZgtY ) ); largestYorZ = vec_and( negTrace, vec_or( YgtX, ZgtX ) ); largestZorX = vec_andc( negTrace, vec_andc( YgtX, ZgtY ) ); zz = vec_sel( zz, negatef4(zz), largestXorY ); xy = vec_sel( xy, negatef4(xy), largestXorY ); xx = vec_sel( xx, negatef4(xx), largestYorZ ); yz = vec_sel( yz, negatef4(yz), largestYorZ ); yy = vec_sel( yy, negatef4(yy), largestZorX ); zx = vec_sel( zx, negatef4(zx), largestZorX ); radicand = vec_add( vec_add( vec_add( xx, yy ), zz ), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) ); 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}) ); tmpx = vec_madd( vec_sub( zy, yz ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmpy = vec_madd( vec_sub( xz, zx ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmpz = vec_madd( vec_sub( yx, xy ), scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); tmpw = vec_madd( radicand, scale, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qx = tmpx; qy = tmpy; qz = tmpz; qw = tmpw; qx = vec_sel( qx, tmpw, largestXorY ); qy = vec_sel( qy, tmpz, largestXorY ); qz = vec_sel( qz, tmpy, largestXorY ); qw = vec_sel( qw, tmpx, largestXorY ); tmpx = qx; tmpz = qz; qx = vec_sel( qx, qy, largestYorZ ); qy = vec_sel( qy, tmpx, largestYorZ ); qz = vec_sel( qz, qw, largestYorZ ); qw = vec_sel( qw, tmpz, largestYorZ ); mX = qx; mY = qy; mZ = qz; mW = qw; } inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) { return Matrix3( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ) ); } inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) { return Matrix4( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ), ( tfrm0 * tfrm1.getW( ) ) ); } inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) { return Vector3( 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}) ) ), 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}) ) ), 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}) ) ) ); } inline const Matrix3 crossMatrix( const Vector3 & vec ) { return Matrix3( Vector3( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec.getZ(), negatef4( vec.getY() ) ), Vector3( negatef4( vec.getZ() ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), vec.getX() ), Vector3( vec.getY(), negatef4( vec.getX() ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) { return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); } } // namespace Soa } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/ppu/cpp/quat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_CPP_H #define _VECTORMATH_QUAT_AOS_CPP_H //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Aos { inline Quat::Quat( float _x, float _y, float _z, float _w ) { if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z) & __builtin_constant_p(_w)) { mVec128 = (vec_float4){_x, _y, _z, _w}; } else { float *pf = (float *)&mVec128; pf[0] = _x; pf[1] = _y; pf[2] = _z; pf[3] = _w; } } inline Quat::Quat( floatInVec _x, floatInVec _y, floatInVec _z, floatInVec _w ) { vec_float4 xz = vec_mergeh( _x.get128(), _z.get128() ); vec_float4 yw = vec_mergeh( _y.get128(), _w.get128() ); mVec128 = vec_mergeh( xz, yw ); } inline Quat::Quat( Vector3 xyz, float _w ) { mVec128 = xyz.get128(); _vmathVfSetElement(mVec128, _w, 3); } inline Quat::Quat( Vector3 xyz, floatInVec _w ) { mVec128 = xyz.get128(); mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); } inline Quat::Quat( Vector4 vec ) { mVec128 = vec.get128(); } inline Quat::Quat( float scalar ) { mVec128 = floatInVec(scalar).get128(); } inline Quat::Quat( floatInVec scalar ) { mVec128 = scalar.get128(); } inline Quat::Quat( vec_float4 vf4 ) { mVec128 = vf4; } inline const Quat Quat::identity( ) { return Quat( _VECTORMATH_UNIT_0001 ); } inline const Quat lerp( float t, Quat quat0, Quat quat1 ) { return lerp( floatInVec(t), quat0, quat1 ); } inline const Quat lerp( floatInVec t, Quat quat0, Quat quat1 ) { return ( quat0 + ( ( quat1 - quat0 ) * t ) ); } inline const Quat slerp( float t, Quat unitQuat0, Quat unitQuat1 ) { return slerp( floatInVec(t), unitQuat0, unitQuat1 ); } inline const Quat slerp( floatInVec t, Quat unitQuat0, Quat unitQuat1 ) { Quat start; vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() ); cosAngle = vec_splat( cosAngle, 0 ); selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), cosAngle ); cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask ); start = Quat( vec_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) ); selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle ); angle = acosf4( cosAngle ); tttt = t.get128(); oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( angles, oneMinusT ); angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sines = sinf4( angles ); scales = divf4( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); return Quat( vec_madd( start.get128(), scale0, vec_madd( unitQuat1.get128(), scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) ); } inline const Quat squad( float t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 ) { return squad( floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3 ); } inline const Quat squad( floatInVec t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 ) { Quat tmp0, tmp1; tmp0 = slerp( t, unitQuat0, unitQuat3 ); tmp1 = slerp( t, unitQuat1, unitQuat2 ); return slerp( ( ( floatInVec(2.0f) * t ) * ( floatInVec(1.0f) - t ) ), tmp0, tmp1 ); } inline vec_float4 Quat::get128( ) const { return mVec128; } inline Quat & Quat::operator =( Quat quat ) { mVec128 = quat.mVec128; return *this; } inline Quat & Quat::setXYZ( Vector3 vec ) { mVec128 = vec_sel( vec.get128(), mVec128, _VECTORMATH_MASK_0x000F ); return *this; } inline const Vector3 Quat::getXYZ( ) const { return Vector3( mVec128 ); } inline Quat & Quat::setX( float _x ) { _vmathVfSetElement(mVec128, _x, 0); return *this; } inline Quat & Quat::setX( floatInVec _x ) { mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); return *this; } inline const floatInVec Quat::getX( ) const { return floatInVec( mVec128, 0 ); } inline Quat & Quat::setY( float _y ) { _vmathVfSetElement(mVec128, _y, 1); return *this; } inline Quat & Quat::setY( floatInVec _y ) { mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); return *this; } inline const floatInVec Quat::getY( ) const { return floatInVec( mVec128, 1 ); } inline Quat & Quat::setZ( float _z ) { _vmathVfSetElement(mVec128, _z, 2); return *this; } inline Quat & Quat::setZ( floatInVec _z ) { mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); return *this; } inline const floatInVec Quat::getZ( ) const { return floatInVec( mVec128, 2 ); } inline Quat & Quat::setW( float _w ) { _vmathVfSetElement(mVec128, _w, 3); return *this; } inline Quat & Quat::setW( floatInVec _w ) { mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); return *this; } inline const floatInVec Quat::getW( ) const { return floatInVec( mVec128, 3 ); } inline Quat & Quat::setElem( int idx, float value ) { _vmathVfSetElement(mVec128, value, idx); return *this; } inline Quat & Quat::setElem( int idx, floatInVec value ) { mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); return *this; } inline const floatInVec Quat::getElem( int idx ) const { return floatInVec( mVec128, idx ); } inline VecIdx Quat::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline const floatInVec Quat::operator []( int idx ) const { return floatInVec( mVec128, idx ); } inline const Quat Quat::operator +( Quat quat ) const { return Quat( vec_add( mVec128, quat.mVec128 ) ); } inline const Quat Quat::operator -( Quat quat ) const { return Quat( vec_sub( mVec128, quat.mVec128 ) ); } inline const Quat Quat::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Quat Quat::operator *( floatInVec scalar ) const { return Quat( vec_madd( mVec128, scalar.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline Quat & Quat::operator +=( Quat quat ) { *this = *this + quat; return *this; } inline Quat & Quat::operator -=( Quat quat ) { *this = *this - quat; return *this; } inline Quat & Quat::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline Quat & Quat::operator *=( floatInVec scalar ) { *this = *this * scalar; return *this; } inline const Quat Quat::operator /( float scalar ) const { return *this / floatInVec(scalar); } inline const Quat Quat::operator /( floatInVec scalar ) const { return Quat( divf4( mVec128, scalar.get128() ) ); } inline Quat & Quat::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline Quat & Quat::operator /=( floatInVec scalar ) { *this = *this / scalar; return *this; } inline const Quat Quat::operator -( ) const { return Quat( negatef4( mVec128 ) ); } inline const Quat operator *( float scalar, Quat quat ) { return floatInVec(scalar) * quat; } inline const Quat operator *( floatInVec scalar, Quat quat ) { return quat * scalar; } inline const floatInVec dot( Quat quat0, Quat quat1 ) { return floatInVec( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 ); } inline const floatInVec norm( Quat quat ) { return floatInVec( _vmathVfDot4( quat.get128(), quat.get128() ), 0 ); } inline const floatInVec length( Quat quat ) { return floatInVec( sqrtf4(_vmathVfDot4( quat.get128(), quat.get128() )), 0 ); } inline const Quat normalize( Quat quat ) { vec_float4 dot = _vmathVfDot4( quat.get128(), quat.get128() ); return Quat( vec_madd( quat.get128(), rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Quat Quat::rotation( Vector3 unitVec0, Vector3 unitVec1 ) { Vector3 crossVec; vec_float4 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); cosAngle = vec_splat( cosAngle, 0 ); cosAngleX2Plus2 = vec_madd( cosAngle, ((vec_float4){2.0f,2.0f,2.0f,2.0f}), ((vec_float4){2.0f,2.0f,2.0f,2.0f}) ); recipCosHalfAngleX2 = rsqrtf4( cosAngleX2Plus2 ); cosHalfAngleX2 = vec_madd( recipCosHalfAngleX2, cosAngleX2Plus2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); crossVec = cross( unitVec0, unitVec1 ); res = vec_madd( crossVec.get128(), recipCosHalfAngleX2, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); 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 ); return Quat( res ); } inline const Quat Quat::rotation( float radians, Vector3 unitVec ) { return rotation( floatInVec(radians), unitVec ); } inline const Quat Quat::rotation( floatInVec radians, Vector3 unitVec ) { vec_float4 s, c, angle, res; 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}) ); sincosf4( angle, &s, &c ); res = vec_sel( vec_madd( unitVec.get128(), s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), c, _VECTORMATH_MASK_0x000F ); return Quat( res ); } inline const Quat Quat::rotationX( float radians ) { return rotationX( floatInVec(radians) ); } inline const Quat Quat::rotationX( floatInVec radians ) { vec_float4 s, c, angle, res; 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}) ); sincosf4( angle, &s, &c ); res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0xF000 ); res = vec_sel( res, c, _VECTORMATH_MASK_0x000F ); return Quat( res ); } inline const Quat Quat::rotationY( float radians ) { return rotationY( floatInVec(radians) ); } inline const Quat Quat::rotationY( floatInVec radians ) { vec_float4 s, c, angle, res; 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}) ); sincosf4( angle, &s, &c ); res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0x0F00 ); res = vec_sel( res, c, _VECTORMATH_MASK_0x000F ); return Quat( res ); } inline const Quat Quat::rotationZ( float radians ) { return rotationZ( floatInVec(radians) ); } inline const Quat Quat::rotationZ( floatInVec radians ) { vec_float4 s, c, angle, res; 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}) ); sincosf4( angle, &s, &c ); res = vec_sel( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, _VECTORMATH_MASK_0x00F0 ); res = vec_sel( res, c, _VECTORMATH_MASK_0x000F ); return Quat( res ); } inline const Quat Quat::operator *( Quat quat ) const { vec_float4 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; vec_float4 product, l_wxyz, r_wxyz, xy, qw; ldata = mVec128; rdata = quat.mVec128; tmp0 = vec_perm( ldata, ldata, _VECTORMATH_PERM_YZXW ); tmp1 = vec_perm( rdata, rdata, _VECTORMATH_PERM_ZXYW ); tmp2 = vec_perm( ldata, ldata, _VECTORMATH_PERM_ZXYW ); tmp3 = vec_perm( rdata, rdata, _VECTORMATH_PERM_YZXW ); qv = vec_madd( vec_splat( ldata, 3 ), rdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv ); qv = vec_madd( tmp0, tmp1, qv ); qv = vec_nmsub( tmp2, tmp3, qv ); product = vec_madd( ldata, rdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); l_wxyz = vec_sld( ldata, ldata, 12 ); r_wxyz = vec_sld( rdata, rdata, 12 ); qw = vec_nmsub( l_wxyz, r_wxyz, product ); xy = vec_madd( l_wxyz, r_wxyz, product ); qw = vec_sub( qw, vec_sld( xy, xy, 8 ) ); return Quat( vec_sel( qv, qw, _VECTORMATH_MASK_0x000F ) ); } inline Quat & Quat::operator *=( Quat quat ) { *this = *this * quat; return *this; } inline const Vector3 rotate( Quat quat, Vector3 vec ) { vec_float4 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; qdata = quat.get128(); vdata = vec.get128(); tmp0 = vec_perm( qdata, qdata, _VECTORMATH_PERM_YZXW ); tmp1 = vec_perm( vdata, vdata, _VECTORMATH_PERM_ZXYW ); tmp2 = vec_perm( qdata, qdata, _VECTORMATH_PERM_ZXYW ); tmp3 = vec_perm( vdata, vdata, _VECTORMATH_PERM_YZXW ); wwww = vec_splat( qdata, 3 ); qv = vec_madd( wwww, vdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qv = vec_madd( tmp0, tmp1, qv ); qv = vec_nmsub( tmp2, tmp3, qv ); product = vec_madd( qdata, vdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product ); qw = vec_add( vec_sld( product, product, 8 ), qw ); tmp1 = vec_perm( qv, qv, _VECTORMATH_PERM_ZXYW ); tmp3 = vec_perm( qv, qv, _VECTORMATH_PERM_YZXW ); res = vec_madd( vec_splat( qw, 0 ), qdata, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); res = vec_madd( wwww, qv, res ); res = vec_madd( tmp0, tmp1, res ); res = vec_nmsub( tmp2, tmp3, res ); return Vector3( res ); } inline const Quat conj( Quat quat ) { return Quat( vec_xor( quat.get128(), ((vec_float4)(vec_int4){0x80000000,0x80000000,0x80000000,0}) ) ); } inline const Quat select( Quat quat0, Quat quat1, bool select1 ) { return select( quat0, quat1, boolInVec(select1) ); } inline const Quat select( Quat quat0, Quat quat1, boolInVec select1 ) { return Quat( vec_sel( quat0.get128(), quat1.get128(), select1.get128() ) ); } #ifdef _VECTORMATH_DEBUG inline void print( Quat quat ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = quat.get128(); printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } inline void print( Quat quat, const char * name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = quat.get128(); printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/ppu/cpp/quat_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_SOA_CPP_H #define _VECTORMATH_QUAT_SOA_CPP_H //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Soa { inline Quat::Quat( const Quat & quat ) { mX = quat.mX; mY = quat.mY; mZ = quat.mZ; mW = quat.mW; } inline Quat::Quat( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { mX = _x; mY = _y; mZ = _z; mW = _w; } inline Quat::Quat( const Vector3 & xyz, vec_float4 _w ) { this->setXYZ( xyz ); this->setW( _w ); } inline Quat::Quat( const Vector4 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); mW = vec.getW(); } inline Quat::Quat( vec_float4 scalar ) { mX = scalar; mY = scalar; mZ = scalar; mW = scalar; } inline Quat::Quat( Aos::Quat quat ) { vec_float4 vec128 = quat.get128(); mX = vec_splat( vec128, 0 ); mY = vec_splat( vec128, 1 ); mZ = vec_splat( vec128, 2 ); mW = vec_splat( vec128, 3 ); } inline Quat::Quat( Aos::Quat quat0, Aos::Quat quat1, Aos::Quat quat2, Aos::Quat quat3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( quat0.get128(), quat2.get128() ); tmp1 = vec_mergeh( quat1.get128(), quat3.get128() ); tmp2 = vec_mergel( quat0.get128(), quat2.get128() ); tmp3 = vec_mergel( quat1.get128(), quat3.get128() ); mX = vec_mergeh( tmp0, tmp1 ); mY = vec_mergel( tmp0, tmp1 ); mZ = vec_mergeh( tmp2, tmp3 ); mW = vec_mergel( tmp2, tmp3 ); } inline const Quat Quat::identity( ) { 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}) ); } inline const Quat lerp( vec_float4 t, const Quat & quat0, const Quat & quat1 ) { return ( quat0 + ( ( quat1 - quat0 ) * t ) ); } inline const Quat slerp( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1 ) { Quat start; vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = dot( unitQuat0, unitQuat1 ); selectMask = (vec_uint4)vec_cmpgt( (vec_float4){0.0f,0.0f,0.0f,0.0f}, cosAngle ); cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask ); start.setX( vec_sel( unitQuat0.getX(), negatef4( unitQuat0.getX() ), selectMask ) ); start.setY( vec_sel( unitQuat0.getY(), negatef4( unitQuat0.getY() ), selectMask ) ); start.setZ( vec_sel( unitQuat0.getZ(), negatef4( unitQuat0.getZ() ), selectMask ) ); start.setW( vec_sel( unitQuat0.getW(), negatef4( unitQuat0.getW() ), selectMask ) ); selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) ); 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 ); 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 ); return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); } inline const Quat squad( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) { Quat tmp0, tmp1; tmp0 = slerp( t, unitQuat0, unitQuat3 ); tmp1 = slerp( t, unitQuat1, unitQuat2 ); 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 ); } inline void Quat::get4Aos( Aos::Quat & result0, Aos::Quat & result1, Aos::Quat & result2, Aos::Quat & result3 ) const { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( mX, mZ ); tmp1 = vec_mergeh( mY, mW ); tmp2 = vec_mergel( mX, mZ ); tmp3 = vec_mergel( mY, mW ); result0 = Aos::Quat( vec_mergeh( tmp0, tmp1 ) ); result1 = Aos::Quat( vec_mergel( tmp0, tmp1 ) ); result2 = Aos::Quat( vec_mergeh( tmp2, tmp3 ) ); result3 = Aos::Quat( vec_mergel( tmp2, tmp3 ) ); } inline Quat & Quat::operator =( const Quat & quat ) { mX = quat.mX; mY = quat.mY; mZ = quat.mZ; mW = quat.mW; return *this; } inline Quat & Quat::setXYZ( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); return *this; } inline const Vector3 Quat::getXYZ( ) const { return Vector3( mX, mY, mZ ); } inline Quat & Quat::setX( vec_float4 _x ) { mX = _x; return *this; } inline vec_float4 Quat::getX( ) const { return mX; } inline Quat & Quat::setY( vec_float4 _y ) { mY = _y; return *this; } inline vec_float4 Quat::getY( ) const { return mY; } inline Quat & Quat::setZ( vec_float4 _z ) { mZ = _z; return *this; } inline vec_float4 Quat::getZ( ) const { return mZ; } inline Quat & Quat::setW( vec_float4 _w ) { mW = _w; return *this; } inline vec_float4 Quat::getW( ) const { return mW; } inline Quat & Quat::setElem( int idx, vec_float4 value ) { *(&mX + idx) = value; return *this; } inline vec_float4 Quat::getElem( int idx ) const { return *(&mX + idx); } inline Quat::vec_float4_t & Quat::operator []( int idx ) { return *(&mX + idx); } inline vec_float4 Quat::operator []( int idx ) const { return *(&mX + idx); } inline const Quat Quat::operator +( const Quat & quat ) const { return Quat( vec_add( mX, quat.mX ), vec_add( mY, quat.mY ), vec_add( mZ, quat.mZ ), vec_add( mW, quat.mW ) ); } inline const Quat Quat::operator -( const Quat & quat ) const { return Quat( vec_sub( mX, quat.mX ), vec_sub( mY, quat.mY ), vec_sub( mZ, quat.mZ ), vec_sub( mW, quat.mW ) ); } inline const Quat Quat::operator *( vec_float4 scalar ) const { return Quat( vec_madd( mX, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mY, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mZ, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mW, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline Quat & Quat::operator +=( const Quat & quat ) { *this = *this + quat; return *this; } inline Quat & Quat::operator -=( const Quat & quat ) { *this = *this - quat; return *this; } inline Quat & Quat::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Quat Quat::operator /( vec_float4 scalar ) const { return Quat( divf4( mX, scalar ), divf4( mY, scalar ), divf4( mZ, scalar ), divf4( mW, scalar ) ); } inline Quat & Quat::operator /=( vec_float4 scalar ) { *this = *this / scalar; return *this; } inline const Quat Quat::operator -( ) const { return Quat( negatef4( mX ), negatef4( mY ), negatef4( mZ ), negatef4( mW ) ); } inline const Quat operator *( vec_float4 scalar, const Quat & quat ) { return quat * scalar; } inline vec_float4 dot( const Quat & quat0, const Quat & quat1 ) { vec_float4 result; result = vec_madd( quat0.getX(), quat1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( quat0.getY(), quat1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( quat0.getZ(), quat1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( quat0.getW(), quat1.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } inline vec_float4 norm( const Quat & quat ) { vec_float4 result; result = vec_madd( quat.getX(), quat.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( quat.getY(), quat.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( quat.getZ(), quat.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( quat.getW(), quat.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } inline vec_float4 length( const Quat & quat ) { return sqrtf4( norm( quat ) ); } inline const Quat normalize( const Quat & quat ) { vec_float4 lenSqr, lenInv; lenSqr = norm( quat ); lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) ); return Quat( vec_madd( quat.getX(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat.getY(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat.getZ(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat.getW(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) { vec_float4 cosHalfAngleX2, recipCosHalfAngleX2; 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}) ) ); recipCosHalfAngleX2 = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), cosHalfAngleX2 ); 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}) ) ); } inline const Quat Quat::rotation( vec_float4 radians, const Vector3 & unitVec ) { vec_float4 s, c, angle; angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sincosf4( angle, &s, &c ); return Quat( ( unitVec * s ), c ); } inline const Quat Quat::rotationX( vec_float4 radians ) { vec_float4 s, c, angle; angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sincosf4( angle, &s, &c ); return Quat( s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ); } inline const Quat Quat::rotationY( vec_float4 radians ) { vec_float4 s, c, angle; angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sincosf4( angle, &s, &c ); return Quat( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c ); } inline const Quat Quat::rotationZ( vec_float4 radians ) { vec_float4 s, c, angle; angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sincosf4( angle, &s, &c ); return Quat( ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, c ); } inline const Quat Quat::operator *( const Quat & quat ) const { return Quat( 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}) ) ), 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}) ) ), 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}) ) ), 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}) ) ) ); } inline Quat & Quat::operator *=( const Quat & quat ) { *this = *this * quat; return *this; } inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) { vec_float4 tmpX, tmpY, tmpZ, tmpW; 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}) ) ); 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}) ) ); 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}) ) ); 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}) ) ); return Vector3( 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}) ) ), 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}) ) ), 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}) ) ) ); } inline const Quat conj( const Quat & quat ) { return Quat( negatef4( quat.getX() ), negatef4( quat.getY() ), negatef4( quat.getZ() ), quat.getW() ); } inline const Quat select( const Quat & quat0, const Quat & quat1, vec_uint4 select1 ) { return Quat( vec_sel( quat0.getX(), quat1.getX(), select1 ), vec_sel( quat0.getY(), quat1.getY(), select1 ), vec_sel( quat0.getZ(), quat1.getZ(), select1 ), vec_sel( quat0.getW(), quat1.getW(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Quat & quat ) { Aos::Quat vec0, vec1, vec2, vec3; quat.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } inline void print( const Quat & quat, const char * name ) { Aos::Quat vec0, vec1, vec2, vec3; printf( "%s:\n", name ); quat.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } #endif } // namespace Soa } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/ppu/cpp/vec_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_CPP_H #define _VECTORMATH_VEC_AOS_CPP_H //----------------------------------------------------------------------------- // Constants // for permutes words are labeled [x,y,z,w] [a,b,c,d] #define _VECTORMATH_PERM_X 0x00010203 #define _VECTORMATH_PERM_Y 0x04050607 #define _VECTORMATH_PERM_Z 0x08090a0b #define _VECTORMATH_PERM_W 0x0c0d0e0f #define _VECTORMATH_PERM_A 0x10111213 #define _VECTORMATH_PERM_B 0x14151617 #define _VECTORMATH_PERM_C 0x18191a1b #define _VECTORMATH_PERM_D 0x1c1d1e1f #define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A } #define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B } #define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C } #define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W } #define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W } #define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 } #define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 } #define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 } #define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff } #define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f } #define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f } #define _VECTORMATH_SLERP_TOL 0.999f //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS static inline vec_float4 _vmathVfDot3( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 result; result = vec_madd( vec0, vec1, (vec_float4){0.0f,0.0f,0.0f,0.0f} ); result = vec_madd( vec_sld( vec0, vec0, 4 ), vec_sld( vec1, vec1, 4 ), result ); return vec_madd( vec_sld( vec0, vec0, 8 ), vec_sld( vec1, vec1, 8 ), result ); } static inline vec_float4 _vmathVfDot4( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 result; result = vec_madd( vec0, vec1, (vec_float4){0.0f,0.0f,0.0f,0.0f} ); result = vec_madd( vec_sld( vec0, vec0, 4 ), vec_sld( vec1, vec1, 4 ), result ); return vec_add( vec_sld( result, result, 8 ), result ); } static inline vec_float4 _vmathVfCross( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 tmp0, tmp1, tmp2, tmp3, result; tmp0 = vec_perm( vec0, vec0, _VECTORMATH_PERM_YZXW ); tmp1 = vec_perm( vec1, vec1, _VECTORMATH_PERM_ZXYW ); tmp2 = vec_perm( vec0, vec0, _VECTORMATH_PERM_ZXYW ); tmp3 = vec_perm( vec1, vec1, _VECTORMATH_PERM_YZXW ); result = vec_madd( tmp0, tmp1, (vec_float4){0.0f,0.0f,0.0f,0.0f} ); result = vec_nmsub( tmp2, tmp3, result ); return result; } static inline vec_uint4 _vmathVfToHalfFloatsUnpacked(vec_float4 v) { vec_int4 bexp; vec_uint4 mant, sign, hfloat; vec_uint4 notZero, isInf; const vec_uint4 hfloatInf = (vec_uint4){0x00007c00u,0x00007c00u,0x00007c00u,0x00007c00u}; const vec_uint4 mergeMant = (vec_uint4){0x000003ffu,0x000003ffu,0x000003ffu,0x000003ffu}; const vec_uint4 mergeSign = (vec_uint4){0x00008000u,0x00008000u,0x00008000u,0x00008000u}; sign = vec_sr((vec_uint4)v, (vec_uint4){16,16,16,16}); mant = vec_sr((vec_uint4)v, (vec_uint4){13,13,13,13}); bexp = vec_and(vec_sr((vec_int4)v, (vec_uint4){23,23,23,23}), (vec_int4){0xff,0xff,0xff,0xff}); notZero = (vec_uint4)vec_cmpgt(bexp, (vec_int4){112,112,112,112}); isInf = (vec_uint4)vec_cmpgt(bexp, (vec_int4){142,142,142,142}); bexp = vec_add(bexp, (vec_int4){-112,-112,-112,-112}); bexp = vec_sl(bexp, (vec_uint4){10,10,10,10}); hfloat = vec_sel((vec_uint4)bexp, mant, mergeMant); hfloat = vec_sel((vec_uint4){0,0,0,0}, hfloat, notZero); hfloat = vec_sel(hfloat, hfloatInf, isInf); hfloat = vec_sel(hfloat, sign, mergeSign); return hfloat; } static inline vec_ushort8 _vmath2VfToHalfFloats(vec_float4 u, vec_float4 v) { vec_uint4 hfloat_u, hfloat_v; const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31}; hfloat_u = _vmathVfToHalfFloatsUnpacked(u); hfloat_v = _vmathVfToHalfFloatsUnpacked(v); return (vec_ushort8)vec_perm(hfloat_u, hfloat_v, pack); } #ifndef __GNUC__ #define __builtin_constant_p(x) 0 #endif static inline vec_float4 _vmathVfInsert(vec_float4 dst, vec_float4 src, int slot) { #ifdef __GNUC__ if (__builtin_constant_p(slot)) { dst = vec_sld(dst, dst, slot<<2); dst = vec_sld(dst, src, 4); if (slot != 3) dst = vec_sld(dst, dst, (3-slot)<<2); return dst; } else #endif { vec_uchar16 shiftpattern = vec_lvsr( 0, (float *)(size_t)(slot<<2) ); vec_uint4 selectmask = (vec_uint4)vec_perm( (vec_uint4){0,0,0,0}, _VECTORMATH_MASK_0xF000, shiftpattern ); return vec_sel( dst, src, selectmask ); } } #define _vmathVfGetElement(vec, slot) ((float *)&(vec))[slot] #ifdef _VECTORMATH_SET_CONSTS_IN_MEM #define _vmathVfSetElement(vec, scalar, slot) ((float *)&(vec))[slot] = scalar #else #define _vmathVfSetElement(vec, scalar, slot) \ { \ if (__builtin_constant_p(scalar)) { \ (vec) = _vmathVfInsert(vec, (vec_float4){scalar, scalar, scalar, scalar}, slot); \ } else { \ ((float *)&(vec))[slot] = scalar; \ } \ } #endif static inline vec_float4 _vmathVfSplatScalar(float scalar) { vec_float4 result; if (__builtin_constant_p(scalar)) { result = (vec_float4){scalar, scalar, scalar, scalar}; } else { result = vec_ld(0, &scalar); result = vec_splat(vec_perm(result, result, vec_lvsl(0, &scalar)), 0); } return result; } static inline vec_uint4 _vmathVuiSplatScalar(unsigned int scalar) { vec_uint4 result; if (__builtin_constant_p(scalar)) { result = (vec_uint4){scalar, scalar, scalar, scalar}; } else { result = vec_ld(0, &scalar); result = vec_splat(vec_perm(result, result, vec_lvsl(0, &scalar)), 0); } return result; } #endif namespace Vectormath { namespace Aos { #ifdef _VECTORMATH_NO_SCALAR_CAST inline VecIdx::operator floatInVec() const { return floatInVec(ref, i); } inline float VecIdx::getAsFloat() const #else inline VecIdx::operator float() const #endif { return _vmathVfGetElement(ref, i); } inline float VecIdx::operator =( float scalar ) { _vmathVfSetElement(ref, scalar, i); return scalar; } inline floatInVec VecIdx::operator =( floatInVec scalar ) { ref = _vmathVfInsert(ref, scalar.get128(), i); return scalar; } inline floatInVec VecIdx::operator =( const VecIdx& scalar ) { return *this = floatInVec(scalar.ref, scalar.i); } inline floatInVec VecIdx::operator *=( float scalar ) { return *this *= floatInVec(scalar); } inline floatInVec VecIdx::operator *=( floatInVec scalar ) { return *this = floatInVec(ref, i) * scalar; } inline floatInVec VecIdx::operator /=( float scalar ) { return *this /= floatInVec(scalar); } inline floatInVec VecIdx::operator /=( floatInVec scalar ) { return *this = floatInVec(ref, i) / scalar; } inline floatInVec VecIdx::operator +=( float scalar ) { return *this += floatInVec(scalar); } inline floatInVec VecIdx::operator +=( floatInVec scalar ) { return *this = floatInVec(ref, i) + scalar; } inline floatInVec VecIdx::operator -=( float scalar ) { return *this -= floatInVec(scalar); } inline floatInVec VecIdx::operator -=( floatInVec scalar ) { return *this = floatInVec(ref, i) - scalar; } inline Vector3::Vector3( float _x, float _y, float _z ) { if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z)) { mVec128 = (vec_float4){_x, _y, _z, 0.0f}; } else { float *pf = (float *)&mVec128; pf[0] = _x; pf[1] = _y; pf[2] = _z; } } inline Vector3::Vector3( floatInVec _x, floatInVec _y, floatInVec _z ) { vec_float4 xz = vec_mergeh( _x.get128(), _z.get128() ); mVec128 = vec_mergeh( xz, _y.get128() ); } inline Vector3::Vector3( Point3 pnt ) { mVec128 = pnt.get128(); } inline Vector3::Vector3( float scalar ) { mVec128 = floatInVec(scalar).get128(); } inline Vector3::Vector3( floatInVec scalar ) { mVec128 = scalar.get128(); } inline Vector3::Vector3( vec_float4 vf4 ) { mVec128 = vf4; } inline const Vector3 Vector3::xAxis( ) { return Vector3( _VECTORMATH_UNIT_1000 ); } inline const Vector3 Vector3::yAxis( ) { return Vector3( _VECTORMATH_UNIT_0100 ); } inline const Vector3 Vector3::zAxis( ) { return Vector3( _VECTORMATH_UNIT_0010 ); } inline const Vector3 lerp( float t, Vector3 vec0, Vector3 vec1 ) { return lerp( floatInVec(t), vec0, vec1 ); } inline const Vector3 lerp( floatInVec t, Vector3 vec0, Vector3 vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector3 slerp( float t, Vector3 unitVec0, Vector3 unitVec1 ) { return slerp( floatInVec(t), unitVec0, unitVec1 ); } inline const Vector3 slerp( floatInVec t, Vector3 unitVec0, Vector3 unitVec1 ) { vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); cosAngle = vec_splat( cosAngle, 0 ); selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle ); angle = acosf4( cosAngle ); tttt = t.get128(); oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( angles, oneMinusT ); angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sines = sinf4( angles ); scales = divf4( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); return Vector3( vec_madd( unitVec0.get128(), scale0, vec_madd( unitVec1.get128(), scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) ); } inline vec_float4 Vector3::get128( ) const { return mVec128; } inline void storeXYZ( Vector3 vec, vec_float4 * quad ) { vec_float4 dstVec = *quad; vec_uint4 mask = _VECTORMATH_MASK_0x000F; dstVec = vec_sel(vec.get128(), dstVec, mask); *quad = dstVec; } inline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyz1 = vec_sld( xyzx, yzxy, 12 ); xyz2 = vec_sld( yzxy, zxyz, 8 ); xyz3 = vec_sld( zxyz, zxyz, 4 ); vec0 = Vector3( xyzx ); vec1 = Vector3( xyz1 ); vec2 = Vector3( xyz2 ); vec3 = Vector3( xyz3 ); } inline void storeXYZArray( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz; xyzx = vec_perm( vec0.get128(), vec1.get128(), _VECTORMATH_PERM_XYZA ); yzxy = vec_perm( vec1.get128(), vec2.get128(), _VECTORMATH_PERM_YZAB ); zxyz = vec_perm( vec2.get128(), vec3.get128(), _VECTORMATH_PERM_ZABC ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } inline void storeHalfFloats( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4, Vector3 vec5, Vector3 vec6, Vector3 vec7, vec_ushort8 * threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; storeXYZArray( vec0, vec1, vec2, vec3, xyz0 ); storeXYZArray( vec4, vec5, vec6, vec7, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } inline Vector3 & Vector3::operator =( Vector3 vec ) { mVec128 = vec.mVec128; return *this; } inline Vector3 & Vector3::setX( float _x ) { _vmathVfSetElement(mVec128, _x, 0); return *this; } inline Vector3 & Vector3::setX( floatInVec _x ) { mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); return *this; } inline const floatInVec Vector3::getX( ) const { return floatInVec( mVec128, 0 ); } inline Vector3 & Vector3::setY( float _y ) { _vmathVfSetElement(mVec128, _y, 1); return *this; } inline Vector3 & Vector3::setY( floatInVec _y ) { mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); return *this; } inline const floatInVec Vector3::getY( ) const { return floatInVec( mVec128, 1 ); } inline Vector3 & Vector3::setZ( float _z ) { _vmathVfSetElement(mVec128, _z, 2); return *this; } inline Vector3 & Vector3::setZ( floatInVec _z ) { mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); return *this; } inline const floatInVec Vector3::getZ( ) const { return floatInVec( mVec128, 2 ); } inline Vector3 & Vector3::setElem( int idx, float value ) { _vmathVfSetElement(mVec128, value, idx); return *this; } inline Vector3 & Vector3::setElem( int idx, floatInVec value ) { mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); return *this; } inline const floatInVec Vector3::getElem( int idx ) const { return floatInVec( mVec128, idx ); } inline VecIdx Vector3::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline const floatInVec Vector3::operator []( int idx ) const { return floatInVec( mVec128, idx ); } inline const Vector3 Vector3::operator +( Vector3 vec ) const { return Vector3( vec_add( mVec128, vec.mVec128 ) ); } inline const Vector3 Vector3::operator -( Vector3 vec ) const { return Vector3( vec_sub( mVec128, vec.mVec128 ) ); } inline const Point3 Vector3::operator +( Point3 pnt ) const { return Point3( vec_add( mVec128, pnt.get128() ) ); } inline const Vector3 Vector3::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Vector3 Vector3::operator *( floatInVec scalar ) const { return Vector3( vec_madd( mVec128, scalar.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline Vector3 & Vector3::operator +=( Vector3 vec ) { *this = *this + vec; return *this; } inline Vector3 & Vector3::operator -=( Vector3 vec ) { *this = *this - vec; return *this; } inline Vector3 & Vector3::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline Vector3 & Vector3::operator *=( floatInVec scalar ) { *this = *this * scalar; return *this; } inline const Vector3 Vector3::operator /( float scalar ) const { return *this / floatInVec(scalar); } inline const Vector3 Vector3::operator /( floatInVec scalar ) const { return Vector3( divf4( mVec128, scalar.get128() ) ); } inline Vector3 & Vector3::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline Vector3 & Vector3::operator /=( floatInVec scalar ) { *this = *this / scalar; return *this; } inline const Vector3 Vector3::operator -( ) const { return Vector3( negatef4( mVec128 ) ); } inline const Vector3 operator *( float scalar, Vector3 vec ) { return floatInVec(scalar) * vec; } inline const Vector3 operator *( floatInVec scalar, Vector3 vec ) { return vec * scalar; } inline const Vector3 mulPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( vec_madd( vec0.get128(), vec1.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Vector3 divPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( divf4( vec0.get128(), vec1.get128() ) ); } inline const Vector3 recipPerElem( Vector3 vec ) { return Vector3( recipf4( vec.get128() ) ); } inline const Vector3 sqrtPerElem( Vector3 vec ) { return Vector3( sqrtf4( vec.get128() ) ); } inline const Vector3 rsqrtPerElem( Vector3 vec ) { return Vector3( rsqrtf4( vec.get128() ) ); } inline const Vector3 absPerElem( Vector3 vec ) { return Vector3( fabsf4( vec.get128() ) ); } inline const Vector3 copySignPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( copysignf4( vec0.get128(), vec1.get128() ) ); } inline const Vector3 maxPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( fmaxf4( vec0.get128(), vec1.get128() ) ); } inline const floatInVec maxElem( Vector3 vec ) { vec_float4 result; result = fmaxf4( vec_splat( vec.get128(), 1 ), vec.get128() ); result = fmaxf4( vec_splat( vec.get128(), 2 ), result ); return floatInVec( result, 0 ); } inline const Vector3 minPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( fminf4( vec0.get128(), vec1.get128() ) ); } inline const floatInVec minElem( Vector3 vec ) { vec_float4 result; result = fminf4( vec_splat( vec.get128(), 1 ), vec.get128() ); result = fminf4( vec_splat( vec.get128(), 2 ), result ); return floatInVec( result, 0 ); } inline const floatInVec sum( Vector3 vec ) { vec_float4 result; result = vec_add( vec_splat( vec.get128(), 1 ), vec.get128() ); result = vec_add( vec_splat( vec.get128(), 2 ), result ); return floatInVec( result, 0 ); } inline const floatInVec dot( Vector3 vec0, Vector3 vec1 ) { return floatInVec( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 ); } inline const floatInVec lengthSqr( Vector3 vec ) { return floatInVec( _vmathVfDot3( vec.get128(), vec.get128() ), 0 ); } inline const floatInVec length( Vector3 vec ) { return floatInVec( sqrtf4(_vmathVfDot3( vec.get128(), vec.get128() )), 0 ); } inline const Vector3 normalize( Vector3 vec ) { vec_float4 dot = _vmathVfDot3( vec.get128(), vec.get128() ); dot = vec_splat( dot, 0 ); return Vector3( vec_madd( vec.get128(), rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Vector3 cross( Vector3 vec0, Vector3 vec1 ) { return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) ); } inline const Vector3 select( Vector3 vec0, Vector3 vec1, bool select1 ) { return select( vec0, vec1, boolInVec(select1) ); } inline const Vector3 select( Vector3 vec0, Vector3 vec1, boolInVec select1 ) { return Vector3( vec_sel( vec0.get128(), vec1.get128(), select1.get128() ) ); } #ifdef _VECTORMATH_DEBUG inline void print( Vector3 vec ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } inline void print( Vector3 vec, const char * name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif inline Vector4::Vector4( float _x, float _y, float _z, float _w ) { if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z) & __builtin_constant_p(_w)) { mVec128 = (vec_float4){_x, _y, _z, _w}; } else { float *pf = (float *)&mVec128; pf[0] = _x; pf[1] = _y; pf[2] = _z; pf[3] = _w; } } inline Vector4::Vector4( floatInVec _x, floatInVec _y, floatInVec _z, floatInVec _w ) { vec_float4 xz = vec_mergeh( _x.get128(), _z.get128() ); vec_float4 yw = vec_mergeh( _y.get128(), _w.get128() ); mVec128 = vec_mergeh( xz, yw ); } inline Vector4::Vector4( Vector3 xyz, float _w ) { mVec128 = xyz.get128(); _vmathVfSetElement(mVec128, _w, 3); } inline Vector4::Vector4( Vector3 xyz, floatInVec _w ) { mVec128 = xyz.get128(); mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); } inline Vector4::Vector4( Vector3 vec ) { mVec128 = vec.get128(); mVec128 = _vmathVfInsert(mVec128, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), 3); } inline Vector4::Vector4( Point3 pnt ) { mVec128 = pnt.get128(); mVec128 = _vmathVfInsert(mVec128, ((vec_float4){1.0f,1.0f,1.0f,1.0f}), 3); } inline Vector4::Vector4( Quat quat ) { mVec128 = quat.get128(); } inline Vector4::Vector4( float scalar ) { mVec128 = floatInVec(scalar).get128(); } inline Vector4::Vector4( floatInVec scalar ) { mVec128 = scalar.get128(); } inline Vector4::Vector4( vec_float4 vf4 ) { mVec128 = vf4; } inline const Vector4 Vector4::xAxis( ) { return Vector4( _VECTORMATH_UNIT_1000 ); } inline const Vector4 Vector4::yAxis( ) { return Vector4( _VECTORMATH_UNIT_0100 ); } inline const Vector4 Vector4::zAxis( ) { return Vector4( _VECTORMATH_UNIT_0010 ); } inline const Vector4 Vector4::wAxis( ) { return Vector4( _VECTORMATH_UNIT_0001 ); } inline const Vector4 lerp( float t, Vector4 vec0, Vector4 vec1 ) { return lerp( floatInVec(t), vec0, vec1 ); } inline const Vector4 lerp( floatInVec t, Vector4 vec0, Vector4 vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector4 slerp( float t, Vector4 unitVec0, Vector4 unitVec1 ) { return slerp( floatInVec(t), unitVec0, unitVec1 ); } inline const Vector4 slerp( floatInVec t, Vector4 unitVec0, Vector4 unitVec1 ) { vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() ); cosAngle = vec_splat( cosAngle, 0 ); selectMask = (vec_uint4)vec_cmpgt( ((vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}), cosAngle ); angle = acosf4( cosAngle ); tttt = t.get128(); oneMinusT = vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), tttt ); angles = vec_mergeh( angles, oneMinusT ); angles = vec_madd( angles, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); sines = sinf4( angles ); scales = divf4( sines, vec_splat( sines, 0 ) ); scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); return Vector4( vec_madd( unitVec0.get128(), scale0, vec_madd( unitVec1.get128(), scale1, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ) ); } inline vec_float4 Vector4::get128( ) const { return mVec128; } inline void storeHalfFloats( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3, vec_ushort8 * twoQuads ) { twoQuads[0] = _vmath2VfToHalfFloats(vec0.get128(), vec1.get128()); twoQuads[1] = _vmath2VfToHalfFloats(vec2.get128(), vec3.get128()); } inline Vector4 & Vector4::operator =( Vector4 vec ) { mVec128 = vec.mVec128; return *this; } inline Vector4 & Vector4::setXYZ( Vector3 vec ) { mVec128 = vec_sel( vec.get128(), mVec128, _VECTORMATH_MASK_0x000F ); return *this; } inline const Vector3 Vector4::getXYZ( ) const { return Vector3( mVec128 ); } inline Vector4 & Vector4::setX( float _x ) { _vmathVfSetElement(mVec128, _x, 0); return *this; } inline Vector4 & Vector4::setX( floatInVec _x ) { mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); return *this; } inline const floatInVec Vector4::getX( ) const { return floatInVec( mVec128, 0 ); } inline Vector4 & Vector4::setY( float _y ) { _vmathVfSetElement(mVec128, _y, 1); return *this; } inline Vector4 & Vector4::setY( floatInVec _y ) { mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); return *this; } inline const floatInVec Vector4::getY( ) const { return floatInVec( mVec128, 1 ); } inline Vector4 & Vector4::setZ( float _z ) { _vmathVfSetElement(mVec128, _z, 2); return *this; } inline Vector4 & Vector4::setZ( floatInVec _z ) { mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); return *this; } inline const floatInVec Vector4::getZ( ) const { return floatInVec( mVec128, 2 ); } inline Vector4 & Vector4::setW( float _w ) { _vmathVfSetElement(mVec128, _w, 3); return *this; } inline Vector4 & Vector4::setW( floatInVec _w ) { mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); return *this; } inline const floatInVec Vector4::getW( ) const { return floatInVec( mVec128, 3 ); } inline Vector4 & Vector4::setElem( int idx, float value ) { _vmathVfSetElement(mVec128, value, idx); return *this; } inline Vector4 & Vector4::setElem( int idx, floatInVec value ) { mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); return *this; } inline const floatInVec Vector4::getElem( int idx ) const { return floatInVec( mVec128, idx ); } inline VecIdx Vector4::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline const floatInVec Vector4::operator []( int idx ) const { return floatInVec( mVec128, idx ); } inline const Vector4 Vector4::operator +( Vector4 vec ) const { return Vector4( vec_add( mVec128, vec.mVec128 ) ); } inline const Vector4 Vector4::operator -( Vector4 vec ) const { return Vector4( vec_sub( mVec128, vec.mVec128 ) ); } inline const Vector4 Vector4::operator *( float scalar ) const { return *this * floatInVec(scalar); } inline const Vector4 Vector4::operator *( floatInVec scalar ) const { return Vector4( vec_madd( mVec128, scalar.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline Vector4 & Vector4::operator +=( Vector4 vec ) { *this = *this + vec; return *this; } inline Vector4 & Vector4::operator -=( Vector4 vec ) { *this = *this - vec; return *this; } inline Vector4 & Vector4::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline Vector4 & Vector4::operator *=( floatInVec scalar ) { *this = *this * scalar; return *this; } inline const Vector4 Vector4::operator /( float scalar ) const { return *this / floatInVec(scalar); } inline const Vector4 Vector4::operator /( floatInVec scalar ) const { return Vector4( divf4( mVec128, scalar.get128() ) ); } inline Vector4 & Vector4::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline Vector4 & Vector4::operator /=( floatInVec scalar ) { *this = *this / scalar; return *this; } inline const Vector4 Vector4::operator -( ) const { return Vector4( negatef4( mVec128 ) ); } inline const Vector4 operator *( float scalar, Vector4 vec ) { return floatInVec(scalar) * vec; } inline const Vector4 operator *( floatInVec scalar, Vector4 vec ) { return vec * scalar; } inline const Vector4 mulPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( vec_madd( vec0.get128(), vec1.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Vector4 divPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( divf4( vec0.get128(), vec1.get128() ) ); } inline const Vector4 recipPerElem( Vector4 vec ) { return Vector4( recipf4( vec.get128() ) ); } inline const Vector4 sqrtPerElem( Vector4 vec ) { return Vector4( sqrtf4( vec.get128() ) ); } inline const Vector4 rsqrtPerElem( Vector4 vec ) { return Vector4( rsqrtf4( vec.get128() ) ); } inline const Vector4 absPerElem( Vector4 vec ) { return Vector4( fabsf4( vec.get128() ) ); } inline const Vector4 copySignPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( copysignf4( vec0.get128(), vec1.get128() ) ); } inline const Vector4 maxPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( fmaxf4( vec0.get128(), vec1.get128() ) ); } inline const floatInVec maxElem( Vector4 vec ) { vec_float4 result; result = fmaxf4( vec_splat( vec.get128(), 1 ), vec.get128() ); result = fmaxf4( vec_splat( vec.get128(), 2 ), result ); result = fmaxf4( vec_splat( vec.get128(), 3 ), result ); return floatInVec( result, 0 ); } inline const Vector4 minPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( fminf4( vec0.get128(), vec1.get128() ) ); } inline const floatInVec minElem( Vector4 vec ) { vec_float4 result; result = fminf4( vec_splat( vec.get128(), 1 ), vec.get128() ); result = fminf4( vec_splat( vec.get128(), 2 ), result ); result = fminf4( vec_splat( vec.get128(), 3 ), result ); return floatInVec( result, 0 ); } inline const floatInVec sum( Vector4 vec ) { vec_float4 result; result = vec_add( vec_splat( vec.get128(), 1 ), vec.get128() ); result = vec_add( vec_splat( vec.get128(), 2 ), result ); result = vec_add( vec_splat( vec.get128(), 3 ), result ); return floatInVec( result, 0 ); } inline const floatInVec dot( Vector4 vec0, Vector4 vec1 ) { return floatInVec( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 ); } inline const floatInVec lengthSqr( Vector4 vec ) { return floatInVec( _vmathVfDot4( vec.get128(), vec.get128() ), 0 ); } inline const floatInVec length( Vector4 vec ) { return floatInVec( sqrtf4(_vmathVfDot4( vec.get128(), vec.get128() )), 0 ); } inline const Vector4 normalize( Vector4 vec ) { vec_float4 dot = _vmathVfDot4( vec.get128(), vec.get128() ); return Vector4( vec_madd( vec.get128(), rsqrtf4( dot ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Vector4 select( Vector4 vec0, Vector4 vec1, bool select1 ) { return select( vec0, vec1, boolInVec(select1) ); } inline const Vector4 select( Vector4 vec0, Vector4 vec1, boolInVec select1 ) { return Vector4( vec_sel( vec0.get128(), vec1.get128(), select1.get128() ) ); } #ifdef _VECTORMATH_DEBUG inline void print( Vector4 vec ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } inline void print( Vector4 vec, const char * name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif inline Point3::Point3( float _x, float _y, float _z ) { if (__builtin_constant_p(_x) & __builtin_constant_p(_y) & __builtin_constant_p(_z)) { mVec128 = (vec_float4){_x, _y, _z, 0.0f}; } else { float *pf = (float *)&mVec128; pf[0] = _x; pf[1] = _y; pf[2] = _z; } } inline Point3::Point3( floatInVec _x, floatInVec _y, floatInVec _z ) { vec_float4 xz = vec_mergeh( _x.get128(), _z.get128() ); mVec128 = vec_mergeh( xz, _y.get128() ); } inline Point3::Point3( Vector3 vec ) { mVec128 = vec.get128(); } inline Point3::Point3( float scalar ) { mVec128 = floatInVec(scalar).get128(); } inline Point3::Point3( floatInVec scalar ) { mVec128 = scalar.get128(); } inline Point3::Point3( vec_float4 vf4 ) { mVec128 = vf4; } inline const Point3 lerp( float t, Point3 pnt0, Point3 pnt1 ) { return lerp( floatInVec(t), pnt0, pnt1 ); } inline const Point3 lerp( floatInVec t, Point3 pnt0, Point3 pnt1 ) { return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); } inline vec_float4 Point3::get128( ) const { return mVec128; } inline void storeXYZ( Point3 pnt, vec_float4 * quad ) { vec_float4 dstVec = *quad; vec_uint4 mask = _VECTORMATH_MASK_0x000F; dstVec = vec_sel(pnt.get128(), dstVec, mask); *quad = dstVec; } inline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyz1 = vec_sld( xyzx, yzxy, 12 ); xyz2 = vec_sld( yzxy, zxyz, 8 ); xyz3 = vec_sld( zxyz, zxyz, 4 ); pnt0 = Point3( xyzx ); pnt1 = Point3( xyz1 ); pnt2 = Point3( xyz2 ); pnt3 = Point3( xyz3 ); } inline void storeXYZArray( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz; xyzx = vec_perm( pnt0.get128(), pnt1.get128(), _VECTORMATH_PERM_XYZA ); yzxy = vec_perm( pnt1.get128(), pnt2.get128(), _VECTORMATH_PERM_YZAB ); zxyz = vec_perm( pnt2.get128(), pnt3.get128(), _VECTORMATH_PERM_ZABC ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } inline void storeHalfFloats( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, Point3 pnt4, Point3 pnt5, Point3 pnt6, Point3 pnt7, vec_ushort8 * threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; storeXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 ); storeXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } inline Point3 & Point3::operator =( Point3 pnt ) { mVec128 = pnt.mVec128; return *this; } inline Point3 & Point3::setX( float _x ) { _vmathVfSetElement(mVec128, _x, 0); return *this; } inline Point3 & Point3::setX( floatInVec _x ) { mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); return *this; } inline const floatInVec Point3::getX( ) const { return floatInVec( mVec128, 0 ); } inline Point3 & Point3::setY( float _y ) { _vmathVfSetElement(mVec128, _y, 1); return *this; } inline Point3 & Point3::setY( floatInVec _y ) { mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); return *this; } inline const floatInVec Point3::getY( ) const { return floatInVec( mVec128, 1 ); } inline Point3 & Point3::setZ( float _z ) { _vmathVfSetElement(mVec128, _z, 2); return *this; } inline Point3 & Point3::setZ( floatInVec _z ) { mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); return *this; } inline const floatInVec Point3::getZ( ) const { return floatInVec( mVec128, 2 ); } inline Point3 & Point3::setElem( int idx, float value ) { _vmathVfSetElement(mVec128, value, idx); return *this; } inline Point3 & Point3::setElem( int idx, floatInVec value ) { mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); return *this; } inline const floatInVec Point3::getElem( int idx ) const { return floatInVec( mVec128, idx ); } inline VecIdx Point3::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline const floatInVec Point3::operator []( int idx ) const { return floatInVec( mVec128, idx ); } inline const Vector3 Point3::operator -( Point3 pnt ) const { return Vector3( vec_sub( mVec128, pnt.mVec128 ) ); } inline const Point3 Point3::operator +( Vector3 vec ) const { return Point3( vec_add( mVec128, vec.get128() ) ); } inline const Point3 Point3::operator -( Vector3 vec ) const { return Point3( vec_sub( mVec128, vec.get128() ) ); } inline Point3 & Point3::operator +=( Vector3 vec ) { *this = *this + vec; return *this; } inline Point3 & Point3::operator -=( Vector3 vec ) { *this = *this - vec; return *this; } inline const Point3 mulPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( vec_madd( pnt0.get128(), pnt1.get128(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Point3 divPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( divf4( pnt0.get128(), pnt1.get128() ) ); } inline const Point3 recipPerElem( Point3 pnt ) { return Point3( recipf4( pnt.get128() ) ); } inline const Point3 sqrtPerElem( Point3 pnt ) { return Point3( sqrtf4( pnt.get128() ) ); } inline const Point3 rsqrtPerElem( Point3 pnt ) { return Point3( rsqrtf4( pnt.get128() ) ); } inline const Point3 absPerElem( Point3 pnt ) { return Point3( fabsf4( pnt.get128() ) ); } inline const Point3 copySignPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( copysignf4( pnt0.get128(), pnt1.get128() ) ); } inline const Point3 maxPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( fmaxf4( pnt0.get128(), pnt1.get128() ) ); } inline const floatInVec maxElem( Point3 pnt ) { vec_float4 result; result = fmaxf4( vec_splat( pnt.get128(), 1 ), pnt.get128() ); result = fmaxf4( vec_splat( pnt.get128(), 2 ), result ); return floatInVec( result, 0 ); } inline const Point3 minPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( fminf4( pnt0.get128(), pnt1.get128() ) ); } inline const floatInVec minElem( Point3 pnt ) { vec_float4 result; result = fminf4( vec_splat( pnt.get128(), 1 ), pnt.get128() ); result = fminf4( vec_splat( pnt.get128(), 2 ), result ); return floatInVec( result, 0 ); } inline const floatInVec sum( Point3 pnt ) { vec_float4 result; result = vec_add( vec_splat( pnt.get128(), 1 ), pnt.get128() ); result = vec_add( vec_splat( pnt.get128(), 2 ), result ); return floatInVec( result, 0 ); } inline const Point3 scale( Point3 pnt, float scaleVal ) { return scale( pnt, floatInVec( scaleVal ) ); } inline const Point3 scale( Point3 pnt, floatInVec scaleVal ) { return mulPerElem( pnt, Point3( scaleVal ) ); } inline const Point3 scale( Point3 pnt, Vector3 scaleVec ) { return mulPerElem( pnt, Point3( scaleVec ) ); } inline const floatInVec projection( Point3 pnt, Vector3 unitVec ) { return floatInVec( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 ); } inline const floatInVec distSqrFromOrigin( Point3 pnt ) { return lengthSqr( Vector3( pnt ) ); } inline const floatInVec distFromOrigin( Point3 pnt ) { return length( Vector3( pnt ) ); } inline const floatInVec distSqr( Point3 pnt0, Point3 pnt1 ) { return lengthSqr( ( pnt1 - pnt0 ) ); } inline const floatInVec dist( Point3 pnt0, Point3 pnt1 ) { return length( ( pnt1 - pnt0 ) ); } inline const Point3 select( Point3 pnt0, Point3 pnt1, bool select1 ) { return select( pnt0, pnt1, boolInVec(select1) ); } inline const Point3 select( Point3 pnt0, Point3 pnt1, boolInVec select1 ) { return Point3( vec_sel( pnt0.get128(), pnt1.get128(), select1.get128() ) ); } #ifdef _VECTORMATH_DEBUG inline void print( Point3 pnt ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = pnt.get128(); printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } inline void print( Point3 pnt, const char * name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = pnt.get128(); printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/ppu/cpp/vec_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_SOA_CPP_H #define _VECTORMATH_VEC_SOA_CPP_H //----------------------------------------------------------------------------- // Constants // for permutes, words are labeled [x,y,z,w] [a,b,c,d] #define _VECTORMATH_PERM_X 0x00010203 #define _VECTORMATH_PERM_Y 0x04050607 #define _VECTORMATH_PERM_Z 0x08090a0b #define _VECTORMATH_PERM_W 0x0c0d0e0f #define _VECTORMATH_PERM_A 0x10111213 #define _VECTORMATH_PERM_B 0x14151617 #define _VECTORMATH_PERM_C 0x18191a1b #define _VECTORMATH_PERM_D 0x1c1d1e1f #define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_ZDWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) #define _VECTORMATH_PERM_ZCXA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_XBZD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_WDYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B }) #define _VECTORMATH_PERM_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X, _VECTORMATH_PERM_D }) #define _VECTORMATH_PERM_WCYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) #define _VECTORMATH_PERM_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_D, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B }) #define _VECTORMATH_SLERP_TOL 0.999f //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Soa { inline Vector3::Vector3( const Vector3 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; } inline Vector3::Vector3( vec_float4 _x, vec_float4 _y, vec_float4 _z ) { mX = _x; mY = _y; mZ = _z; } inline Vector3::Vector3( const Point3 & pnt ) { mX = pnt.getX(); mY = pnt.getY(); mZ = pnt.getZ(); } inline Vector3::Vector3( vec_float4 scalar ) { mX = scalar; mY = scalar; mZ = scalar; } inline Vector3::Vector3( Aos::Vector3 vec ) { vec_float4 vec128 = vec.get128(); mX = vec_splat( vec128, 0 ); mY = vec_splat( vec128, 1 ); mZ = vec_splat( vec128, 2 ); } inline Vector3::Vector3( Aos::Vector3 vec0, Aos::Vector3 vec1, Aos::Vector3 vec2, Aos::Vector3 vec3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( vec0.get128(), vec2.get128() ); tmp1 = vec_mergeh( vec1.get128(), vec3.get128() ); tmp2 = vec_mergel( vec0.get128(), vec2.get128() ); tmp3 = vec_mergel( vec1.get128(), vec3.get128() ); mX = vec_mergeh( tmp0, tmp1 ); mY = vec_mergel( tmp0, tmp1 ); mZ = vec_mergeh( tmp2, tmp3 ); } inline const Vector3 Vector3::xAxis( ) { 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}) ); } inline const Vector3 Vector3::yAxis( ) { 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}) ); } inline const Vector3 Vector3::zAxis( ) { 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}) ); } inline const Vector3 lerp( vec_float4 t, const Vector3 & vec0, const Vector3 & vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector3 slerp( vec_float4 t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) { vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = dot( unitVec0, unitVec1 ); selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) ); 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 ); 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 ); return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); } inline void Vector3::get4Aos( Aos::Vector3 & result0, Aos::Vector3 & result1, Aos::Vector3 & result2, Aos::Vector3 & result3 ) const { vec_float4 tmp0, tmp1; tmp0 = vec_mergeh( mX, mZ ); tmp1 = vec_mergel( mX, mZ ); result0 = Aos::Vector3( vec_mergeh( tmp0, mY ) ); result1 = Aos::Vector3( vec_perm( tmp0, mY, _VECTORMATH_PERM_ZBWX ) ); result2 = Aos::Vector3( vec_perm( tmp1, mY, _VECTORMATH_PERM_XCYX ) ); result3 = Aos::Vector3( vec_perm( tmp1, mY, _VECTORMATH_PERM_ZDWX ) ); } inline void loadXYZArray( Vector3 & vec, const vec_float4 * threeQuads ) { vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyxy = vec_sld( yzxy, xyzx, 8 ); zxzx = vec_sld( xyzx, zxyz, 8 ); yzyz = vec_sld( zxyz, yzxy, 8 ); vec.setX( vec_perm( xyxy, zxzx, _VECTORMATH_PERM_ZBXD ) ); vec.setY( vec_perm( xyxy, yzyz, _VECTORMATH_PERM_WCYA ) ); vec.setZ( vec_perm( zxzx, yzyz, _VECTORMATH_PERM_XDZB ) ); } inline void storeXYZArray( const Vector3 & vec, vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz; xyxy = vec_perm( vec.getX(), vec.getY(), _VECTORMATH_PERM_ZCXA ); zxzx = vec_perm( vec.getZ(), vec.getX(), _VECTORMATH_PERM_XBZD ); yzyz = vec_perm( vec.getY(), vec.getZ(), _VECTORMATH_PERM_WDYB ); xyzx = vec_sld( xyxy, zxzx, 8 ); yzxy = vec_sld( yzyz, xyxy, 8 ); zxyz = vec_sld( zxzx, yzyz, 8 ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } inline void storeHalfFloats( const Vector3 & vec0, const Vector3 & vec1, vec_ushort8 * threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; storeXYZArray( vec0, xyz0 ); storeXYZArray( vec1, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } inline Vector3 & Vector3::operator =( const Vector3 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; return *this; } inline Vector3 & Vector3::setX( vec_float4 _x ) { mX = _x; return *this; } inline vec_float4 Vector3::getX( ) const { return mX; } inline Vector3 & Vector3::setY( vec_float4 _y ) { mY = _y; return *this; } inline vec_float4 Vector3::getY( ) const { return mY; } inline Vector3 & Vector3::setZ( vec_float4 _z ) { mZ = _z; return *this; } inline vec_float4 Vector3::getZ( ) const { return mZ; } inline Vector3 & Vector3::setElem( int idx, vec_float4 value ) { *(&mX + idx) = value; return *this; } inline vec_float4 Vector3::getElem( int idx ) const { return *(&mX + idx); } inline Vector3::vec_float4_t & Vector3::operator []( int idx ) { return *(&mX + idx); } inline vec_float4 Vector3::operator []( int idx ) const { return *(&mX + idx); } inline const Vector3 Vector3::operator +( const Vector3 & vec ) const { return Vector3( vec_add( mX, vec.mX ), vec_add( mY, vec.mY ), vec_add( mZ, vec.mZ ) ); } inline const Vector3 Vector3::operator -( const Vector3 & vec ) const { return Vector3( vec_sub( mX, vec.mX ), vec_sub( mY, vec.mY ), vec_sub( mZ, vec.mZ ) ); } inline const Point3 Vector3::operator +( const Point3 & pnt ) const { return Point3( vec_add( mX, pnt.getX() ), vec_add( mY, pnt.getY() ), vec_add( mZ, pnt.getZ() ) ); } inline const Vector3 Vector3::operator *( vec_float4 scalar ) const { return Vector3( vec_madd( mX, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mY, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mZ, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline Vector3 & Vector3::operator +=( const Vector3 & vec ) { *this = *this + vec; return *this; } inline Vector3 & Vector3::operator -=( const Vector3 & vec ) { *this = *this - vec; return *this; } inline Vector3 & Vector3::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Vector3 Vector3::operator /( vec_float4 scalar ) const { return Vector3( divf4( mX, scalar ), divf4( mY, scalar ), divf4( mZ, scalar ) ); } inline Vector3 & Vector3::operator /=( vec_float4 scalar ) { *this = *this / scalar; return *this; } inline const Vector3 Vector3::operator -( ) const { return Vector3( negatef4( mX ), negatef4( mY ), negatef4( mZ ) ); } inline const Vector3 operator *( vec_float4 scalar, const Vector3 & vec ) { return vec * scalar; } inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( vec_madd( vec0.getX(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0.getY(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0.getZ(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( divf4( vec0.getX(), vec1.getX() ), divf4( vec0.getY(), vec1.getY() ), divf4( vec0.getZ(), vec1.getZ() ) ); } inline const Vector3 recipPerElem( const Vector3 & vec ) { return Vector3( divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getX() ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getY() ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getZ() ) ); } inline const Vector3 sqrtPerElem( const Vector3 & vec ) { return Vector3( sqrtf4( vec.getX() ), sqrtf4( vec.getY() ), sqrtf4( vec.getZ() ) ); } inline const Vector3 rsqrtPerElem( const Vector3 & vec ) { return Vector3( divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getX() ) ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getY() ) ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getZ() ) ) ); } inline const Vector3 absPerElem( const Vector3 & vec ) { return Vector3( fabsf4( vec.getX() ), fabsf4( vec.getY() ), fabsf4( vec.getZ() ) ); } inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( copysignf4( vec0.getX(), vec1.getX() ), copysignf4( vec0.getY(), vec1.getY() ), copysignf4( vec0.getZ(), vec1.getZ() ) ); } inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( fmaxf4( vec0.getX(), vec1.getX() ), fmaxf4( vec0.getY(), vec1.getY() ), fmaxf4( vec0.getZ(), vec1.getZ() ) ); } inline vec_float4 maxElem( const Vector3 & vec ) { vec_float4 result; result = fmaxf4( vec.getX(), vec.getY() ); result = fmaxf4( vec.getZ(), result ); return result; } inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( fminf4( vec0.getX(), vec1.getX() ), fminf4( vec0.getY(), vec1.getY() ), fminf4( vec0.getZ(), vec1.getZ() ) ); } inline vec_float4 minElem( const Vector3 & vec ) { vec_float4 result; result = fminf4( vec.getX(), vec.getY() ); result = fminf4( vec.getZ(), result ); return result; } inline vec_float4 sum( const Vector3 & vec ) { vec_float4 result; result = vec_add( vec.getX(), vec.getY() ); result = vec_add( result, vec.getZ() ); return result; } inline vec_float4 dot( const Vector3 & vec0, const Vector3 & vec1 ) { vec_float4 result; result = vec_madd( vec0.getX(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( vec0.getY(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec0.getZ(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } inline vec_float4 lengthSqr( const Vector3 & vec ) { vec_float4 result; result = vec_madd( vec.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( vec.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } inline vec_float4 length( const Vector3 & vec ) { return sqrtf4( lengthSqr( vec ) ); } inline const Vector3 normalize( const Vector3 & vec ) { vec_float4 lenSqr, lenInv; lenSqr = lengthSqr( vec ); lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) ); return Vector3( vec_madd( vec.getX(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec.getY(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec.getZ(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( 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}) ) ), 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}) ) ), 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}) ) ) ); } inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, vec_uint4 select1 ) { return Vector3( vec_sel( vec0.getX(), vec1.getX(), select1 ), vec_sel( vec0.getY(), vec1.getY(), select1 ), vec_sel( vec0.getZ(), vec1.getZ(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Vector3 & vec ) { Aos::Vector3 vec0, vec1, vec2, vec3; vec.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } inline void print( const Vector3 & vec, const char * name ) { Aos::Vector3 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vec.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } #endif inline Vector4::Vector4( const Vector4 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; mW = vec.mW; } inline Vector4::Vector4( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { mX = _x; mY = _y; mZ = _z; mW = _w; } inline Vector4::Vector4( const Vector3 & xyz, vec_float4 _w ) { this->setXYZ( xyz ); this->setW( _w ); } inline Vector4::Vector4( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); mW = ((vec_float4){0.0f,0.0f,0.0f,0.0f}); } inline Vector4::Vector4( const Point3 & pnt ) { mX = pnt.getX(); mY = pnt.getY(); mZ = pnt.getZ(); mW = ((vec_float4){1.0f,1.0f,1.0f,1.0f}); } inline Vector4::Vector4( const Quat & quat ) { mX = quat.getX(); mY = quat.getY(); mZ = quat.getZ(); mW = quat.getW(); } inline Vector4::Vector4( vec_float4 scalar ) { mX = scalar; mY = scalar; mZ = scalar; mW = scalar; } inline Vector4::Vector4( Aos::Vector4 vec ) { vec_float4 vec128 = vec.get128(); mX = vec_splat( vec128, 0 ); mY = vec_splat( vec128, 1 ); mZ = vec_splat( vec128, 2 ); mW = vec_splat( vec128, 3 ); } inline Vector4::Vector4( Aos::Vector4 vec0, Aos::Vector4 vec1, Aos::Vector4 vec2, Aos::Vector4 vec3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( vec0.get128(), vec2.get128() ); tmp1 = vec_mergeh( vec1.get128(), vec3.get128() ); tmp2 = vec_mergel( vec0.get128(), vec2.get128() ); tmp3 = vec_mergel( vec1.get128(), vec3.get128() ); mX = vec_mergeh( tmp0, tmp1 ); mY = vec_mergel( tmp0, tmp1 ); mZ = vec_mergeh( tmp2, tmp3 ); mW = vec_mergel( tmp2, tmp3 ); } inline const Vector4 Vector4::xAxis( ) { 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}) ); } inline const Vector4 Vector4::yAxis( ) { 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}) ); } inline const Vector4 Vector4::zAxis( ) { 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}) ); } inline const Vector4 Vector4::wAxis( ) { 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}) ); } inline const Vector4 lerp( vec_float4 t, const Vector4 & vec0, const Vector4 & vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector4 slerp( vec_float4 t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) { vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = dot( unitVec0, unitVec1 ); selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) ); 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 ); 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 ); return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); } inline void Vector4::get4Aos( Aos::Vector4 & result0, Aos::Vector4 & result1, Aos::Vector4 & result2, Aos::Vector4 & result3 ) const { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( mX, mZ ); tmp1 = vec_mergeh( mY, mW ); tmp2 = vec_mergel( mX, mZ ); tmp3 = vec_mergel( mY, mW ); result0 = Aos::Vector4( vec_mergeh( tmp0, tmp1 ) ); result1 = Aos::Vector4( vec_mergel( tmp0, tmp1 ) ); result2 = Aos::Vector4( vec_mergeh( tmp2, tmp3 ) ); result3 = Aos::Vector4( vec_mergel( tmp2, tmp3 ) ); } inline void storeHalfFloats( const Vector4 & vec, vec_ushort8 * twoQuads ) { Aos::Vector4 v0, v1, v2, v3; vec.get4Aos( v0, v1, v2, v3 ); twoQuads[0] = _vmath2VfToHalfFloats(v0.get128(), v1.get128()); twoQuads[1] = _vmath2VfToHalfFloats(v2.get128(), v3.get128()); } inline Vector4 & Vector4::operator =( const Vector4 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; mW = vec.mW; return *this; } inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); return *this; } inline const Vector3 Vector4::getXYZ( ) const { return Vector3( mX, mY, mZ ); } inline Vector4 & Vector4::setX( vec_float4 _x ) { mX = _x; return *this; } inline vec_float4 Vector4::getX( ) const { return mX; } inline Vector4 & Vector4::setY( vec_float4 _y ) { mY = _y; return *this; } inline vec_float4 Vector4::getY( ) const { return mY; } inline Vector4 & Vector4::setZ( vec_float4 _z ) { mZ = _z; return *this; } inline vec_float4 Vector4::getZ( ) const { return mZ; } inline Vector4 & Vector4::setW( vec_float4 _w ) { mW = _w; return *this; } inline vec_float4 Vector4::getW( ) const { return mW; } inline Vector4 & Vector4::setElem( int idx, vec_float4 value ) { *(&mX + idx) = value; return *this; } inline vec_float4 Vector4::getElem( int idx ) const { return *(&mX + idx); } inline Vector4::vec_float4_t & Vector4::operator []( int idx ) { return *(&mX + idx); } inline vec_float4 Vector4::operator []( int idx ) const { return *(&mX + idx); } inline const Vector4 Vector4::operator +( const Vector4 & vec ) const { return Vector4( vec_add( mX, vec.mX ), vec_add( mY, vec.mY ), vec_add( mZ, vec.mZ ), vec_add( mW, vec.mW ) ); } inline const Vector4 Vector4::operator -( const Vector4 & vec ) const { return Vector4( vec_sub( mX, vec.mX ), vec_sub( mY, vec.mY ), vec_sub( mZ, vec.mZ ), vec_sub( mW, vec.mW ) ); } inline const Vector4 Vector4::operator *( vec_float4 scalar ) const { return Vector4( vec_madd( mX, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mY, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mZ, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( mW, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline Vector4 & Vector4::operator +=( const Vector4 & vec ) { *this = *this + vec; return *this; } inline Vector4 & Vector4::operator -=( const Vector4 & vec ) { *this = *this - vec; return *this; } inline Vector4 & Vector4::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Vector4 Vector4::operator /( vec_float4 scalar ) const { return Vector4( divf4( mX, scalar ), divf4( mY, scalar ), divf4( mZ, scalar ), divf4( mW, scalar ) ); } inline Vector4 & Vector4::operator /=( vec_float4 scalar ) { *this = *this / scalar; return *this; } inline const Vector4 Vector4::operator -( ) const { return Vector4( negatef4( mX ), negatef4( mY ), negatef4( mZ ), negatef4( mW ) ); } inline const Vector4 operator *( vec_float4 scalar, const Vector4 & vec ) { return vec * scalar; } inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( vec_madd( vec0.getX(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0.getY(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0.getZ(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec0.getW(), vec1.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( divf4( vec0.getX(), vec1.getX() ), divf4( vec0.getY(), vec1.getY() ), divf4( vec0.getZ(), vec1.getZ() ), divf4( vec0.getW(), vec1.getW() ) ); } inline const Vector4 recipPerElem( const Vector4 & vec ) { return Vector4( divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getX() ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getY() ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getZ() ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vec.getW() ) ); } inline const Vector4 sqrtPerElem( const Vector4 & vec ) { return Vector4( sqrtf4( vec.getX() ), sqrtf4( vec.getY() ), sqrtf4( vec.getZ() ), sqrtf4( vec.getW() ) ); } inline const Vector4 rsqrtPerElem( const Vector4 & vec ) { return Vector4( divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getX() ) ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getY() ) ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getZ() ) ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( vec.getW() ) ) ); } inline const Vector4 absPerElem( const Vector4 & vec ) { return Vector4( fabsf4( vec.getX() ), fabsf4( vec.getY() ), fabsf4( vec.getZ() ), fabsf4( vec.getW() ) ); } inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( copysignf4( vec0.getX(), vec1.getX() ), copysignf4( vec0.getY(), vec1.getY() ), copysignf4( vec0.getZ(), vec1.getZ() ), copysignf4( vec0.getW(), vec1.getW() ) ); } inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( fmaxf4( vec0.getX(), vec1.getX() ), fmaxf4( vec0.getY(), vec1.getY() ), fmaxf4( vec0.getZ(), vec1.getZ() ), fmaxf4( vec0.getW(), vec1.getW() ) ); } inline vec_float4 maxElem( const Vector4 & vec ) { vec_float4 result; result = fmaxf4( vec.getX(), vec.getY() ); result = fmaxf4( vec.getZ(), result ); result = fmaxf4( vec.getW(), result ); return result; } inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( fminf4( vec0.getX(), vec1.getX() ), fminf4( vec0.getY(), vec1.getY() ), fminf4( vec0.getZ(), vec1.getZ() ), fminf4( vec0.getW(), vec1.getW() ) ); } inline vec_float4 minElem( const Vector4 & vec ) { vec_float4 result; result = fminf4( vec.getX(), vec.getY() ); result = fminf4( vec.getZ(), result ); result = fminf4( vec.getW(), result ); return result; } inline vec_float4 sum( const Vector4 & vec ) { vec_float4 result; result = vec_add( vec.getX(), vec.getY() ); result = vec_add( result, vec.getZ() ); result = vec_add( result, vec.getW() ); return result; } inline vec_float4 dot( const Vector4 & vec0, const Vector4 & vec1 ) { vec_float4 result; result = vec_madd( vec0.getX(), vec1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( vec0.getY(), vec1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec0.getZ(), vec1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec0.getW(), vec1.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } inline vec_float4 lengthSqr( const Vector4 & vec ) { vec_float4 result; result = vec_madd( vec.getX(), vec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( vec.getY(), vec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec.getZ(), vec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( vec.getW(), vec.getW(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } inline vec_float4 length( const Vector4 & vec ) { return sqrtf4( lengthSqr( vec ) ); } inline const Vector4 normalize( const Vector4 & vec ) { vec_float4 lenSqr, lenInv; lenSqr = lengthSqr( vec ); lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) ); return Vector4( vec_madd( vec.getX(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec.getY(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec.getZ(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( vec.getW(), lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, vec_uint4 select1 ) { return Vector4( vec_sel( vec0.getX(), vec1.getX(), select1 ), vec_sel( vec0.getY(), vec1.getY(), select1 ), vec_sel( vec0.getZ(), vec1.getZ(), select1 ), vec_sel( vec0.getW(), vec1.getW(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Vector4 & vec ) { Aos::Vector4 vec0, vec1, vec2, vec3; vec.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } inline void print( const Vector4 & vec, const char * name ) { Aos::Vector4 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vec.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } #endif inline Point3::Point3( const Point3 & pnt ) { mX = pnt.mX; mY = pnt.mY; mZ = pnt.mZ; } inline Point3::Point3( vec_float4 _x, vec_float4 _y, vec_float4 _z ) { mX = _x; mY = _y; mZ = _z; } inline Point3::Point3( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); } inline Point3::Point3( vec_float4 scalar ) { mX = scalar; mY = scalar; mZ = scalar; } inline Point3::Point3( Aos::Point3 pnt ) { vec_float4 vec128 = pnt.get128(); mX = vec_splat( vec128, 0 ); mY = vec_splat( vec128, 1 ); mZ = vec_splat( vec128, 2 ); } inline Point3::Point3( Aos::Point3 pnt0, Aos::Point3 pnt1, Aos::Point3 pnt2, Aos::Point3 pnt3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = vec_mergeh( pnt0.get128(), pnt2.get128() ); tmp1 = vec_mergeh( pnt1.get128(), pnt3.get128() ); tmp2 = vec_mergel( pnt0.get128(), pnt2.get128() ); tmp3 = vec_mergel( pnt1.get128(), pnt3.get128() ); mX = vec_mergeh( tmp0, tmp1 ); mY = vec_mergel( tmp0, tmp1 ); mZ = vec_mergeh( tmp2, tmp3 ); } inline const Point3 lerp( vec_float4 t, const Point3 & pnt0, const Point3 & pnt1 ) { return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); } inline void Point3::get4Aos( Aos::Point3 & result0, Aos::Point3 & result1, Aos::Point3 & result2, Aos::Point3 & result3 ) const { vec_float4 tmp0, tmp1; tmp0 = vec_mergeh( mX, mZ ); tmp1 = vec_mergel( mX, mZ ); result0 = Aos::Point3( vec_mergeh( tmp0, mY ) ); result1 = Aos::Point3( vec_perm( tmp0, mY, _VECTORMATH_PERM_ZBWX ) ); result2 = Aos::Point3( vec_perm( tmp1, mY, _VECTORMATH_PERM_XCYX ) ); result3 = Aos::Point3( vec_perm( tmp1, mY, _VECTORMATH_PERM_ZDWX ) ); } inline void loadXYZArray( Point3 & vec, const vec_float4 * threeQuads ) { vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyxy = vec_sld( yzxy, xyzx, 8 ); zxzx = vec_sld( xyzx, zxyz, 8 ); yzyz = vec_sld( zxyz, yzxy, 8 ); vec.setX( vec_perm( xyxy, zxzx, _VECTORMATH_PERM_ZBXD ) ); vec.setY( vec_perm( xyxy, yzyz, _VECTORMATH_PERM_WCYA ) ); vec.setZ( vec_perm( zxzx, yzyz, _VECTORMATH_PERM_XDZB ) ); } inline void storeXYZArray( const Point3 & vec, vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz; xyxy = vec_perm( vec.getX(), vec.getY(), _VECTORMATH_PERM_ZCXA ); zxzx = vec_perm( vec.getZ(), vec.getX(), _VECTORMATH_PERM_XBZD ); yzyz = vec_perm( vec.getY(), vec.getZ(), _VECTORMATH_PERM_WDYB ); xyzx = vec_sld( xyxy, zxzx, 8 ); yzxy = vec_sld( yzyz, xyxy, 8 ); zxyz = vec_sld( zxzx, yzyz, 8 ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } inline void storeHalfFloats( const Point3 & pnt0, const Point3 & pnt1, vec_ushort8 * threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; storeXYZArray( pnt0, xyz0 ); storeXYZArray( pnt1, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } inline Point3 & Point3::operator =( const Point3 & pnt ) { mX = pnt.mX; mY = pnt.mY; mZ = pnt.mZ; return *this; } inline Point3 & Point3::setX( vec_float4 _x ) { mX = _x; return *this; } inline vec_float4 Point3::getX( ) const { return mX; } inline Point3 & Point3::setY( vec_float4 _y ) { mY = _y; return *this; } inline vec_float4 Point3::getY( ) const { return mY; } inline Point3 & Point3::setZ( vec_float4 _z ) { mZ = _z; return *this; } inline vec_float4 Point3::getZ( ) const { return mZ; } inline Point3 & Point3::setElem( int idx, vec_float4 value ) { *(&mX + idx) = value; return *this; } inline vec_float4 Point3::getElem( int idx ) const { return *(&mX + idx); } inline Point3::vec_float4_t & Point3::operator []( int idx ) { return *(&mX + idx); } inline vec_float4 Point3::operator []( int idx ) const { return *(&mX + idx); } inline const Vector3 Point3::operator -( const Point3 & pnt ) const { return Vector3( vec_sub( mX, pnt.mX ), vec_sub( mY, pnt.mY ), vec_sub( mZ, pnt.mZ ) ); } inline const Point3 Point3::operator +( const Vector3 & vec ) const { return Point3( vec_add( mX, vec.getX() ), vec_add( mY, vec.getY() ), vec_add( mZ, vec.getZ() ) ); } inline const Point3 Point3::operator -( const Vector3 & vec ) const { return Point3( vec_sub( mX, vec.getX() ), vec_sub( mY, vec.getY() ), vec_sub( mZ, vec.getZ() ) ); } inline Point3 & Point3::operator +=( const Vector3 & vec ) { *this = *this + vec; return *this; } inline Point3 & Point3::operator -=( const Vector3 & vec ) { *this = *this - vec; return *this; } inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( vec_madd( pnt0.getX(), pnt1.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( pnt0.getY(), pnt1.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( pnt0.getZ(), pnt1.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); } inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( divf4( pnt0.getX(), pnt1.getX() ), divf4( pnt0.getY(), pnt1.getY() ), divf4( pnt0.getZ(), pnt1.getZ() ) ); } inline const Point3 recipPerElem( const Point3 & pnt ) { return Point3( divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt.getX() ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt.getY() ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), pnt.getZ() ) ); } inline const Point3 sqrtPerElem( const Point3 & pnt ) { return Point3( sqrtf4( pnt.getX() ), sqrtf4( pnt.getY() ), sqrtf4( pnt.getZ() ) ); } inline const Point3 rsqrtPerElem( const Point3 & pnt ) { return Point3( divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt.getX() ) ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt.getY() ) ), divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( pnt.getZ() ) ) ); } inline const Point3 absPerElem( const Point3 & pnt ) { return Point3( fabsf4( pnt.getX() ), fabsf4( pnt.getY() ), fabsf4( pnt.getZ() ) ); } inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( copysignf4( pnt0.getX(), pnt1.getX() ), copysignf4( pnt0.getY(), pnt1.getY() ), copysignf4( pnt0.getZ(), pnt1.getZ() ) ); } inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( fmaxf4( pnt0.getX(), pnt1.getX() ), fmaxf4( pnt0.getY(), pnt1.getY() ), fmaxf4( pnt0.getZ(), pnt1.getZ() ) ); } inline vec_float4 maxElem( const Point3 & pnt ) { vec_float4 result; result = fmaxf4( pnt.getX(), pnt.getY() ); result = fmaxf4( pnt.getZ(), result ); return result; } inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( fminf4( pnt0.getX(), pnt1.getX() ), fminf4( pnt0.getY(), pnt1.getY() ), fminf4( pnt0.getZ(), pnt1.getZ() ) ); } inline vec_float4 minElem( const Point3 & pnt ) { vec_float4 result; result = fminf4( pnt.getX(), pnt.getY() ); result = fminf4( pnt.getZ(), result ); return result; } inline vec_float4 sum( const Point3 & pnt ) { vec_float4 result; result = vec_add( pnt.getX(), pnt.getY() ); result = vec_add( result, pnt.getZ() ); return result; } inline const Point3 scale( const Point3 & pnt, vec_float4 scaleVal ) { return mulPerElem( pnt, Point3( scaleVal ) ); } inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) { return mulPerElem( pnt, Point3( scaleVec ) ); } inline vec_float4 projection( const Point3 & pnt, const Vector3 & unitVec ) { vec_float4 result; result = vec_madd( pnt.getX(), unitVec.getX(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ); result = vec_add( result, vec_madd( pnt.getY(), unitVec.getY(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); result = vec_add( result, vec_madd( pnt.getZ(), unitVec.getZ(), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ); return result; } inline vec_float4 distSqrFromOrigin( const Point3 & pnt ) { return lengthSqr( Vector3( pnt ) ); } inline vec_float4 distFromOrigin( const Point3 & pnt ) { return length( Vector3( pnt ) ); } inline vec_float4 distSqr( const Point3 & pnt0, const Point3 & pnt1 ) { return lengthSqr( ( pnt1 - pnt0 ) ); } inline vec_float4 dist( const Point3 & pnt0, const Point3 & pnt1 ) { return length( ( pnt1 - pnt0 ) ); } inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, vec_uint4 select1 ) { return Point3( vec_sel( pnt0.getX(), pnt1.getX(), select1 ), vec_sel( pnt0.getY(), pnt1.getY(), select1 ), vec_sel( pnt0.getZ(), pnt1.getZ(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Point3 & pnt ) { Aos::Point3 vec0, vec1, vec2, vec3; pnt.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } inline void print( const Point3 & pnt, const char * name ) { Aos::Point3 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); pnt.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } #endif } // namespace Soa } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/ppu/cpp/vecidx_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VECIDX_AOS_H #define _VECTORMATH_VECIDX_AOS_H #include "floatInVec.h" namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // VecIdx // Used in setting elements of Vector3, Vector4, Point3, or Quat with the // subscripting operator. // class VecIdx { private: typedef vec_float4 vec_float4_t; vec_float4_t &ref __attribute__ ((aligned(16))); int i __attribute__ ((aligned(16))); public: inline VecIdx( vec_float4_t& vec, int idx ): ref(vec) { i = idx; } // implicitly casts to float unless _VECTORMATH_NO_SCALAR_CAST defined // in which case, implicitly casts to floatInVec, and one must call // getAsFloat to convert to float. // #ifdef _VECTORMATH_NO_SCALAR_CAST inline operator floatInVec() const; inline float getAsFloat() const; #else inline operator float() const; #endif inline float operator =( float scalar ); inline floatInVec operator =( floatInVec scalar ); inline floatInVec operator =( const VecIdx& scalar ); inline floatInVec operator *=( float scalar ); inline floatInVec operator *=( floatInVec scalar ); inline floatInVec operator /=( float scalar ); inline floatInVec operator /=( floatInVec scalar ); inline floatInVec operator +=( float scalar ); inline floatInVec operator +=( floatInVec scalar ); inline floatInVec operator -=( float scalar ); inline floatInVec operator -=( floatInVec scalar ); }; } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/ppu/cpp/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_CPP_PPU_H #define _VECTORMATH_AOS_CPP_PPU_H #include #include #include "vecidx_aos.h" #include "floatInVec.h" #include "boolInVec.h" #ifdef _VECTORMATH_DEBUG #include #endif namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // Forward Declarations // class Vector3; class Vector4; class Point3; class Quat; class Matrix3; class Matrix4; class Transform3; // A 3-D vector in array-of-structures format // class Vector3 { vec_float4 mVec128; public: // Default constructor; does no initialization // inline Vector3( ) { }; // Construct a 3-D vector from x, y, and z elements // inline Vector3( float x, float y, float z ); // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type) // inline Vector3( floatInVec x, floatInVec y, floatInVec z ); // Copy elements from a 3-D point into a 3-D vector // explicit inline Vector3( Point3 pnt ); // Set all elements of a 3-D vector to the same scalar value // explicit inline Vector3( float scalar ); // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type) // explicit inline Vector3( floatInVec scalar ); // Set vector float data in a 3-D vector // explicit inline Vector3( vec_float4 vf4 ); // Get vector float data from a 3-D vector // inline vec_float4 get128( ) const; // Assign one 3-D vector to another // inline Vector3 & operator =( Vector3 vec ); // Set the x element of a 3-D vector // inline Vector3 & setX( float x ); // Set the y element of a 3-D vector // inline Vector3 & setY( float y ); // Set the z element of a 3-D vector // inline Vector3 & setZ( float z ); // Set the x element of a 3-D vector (scalar data contained in vector data type) // inline Vector3 & setX( floatInVec x ); // Set the y element of a 3-D vector (scalar data contained in vector data type) // inline Vector3 & setY( floatInVec y ); // Set the z element of a 3-D vector (scalar data contained in vector data type) // inline Vector3 & setZ( floatInVec z ); // Get the x element of a 3-D vector // inline const floatInVec getX( ) const; // Get the y element of a 3-D vector // inline const floatInVec getY( ) const; // Get the z element of a 3-D vector // inline const floatInVec getZ( ) const; // Set an x, y, or z element of a 3-D vector by index // inline Vector3 & setElem( int idx, float value ); // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type) // inline Vector3 & setElem( int idx, floatInVec value ); // Get an x, y, or z element of a 3-D vector by index // inline const floatInVec getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline const floatInVec operator []( int idx ) const; // Add two 3-D vectors // inline const Vector3 operator +( Vector3 vec ) const; // Subtract a 3-D vector from another 3-D vector // inline const Vector3 operator -( Vector3 vec ) const; // Add a 3-D vector to a 3-D point // inline const Point3 operator +( Point3 pnt ) const; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( float scalar ) const; // Divide a 3-D vector by a scalar // inline const Vector3 operator /( float scalar ) const; // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) // inline const Vector3 operator *( floatInVec scalar ) const; // Divide a 3-D vector by a scalar (scalar data contained in vector data type) // inline const Vector3 operator /( floatInVec scalar ) const; // Perform compound assignment and addition with a 3-D vector // inline Vector3 & operator +=( Vector3 vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Vector3 & operator -=( Vector3 vec ); // Perform compound assignment and multiplication by a scalar // inline Vector3 & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Vector3 & operator /=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Vector3 & operator *=( floatInVec scalar ); // Perform compound assignment and division by a scalar (scalar data contained in vector data type) // inline Vector3 & operator /=( floatInVec scalar ); // Negate all elements of a 3-D vector // inline const Vector3 operator -( ) const; // Construct x axis // static inline const Vector3 xAxis( ); // Construct y axis // static inline const Vector3 yAxis( ); // Construct z axis // static inline const Vector3 zAxis( ); }; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( float scalar, Vector3 vec ); // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) // inline const Vector3 operator *( floatInVec scalar, Vector3 vec ); // Multiply two 3-D vectors per element // inline const Vector3 mulPerElem( Vector3 vec0, Vector3 vec1 ); // Divide two 3-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector3 divPerElem( Vector3 vec0, Vector3 vec1 ); // Compute the reciprocal of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector3 recipPerElem( Vector3 vec ); // Compute the square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector3 sqrtPerElem( Vector3 vec ); // Compute the reciprocal square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector3 rsqrtPerElem( Vector3 vec ); // Compute the absolute value of a 3-D vector per element // inline const Vector3 absPerElem( Vector3 vec ); // Copy sign from one 3-D vector to another, per element // inline const Vector3 copySignPerElem( Vector3 vec0, Vector3 vec1 ); // Maximum of two 3-D vectors per element // inline const Vector3 maxPerElem( Vector3 vec0, Vector3 vec1 ); // Minimum of two 3-D vectors per element // inline const Vector3 minPerElem( Vector3 vec0, Vector3 vec1 ); // Maximum element of a 3-D vector // inline const floatInVec maxElem( Vector3 vec ); // Minimum element of a 3-D vector // inline const floatInVec minElem( Vector3 vec ); // Compute the sum of all elements of a 3-D vector // inline const floatInVec sum( Vector3 vec ); // Compute the dot product of two 3-D vectors // inline const floatInVec dot( Vector3 vec0, Vector3 vec1 ); // Compute the square of the length of a 3-D vector // inline const floatInVec lengthSqr( Vector3 vec ); // Compute the length of a 3-D vector // inline const floatInVec length( Vector3 vec ); // Normalize a 3-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector3 normalize( Vector3 vec ); // Compute cross product of two 3-D vectors // inline const Vector3 cross( Vector3 vec0, Vector3 vec1 ); // Outer product of two 3-D vectors // inline const Matrix3 outer( Vector3 vec0, Vector3 vec1 ); // Pre-multiply a row vector by a 3x3 matrix // NOTE: // Slower than column post-multiply. // inline const Vector3 rowMul( Vector3 vec, const Matrix3 & mat ); // Cross-product matrix of a 3-D vector // inline const Matrix3 crossMatrix( Vector3 vec ); // Create cross-product matrix and multiply // NOTE: // Faster than separately creating a cross-product matrix and multiplying. // inline const Matrix3 crossMatrixMul( Vector3 vec, const Matrix3 & mat ); // Linear interpolation between two 3-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector3 lerp( float t, Vector3 vec0, Vector3 vec1 ); // Linear interpolation between two 3-D vectors (scalar data contained in vector data type) // NOTE: // Does not clamp t between 0 and 1. // inline const Vector3 lerp( floatInVec t, Vector3 vec0, Vector3 vec1 ); // Spherical linear interpolation between two 3-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector3 slerp( float t, Vector3 unitVec0, Vector3 unitVec1 ); // Spherical linear interpolation between two 3-D vectors (scalar data contained in vector data type) // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector3 slerp( floatInVec t, Vector3 unitVec0, Vector3 unitVec1 ); // Conditionally select between two 3-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Vector3 select( Vector3 vec0, Vector3 vec1, bool select1 ); // Conditionally select between two 3-D vectors (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector3 select( Vector3 vec0, Vector3 vec1, boolInVec select1 ); // Store x, y, and z elements of a 3-D vector in the first three words of a quadword. // The value of the fourth word (the word with the highest address) remains unchanged // inline void storeXYZ( Vector3 vec, vec_float4 * quad ); // Load four three-float 3-D vectors, stored in three quadwords // inline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const vec_float4 * threeQuads ); // Store four 3-D vectors in three quadwords // inline void storeXYZArray( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, vec_float4 * threeQuads ); // Store eight 3-D vectors as half-floats // inline void storeHalfFloats( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4, Vector3 vec5, Vector3 vec6, Vector3 vec7, vec_ushort8 * threeQuads ); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Vector3 vec ); // Print a 3-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Vector3 vec, const char * name ); #endif // A 4-D vector in array-of-structures format // class Vector4 { vec_float4 mVec128; public: // Default constructor; does no initialization // inline Vector4( ) { }; // Construct a 4-D vector from x, y, z, and w elements // inline Vector4( float x, float y, float z, float w ); // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type) // inline Vector4( floatInVec x, floatInVec y, floatInVec z, floatInVec w ); // Construct a 4-D vector from a 3-D vector and a scalar // inline Vector4( Vector3 xyz, float w ); // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type) // inline Vector4( Vector3 xyz, floatInVec w ); // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 // explicit inline Vector4( Vector3 vec ); // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 // explicit inline Vector4( Point3 pnt ); // Copy elements from a quaternion into a 4-D vector // explicit inline Vector4( Quat quat ); // Set all elements of a 4-D vector to the same scalar value // explicit inline Vector4( float scalar ); // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type) // explicit inline Vector4( floatInVec scalar ); // Set vector float data in a 4-D vector // explicit inline Vector4( vec_float4 vf4 ); // Get vector float data from a 4-D vector // inline vec_float4 get128( ) const; // Assign one 4-D vector to another // inline Vector4 & operator =( Vector4 vec ); // Set the x, y, and z elements of a 4-D vector // NOTE: // This function does not change the w element. // inline Vector4 & setXYZ( Vector3 vec ); // Get the x, y, and z elements of a 4-D vector // inline const Vector3 getXYZ( ) const; // Set the x element of a 4-D vector // inline Vector4 & setX( float x ); // Set the y element of a 4-D vector // inline Vector4 & setY( float y ); // Set the z element of a 4-D vector // inline Vector4 & setZ( float z ); // Set the w element of a 4-D vector // inline Vector4 & setW( float w ); // Set the x element of a 4-D vector (scalar data contained in vector data type) // inline Vector4 & setX( floatInVec x ); // Set the y element of a 4-D vector (scalar data contained in vector data type) // inline Vector4 & setY( floatInVec y ); // Set the z element of a 4-D vector (scalar data contained in vector data type) // inline Vector4 & setZ( floatInVec z ); // Set the w element of a 4-D vector (scalar data contained in vector data type) // inline Vector4 & setW( floatInVec w ); // Get the x element of a 4-D vector // inline const floatInVec getX( ) const; // Get the y element of a 4-D vector // inline const floatInVec getY( ) const; // Get the z element of a 4-D vector // inline const floatInVec getZ( ) const; // Get the w element of a 4-D vector // inline const floatInVec getW( ) const; // Set an x, y, z, or w element of a 4-D vector by index // inline Vector4 & setElem( int idx, float value ); // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type) // inline Vector4 & setElem( int idx, floatInVec value ); // Get an x, y, z, or w element of a 4-D vector by index // inline const floatInVec getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline const floatInVec operator []( int idx ) const; // Add two 4-D vectors // inline const Vector4 operator +( Vector4 vec ) const; // Subtract a 4-D vector from another 4-D vector // inline const Vector4 operator -( Vector4 vec ) const; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( float scalar ) const; // Divide a 4-D vector by a scalar // inline const Vector4 operator /( float scalar ) const; // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) // inline const Vector4 operator *( floatInVec scalar ) const; // Divide a 4-D vector by a scalar (scalar data contained in vector data type) // inline const Vector4 operator /( floatInVec scalar ) const; // Perform compound assignment and addition with a 4-D vector // inline Vector4 & operator +=( Vector4 vec ); // Perform compound assignment and subtraction by a 4-D vector // inline Vector4 & operator -=( Vector4 vec ); // Perform compound assignment and multiplication by a scalar // inline Vector4 & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Vector4 & operator /=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Vector4 & operator *=( floatInVec scalar ); // Perform compound assignment and division by a scalar (scalar data contained in vector data type) // inline Vector4 & operator /=( floatInVec scalar ); // Negate all elements of a 4-D vector // inline const Vector4 operator -( ) const; // Construct x axis // static inline const Vector4 xAxis( ); // Construct y axis // static inline const Vector4 yAxis( ); // Construct z axis // static inline const Vector4 zAxis( ); // Construct w axis // static inline const Vector4 wAxis( ); }; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( float scalar, Vector4 vec ); // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) // inline const Vector4 operator *( floatInVec scalar, Vector4 vec ); // Multiply two 4-D vectors per element // inline const Vector4 mulPerElem( Vector4 vec0, Vector4 vec1 ); // Divide two 4-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector4 divPerElem( Vector4 vec0, Vector4 vec1 ); // Compute the reciprocal of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector4 recipPerElem( Vector4 vec ); // Compute the square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector4 sqrtPerElem( Vector4 vec ); // Compute the reciprocal square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector4 rsqrtPerElem( Vector4 vec ); // Compute the absolute value of a 4-D vector per element // inline const Vector4 absPerElem( Vector4 vec ); // Copy sign from one 4-D vector to another, per element // inline const Vector4 copySignPerElem( Vector4 vec0, Vector4 vec1 ); // Maximum of two 4-D vectors per element // inline const Vector4 maxPerElem( Vector4 vec0, Vector4 vec1 ); // Minimum of two 4-D vectors per element // inline const Vector4 minPerElem( Vector4 vec0, Vector4 vec1 ); // Maximum element of a 4-D vector // inline const floatInVec maxElem( Vector4 vec ); // Minimum element of a 4-D vector // inline const floatInVec minElem( Vector4 vec ); // Compute the sum of all elements of a 4-D vector // inline const floatInVec sum( Vector4 vec ); // Compute the dot product of two 4-D vectors // inline const floatInVec dot( Vector4 vec0, Vector4 vec1 ); // Compute the square of the length of a 4-D vector // inline const floatInVec lengthSqr( Vector4 vec ); // Compute the length of a 4-D vector // inline const floatInVec length( Vector4 vec ); // Normalize a 4-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector4 normalize( Vector4 vec ); // Outer product of two 4-D vectors // inline const Matrix4 outer( Vector4 vec0, Vector4 vec1 ); // Linear interpolation between two 4-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector4 lerp( float t, Vector4 vec0, Vector4 vec1 ); // Linear interpolation between two 4-D vectors (scalar data contained in vector data type) // NOTE: // Does not clamp t between 0 and 1. // inline const Vector4 lerp( floatInVec t, Vector4 vec0, Vector4 vec1 ); // Spherical linear interpolation between two 4-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector4 slerp( float t, Vector4 unitVec0, Vector4 unitVec1 ); // Spherical linear interpolation between two 4-D vectors (scalar data contained in vector data type) // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector4 slerp( floatInVec t, Vector4 unitVec0, Vector4 unitVec1 ); // Conditionally select between two 4-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Vector4 select( Vector4 vec0, Vector4 vec1, bool select1 ); // Conditionally select between two 4-D vectors (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector4 select( Vector4 vec0, Vector4 vec1, boolInVec select1 ); // Store four 4-D vectors as half-floats // inline void storeHalfFloats( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3, vec_ushort8 * twoQuads ); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Vector4 vec ); // Print a 4-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Vector4 vec, const char * name ); #endif // A 3-D point in array-of-structures format // class Point3 { vec_float4 mVec128; public: // Default constructor; does no initialization // inline Point3( ) { }; // Construct a 3-D point from x, y, and z elements // inline Point3( float x, float y, float z ); // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type) // inline Point3( floatInVec x, floatInVec y, floatInVec z ); // Copy elements from a 3-D vector into a 3-D point // explicit inline Point3( Vector3 vec ); // Set all elements of a 3-D point to the same scalar value // explicit inline Point3( float scalar ); // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type) // explicit inline Point3( floatInVec scalar ); // Set vector float data in a 3-D point // explicit inline Point3( vec_float4 vf4 ); // Get vector float data from a 3-D point // inline vec_float4 get128( ) const; // Assign one 3-D point to another // inline Point3 & operator =( Point3 pnt ); // Set the x element of a 3-D point // inline Point3 & setX( float x ); // Set the y element of a 3-D point // inline Point3 & setY( float y ); // Set the z element of a 3-D point // inline Point3 & setZ( float z ); // Set the x element of a 3-D point (scalar data contained in vector data type) // inline Point3 & setX( floatInVec x ); // Set the y element of a 3-D point (scalar data contained in vector data type) // inline Point3 & setY( floatInVec y ); // Set the z element of a 3-D point (scalar data contained in vector data type) // inline Point3 & setZ( floatInVec z ); // Get the x element of a 3-D point // inline const floatInVec getX( ) const; // Get the y element of a 3-D point // inline const floatInVec getY( ) const; // Get the z element of a 3-D point // inline const floatInVec getZ( ) const; // Set an x, y, or z element of a 3-D point by index // inline Point3 & setElem( int idx, float value ); // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type) // inline Point3 & setElem( int idx, floatInVec value ); // Get an x, y, or z element of a 3-D point by index // inline const floatInVec getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline const floatInVec operator []( int idx ) const; // Subtract a 3-D point from another 3-D point // inline const Vector3 operator -( Point3 pnt ) const; // Add a 3-D point to a 3-D vector // inline const Point3 operator +( Vector3 vec ) const; // Subtract a 3-D vector from a 3-D point // inline const Point3 operator -( Vector3 vec ) const; // Perform compound assignment and addition with a 3-D vector // inline Point3 & operator +=( Vector3 vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Point3 & operator -=( Vector3 vec ); }; // Multiply two 3-D points per element // inline const Point3 mulPerElem( Point3 pnt0, Point3 pnt1 ); // Divide two 3-D points per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Point3 divPerElem( Point3 pnt0, Point3 pnt1 ); // Compute the reciprocal of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Point3 recipPerElem( Point3 pnt ); // Compute the square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Point3 sqrtPerElem( Point3 pnt ); // Compute the reciprocal square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Point3 rsqrtPerElem( Point3 pnt ); // Compute the absolute value of a 3-D point per element // inline const Point3 absPerElem( Point3 pnt ); // Copy sign from one 3-D point to another, per element // inline const Point3 copySignPerElem( Point3 pnt0, Point3 pnt1 ); // Maximum of two 3-D points per element // inline const Point3 maxPerElem( Point3 pnt0, Point3 pnt1 ); // Minimum of two 3-D points per element // inline const Point3 minPerElem( Point3 pnt0, Point3 pnt1 ); // Maximum element of a 3-D point // inline const floatInVec maxElem( Point3 pnt ); // Minimum element of a 3-D point // inline const floatInVec minElem( Point3 pnt ); // Compute the sum of all elements of a 3-D point // inline const floatInVec sum( Point3 pnt ); // Apply uniform scale to a 3-D point // inline const Point3 scale( Point3 pnt, float scaleVal ); // Apply uniform scale to a 3-D point (scalar data contained in vector data type) // inline const Point3 scale( Point3 pnt, floatInVec scaleVal ); // Apply non-uniform scale to a 3-D point // inline const Point3 scale( Point3 pnt, Vector3 scaleVec ); // Scalar projection of a 3-D point on a unit-length 3-D vector // inline const floatInVec projection( Point3 pnt, Vector3 unitVec ); // Compute the square of the distance of a 3-D point from the coordinate-system origin // inline const floatInVec distSqrFromOrigin( Point3 pnt ); // Compute the distance of a 3-D point from the coordinate-system origin // inline const floatInVec distFromOrigin( Point3 pnt ); // Compute the square of the distance between two 3-D points // inline const floatInVec distSqr( Point3 pnt0, Point3 pnt1 ); // Compute the distance between two 3-D points // inline const floatInVec dist( Point3 pnt0, Point3 pnt1 ); // Linear interpolation between two 3-D points // NOTE: // Does not clamp t between 0 and 1. // inline const Point3 lerp( float t, Point3 pnt0, Point3 pnt1 ); // Linear interpolation between two 3-D points (scalar data contained in vector data type) // NOTE: // Does not clamp t between 0 and 1. // inline const Point3 lerp( floatInVec t, Point3 pnt0, Point3 pnt1 ); // Conditionally select between two 3-D points // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Point3 select( Point3 pnt0, Point3 pnt1, bool select1 ); // Conditionally select between two 3-D points (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Point3 select( Point3 pnt0, Point3 pnt1, boolInVec select1 ); // Store x, y, and z elements of a 3-D point in the first three words of a quadword. // The value of the fourth word (the word with the highest address) remains unchanged // inline void storeXYZ( Point3 pnt, vec_float4 * quad ); // Load four three-float 3-D points, stored in three quadwords // inline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const vec_float4 * threeQuads ); // Store four 3-D points in three quadwords // inline void storeXYZArray( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, vec_float4 * threeQuads ); // Store eight 3-D points as half-floats // inline void storeHalfFloats( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, Point3 pnt4, Point3 pnt5, Point3 pnt6, Point3 pnt7, vec_ushort8 * threeQuads ); #ifdef _VECTORMATH_DEBUG // Print a 3-D point // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Point3 pnt ); // Print a 3-D point and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Point3 pnt, const char * name ); #endif // A quaternion in array-of-structures format // class Quat { vec_float4 mVec128; public: // Default constructor; does no initialization // inline Quat( ) { }; // Construct a quaternion from x, y, z, and w elements // inline Quat( float x, float y, float z, float w ); // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type) // inline Quat( floatInVec x, floatInVec y, floatInVec z, floatInVec w ); // Construct a quaternion from a 3-D vector and a scalar // inline Quat( Vector3 xyz, float w ); // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type) // inline Quat( Vector3 xyz, floatInVec w ); // Copy elements from a 4-D vector into a quaternion // explicit inline Quat( Vector4 vec ); // Convert a rotation matrix to a unit-length quaternion // explicit inline Quat( const Matrix3 & rotMat ); // Set all elements of a quaternion to the same scalar value // explicit inline Quat( float scalar ); // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type) // explicit inline Quat( floatInVec scalar ); // Set vector float data in a quaternion // explicit inline Quat( vec_float4 vf4 ); // Get vector float data from a quaternion // inline vec_float4 get128( ) const; // Assign one quaternion to another // inline Quat & operator =( Quat quat ); // Set the x, y, and z elements of a quaternion // NOTE: // This function does not change the w element. // inline Quat & setXYZ( Vector3 vec ); // Get the x, y, and z elements of a quaternion // inline const Vector3 getXYZ( ) const; // Set the x element of a quaternion // inline Quat & setX( float x ); // Set the y element of a quaternion // inline Quat & setY( float y ); // Set the z element of a quaternion // inline Quat & setZ( float z ); // Set the w element of a quaternion // inline Quat & setW( float w ); // Set the x element of a quaternion (scalar data contained in vector data type) // inline Quat & setX( floatInVec x ); // Set the y element of a quaternion (scalar data contained in vector data type) // inline Quat & setY( floatInVec y ); // Set the z element of a quaternion (scalar data contained in vector data type) // inline Quat & setZ( floatInVec z ); // Set the w element of a quaternion (scalar data contained in vector data type) // inline Quat & setW( floatInVec w ); // Get the x element of a quaternion // inline const floatInVec getX( ) const; // Get the y element of a quaternion // inline const floatInVec getY( ) const; // Get the z element of a quaternion // inline const floatInVec getZ( ) const; // Get the w element of a quaternion // inline const floatInVec getW( ) const; // Set an x, y, z, or w element of a quaternion by index // inline Quat & setElem( int idx, float value ); // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type) // inline Quat & setElem( int idx, floatInVec value ); // Get an x, y, z, or w element of a quaternion by index // inline const floatInVec getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline const floatInVec operator []( int idx ) const; // Add two quaternions // inline const Quat operator +( Quat quat ) const; // Subtract a quaternion from another quaternion // inline const Quat operator -( Quat quat ) const; // Multiply two quaternions // inline const Quat operator *( Quat quat ) const; // Multiply a quaternion by a scalar // inline const Quat operator *( float scalar ) const; // Divide a quaternion by a scalar // inline const Quat operator /( float scalar ) const; // Multiply a quaternion by a scalar (scalar data contained in vector data type) // inline const Quat operator *( floatInVec scalar ) const; // Divide a quaternion by a scalar (scalar data contained in vector data type) // inline const Quat operator /( floatInVec scalar ) const; // Perform compound assignment and addition with a quaternion // inline Quat & operator +=( Quat quat ); // Perform compound assignment and subtraction by a quaternion // inline Quat & operator -=( Quat quat ); // Perform compound assignment and multiplication by a quaternion // inline Quat & operator *=( Quat quat ); // Perform compound assignment and multiplication by a scalar // inline Quat & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Quat & operator /=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Quat & operator *=( floatInVec scalar ); // Perform compound assignment and division by a scalar (scalar data contained in vector data type) // inline Quat & operator /=( floatInVec scalar ); // Negate all elements of a quaternion // inline const Quat operator -( ) const; // Construct an identity quaternion // static inline const Quat identity( ); // Construct a quaternion to rotate between two unit-length 3-D vectors // NOTE: // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. // static inline const Quat rotation( Vector3 unitVec0, Vector3 unitVec1 ); // Construct a quaternion to rotate around a unit-length 3-D vector // static inline const Quat rotation( float radians, Vector3 unitVec ); // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type) // static inline const Quat rotation( floatInVec radians, Vector3 unitVec ); // Construct a quaternion to rotate around the x axis // static inline const Quat rotationX( float radians ); // Construct a quaternion to rotate around the y axis // static inline const Quat rotationY( float radians ); // Construct a quaternion to rotate around the z axis // static inline const Quat rotationZ( float radians ); // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type) // static inline const Quat rotationX( floatInVec radians ); // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type) // static inline const Quat rotationY( floatInVec radians ); // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type) // static inline const Quat rotationZ( floatInVec radians ); }; // Multiply a quaternion by a scalar // inline const Quat operator *( float scalar, Quat quat ); // Multiply a quaternion by a scalar (scalar data contained in vector data type) // inline const Quat operator *( floatInVec scalar, Quat quat ); // Compute the conjugate of a quaternion // inline const Quat conj( Quat quat ); // Use a unit-length quaternion to rotate a 3-D vector // inline const Vector3 rotate( Quat unitQuat, Vector3 vec ); // Compute the dot product of two quaternions // inline const floatInVec dot( Quat quat0, Quat quat1 ); // Compute the norm of a quaternion // inline const floatInVec norm( Quat quat ); // Compute the length of a quaternion // inline const floatInVec length( Quat quat ); // Normalize a quaternion // NOTE: // The result is unpredictable when all elements of quat are at or near zero. // inline const Quat normalize( Quat quat ); // Linear interpolation between two quaternions // NOTE: // Does not clamp t between 0 and 1. // inline const Quat lerp( float t, Quat quat0, Quat quat1 ); // Linear interpolation between two quaternions (scalar data contained in vector data type) // NOTE: // Does not clamp t between 0 and 1. // inline const Quat lerp( floatInVec t, Quat quat0, Quat quat1 ); // Spherical linear interpolation between two quaternions // NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. // inline const Quat slerp( float t, Quat unitQuat0, Quat unitQuat1 ); // Spherical linear interpolation between two quaternions (scalar data contained in vector data type) // NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. // inline const Quat slerp( floatInVec t, Quat unitQuat0, Quat unitQuat1 ); // Spherical quadrangle interpolation // inline const Quat squad( float t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 ); // Spherical quadrangle interpolation (scalar data contained in vector data type) // inline const Quat squad( floatInVec t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 ); // Conditionally select between two quaternions // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Quat select( Quat quat0, Quat quat1, bool select1 ); // Conditionally select between two quaternions (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Quat select( Quat quat0, Quat quat1, boolInVec select1 ); #ifdef _VECTORMATH_DEBUG // Print a quaternion // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Quat quat ); // Print a quaternion and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Quat quat, const char * name ); #endif // A 3x3 matrix in array-of-structures format // class Matrix3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; public: // Default constructor; does no initialization // inline Matrix3( ) { }; // Copy a 3x3 matrix // inline Matrix3( const Matrix3 & mat ); // Construct a 3x3 matrix containing the specified columns // inline Matrix3( Vector3 col0, Vector3 col1, Vector3 col2 ); // Construct a 3x3 rotation matrix from a unit-length quaternion // explicit inline Matrix3( Quat unitQuat ); // Set all elements of a 3x3 matrix to the same scalar value // explicit inline Matrix3( float scalar ); // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type) // explicit inline Matrix3( floatInVec scalar ); // Assign one 3x3 matrix to another // inline Matrix3 & operator =( const Matrix3 & mat ); // Set column 0 of a 3x3 matrix // inline Matrix3 & setCol0( Vector3 col0 ); // Set column 1 of a 3x3 matrix // inline Matrix3 & setCol1( Vector3 col1 ); // Set column 2 of a 3x3 matrix // inline Matrix3 & setCol2( Vector3 col2 ); // Get column 0 of a 3x3 matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x3 matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x3 matrix // inline const Vector3 getCol2( ) const; // Set the column of a 3x3 matrix referred to by the specified index // inline Matrix3 & setCol( int col, Vector3 vec ); // Set the row of a 3x3 matrix referred to by the specified index // inline Matrix3 & setRow( int row, Vector3 vec ); // Get the column of a 3x3 matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x3 matrix referred to by the specified index // inline const Vector3 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x3 matrix referred to by column and row indices // inline Matrix3 & setElem( int col, int row, float val ); // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type) // inline Matrix3 & setElem( int col, int row, floatInVec val ); // Get the element of a 3x3 matrix referred to by column and row indices // inline const floatInVec getElem( int col, int row ) const; // Add two 3x3 matrices // inline const Matrix3 operator +( const Matrix3 & mat ) const; // Subtract a 3x3 matrix from another 3x3 matrix // inline const Matrix3 operator -( const Matrix3 & mat ) const; // Negate all elements of a 3x3 matrix // inline const Matrix3 operator -( ) const; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( float scalar ) const; // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) // inline const Matrix3 operator *( floatInVec scalar ) const; // Multiply a 3x3 matrix by a 3-D vector // inline const Vector3 operator *( Vector3 vec ) const; // Multiply two 3x3 matrices // inline const Matrix3 operator *( const Matrix3 & mat ) const; // Perform compound assignment and addition with a 3x3 matrix // inline Matrix3 & operator +=( const Matrix3 & mat ); // Perform compound assignment and subtraction by a 3x3 matrix // inline Matrix3 & operator -=( const Matrix3 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix3 & operator *=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Matrix3 & operator *=( floatInVec scalar ); // Perform compound assignment and multiplication by a 3x3 matrix // inline Matrix3 & operator *=( const Matrix3 & mat ); // Construct an identity 3x3 matrix // static inline const Matrix3 identity( ); // Construct a 3x3 matrix to rotate around the x axis // static inline const Matrix3 rotationX( float radians ); // Construct a 3x3 matrix to rotate around the y axis // static inline const Matrix3 rotationY( float radians ); // Construct a 3x3 matrix to rotate around the z axis // static inline const Matrix3 rotationZ( float radians ); // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type) // static inline const Matrix3 rotationX( floatInVec radians ); // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type) // static inline const Matrix3 rotationY( floatInVec radians ); // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type) // static inline const Matrix3 rotationZ( floatInVec radians ); // Construct a 3x3 matrix to rotate around the x, y, and z axes // static inline const Matrix3 rotationZYX( Vector3 radiansXYZ ); // Construct a 3x3 matrix to rotate around a unit-length 3-D vector // static inline const Matrix3 rotation( float radians, Vector3 unitVec ); // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) // static inline const Matrix3 rotation( floatInVec radians, Vector3 unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix3 rotation( Quat unitQuat ); // Construct a 3x3 matrix to perform scaling // static inline const Matrix3 scale( Vector3 scaleVec ); }; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) // inline const Matrix3 operator *( floatInVec scalar, const Matrix3 & mat ); // Append (post-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 appendScale( const Matrix3 & mat, Vector3 scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 prependScale( Vector3 scaleVec, const Matrix3 & mat ); // Multiply two 3x3 matrices per element // inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); // Compute the absolute value of a 3x3 matrix per element // inline const Matrix3 absPerElem( const Matrix3 & mat ); // Transpose of a 3x3 matrix // inline const Matrix3 transpose( const Matrix3 & mat ); // Compute the inverse of a 3x3 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix3 inverse( const Matrix3 & mat ); // Determinant of a 3x3 matrix // inline const floatInVec determinant( const Matrix3 & mat ); // Conditionally select between two 3x3 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); // Conditionally select between two 3x3 matrices (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, boolInVec select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat ); // Print a 3x3 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat, const char * name ); #endif // A 4x4 matrix in array-of-structures format // class Matrix4 { Vector4 mCol0; Vector4 mCol1; Vector4 mCol2; Vector4 mCol3; public: // Default constructor; does no initialization // inline Matrix4( ) { }; // Copy a 4x4 matrix // inline Matrix4( const Matrix4 & mat ); // Construct a 4x4 matrix containing the specified columns // inline Matrix4( Vector4 col0, Vector4 col1, Vector4 col2, Vector4 col3 ); // Construct a 4x4 matrix from a 3x4 transformation matrix // explicit inline Matrix4( const Transform3 & mat ); // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector // inline Matrix4( const Matrix3 & mat, Vector3 translateVec ); // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector // inline Matrix4( Quat unitQuat, Vector3 translateVec ); // Set all elements of a 4x4 matrix to the same scalar value // explicit inline Matrix4( float scalar ); // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type) // explicit inline Matrix4( floatInVec scalar ); // Assign one 4x4 matrix to another // inline Matrix4 & operator =( const Matrix4 & mat ); // Set the upper-left 3x3 submatrix // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 4x4 matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setTranslation( Vector3 translateVec ); // Get the translation component of a 4x4 matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 4x4 matrix // inline Matrix4 & setCol0( Vector4 col0 ); // Set column 1 of a 4x4 matrix // inline Matrix4 & setCol1( Vector4 col1 ); // Set column 2 of a 4x4 matrix // inline Matrix4 & setCol2( Vector4 col2 ); // Set column 3 of a 4x4 matrix // inline Matrix4 & setCol3( Vector4 col3 ); // Get column 0 of a 4x4 matrix // inline const Vector4 getCol0( ) const; // Get column 1 of a 4x4 matrix // inline const Vector4 getCol1( ) const; // Get column 2 of a 4x4 matrix // inline const Vector4 getCol2( ) const; // Get column 3 of a 4x4 matrix // inline const Vector4 getCol3( ) const; // Set the column of a 4x4 matrix referred to by the specified index // inline Matrix4 & setCol( int col, Vector4 vec ); // Set the row of a 4x4 matrix referred to by the specified index // inline Matrix4 & setRow( int row, Vector4 vec ); // Get the column of a 4x4 matrix referred to by the specified index // inline const Vector4 getCol( int col ) const; // Get the row of a 4x4 matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector4 & operator []( int col ); // Subscripting operator to get a column // inline const Vector4 operator []( int col ) const; // Set the element of a 4x4 matrix referred to by column and row indices // inline Matrix4 & setElem( int col, int row, float val ); // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type) // inline Matrix4 & setElem( int col, int row, floatInVec val ); // Get the element of a 4x4 matrix referred to by column and row indices // inline const floatInVec getElem( int col, int row ) const; // Add two 4x4 matrices // inline const Matrix4 operator +( const Matrix4 & mat ) const; // Subtract a 4x4 matrix from another 4x4 matrix // inline const Matrix4 operator -( const Matrix4 & mat ) const; // Negate all elements of a 4x4 matrix // inline const Matrix4 operator -( ) const; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( float scalar ) const; // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) // inline const Matrix4 operator *( floatInVec scalar ) const; // Multiply a 4x4 matrix by a 4-D vector // inline const Vector4 operator *( Vector4 vec ) const; // Multiply a 4x4 matrix by a 3-D vector // inline const Vector4 operator *( Vector3 vec ) const; // Multiply a 4x4 matrix by a 3-D point // inline const Vector4 operator *( Point3 pnt ) const; // Multiply two 4x4 matrices // inline const Matrix4 operator *( const Matrix4 & mat ) const; // Multiply a 4x4 matrix by a 3x4 transformation matrix // inline const Matrix4 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and addition with a 4x4 matrix // inline Matrix4 & operator +=( const Matrix4 & mat ); // Perform compound assignment and subtraction by a 4x4 matrix // inline Matrix4 & operator -=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix4 & operator *=( float scalar ); // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) // inline Matrix4 & operator *=( floatInVec scalar ); // Perform compound assignment and multiplication by a 4x4 matrix // inline Matrix4 & operator *=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Matrix4 & operator *=( const Transform3 & tfrm ); // Construct an identity 4x4 matrix // static inline const Matrix4 identity( ); // Construct a 4x4 matrix to rotate around the x axis // static inline const Matrix4 rotationX( float radians ); // Construct a 4x4 matrix to rotate around the y axis // static inline const Matrix4 rotationY( float radians ); // Construct a 4x4 matrix to rotate around the z axis // static inline const Matrix4 rotationZ( float radians ); // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type) // static inline const Matrix4 rotationX( floatInVec radians ); // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type) // static inline const Matrix4 rotationY( floatInVec radians ); // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type) // static inline const Matrix4 rotationZ( floatInVec radians ); // Construct a 4x4 matrix to rotate around the x, y, and z axes // static inline const Matrix4 rotationZYX( Vector3 radiansXYZ ); // Construct a 4x4 matrix to rotate around a unit-length 3-D vector // static inline const Matrix4 rotation( float radians, Vector3 unitVec ); // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) // static inline const Matrix4 rotation( floatInVec radians, Vector3 unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix4 rotation( Quat unitQuat ); // Construct a 4x4 matrix to perform scaling // static inline const Matrix4 scale( Vector3 scaleVec ); // Construct a 4x4 matrix to perform translation // static inline const Matrix4 translation( Vector3 translateVec ); // Construct viewing matrix based on eye position, position looked at, and up direction // static inline const Matrix4 lookAt( Point3 eyePos, Point3 lookAtPos, Vector3 upVec ); // Construct a perspective projection matrix // static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); // Construct a perspective projection matrix based on frustum // static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); // Construct an orthographic projection matrix // static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); }; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) // inline const Matrix4 operator *( floatInVec scalar, const Matrix4 & mat ); // Append (post-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 appendScale( const Matrix4 & mat, Vector3 scaleVec ); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 prependScale( Vector3 scaleVec, const Matrix4 & mat ); // Multiply two 4x4 matrices per element // inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); // Compute the absolute value of a 4x4 matrix per element // inline const Matrix4 absPerElem( const Matrix4 & mat ); // Transpose of a 4x4 matrix // inline const Matrix4 transpose( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix4 inverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix // NOTE: // 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. // inline const Matrix4 affineInverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. // inline const Matrix4 orthoInverse( const Matrix4 & mat ); // Determinant of a 4x4 matrix // inline const floatInVec determinant( const Matrix4 & mat ); // Conditionally select between two 4x4 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); // Conditionally select between two 4x4 matrices (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, boolInVec select1 ); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat ); // Print a 4x4 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat, const char * name ); #endif // A 3x4 transformation matrix in array-of-structures format // class Transform3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; Vector3 mCol3; public: // Default constructor; does no initialization // inline Transform3( ) { }; // Copy a 3x4 transformation matrix // inline Transform3( const Transform3 & tfrm ); // Construct a 3x4 transformation matrix containing the specified columns // inline Transform3( Vector3 col0, Vector3 col1, Vector3 col2, Vector3 col3 ); // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector // inline Transform3( const Matrix3 & tfrm, Vector3 translateVec ); // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector // inline Transform3( Quat unitQuat, Vector3 translateVec ); // Set all elements of a 3x4 transformation matrix to the same scalar value // explicit inline Transform3( float scalar ); // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type) // explicit inline Transform3( floatInVec scalar ); // Assign one 3x4 transformation matrix to another // inline Transform3 & operator =( const Transform3 & tfrm ); // Set the upper-left 3x3 submatrix // inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // inline Transform3 & setTranslation( Vector3 translateVec ); // Get the translation component of a 3x4 transformation matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 3x4 transformation matrix // inline Transform3 & setCol0( Vector3 col0 ); // Set column 1 of a 3x4 transformation matrix // inline Transform3 & setCol1( Vector3 col1 ); // Set column 2 of a 3x4 transformation matrix // inline Transform3 & setCol2( Vector3 col2 ); // Set column 3 of a 3x4 transformation matrix // inline Transform3 & setCol3( Vector3 col3 ); // Get column 0 of a 3x4 transformation matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x4 transformation matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x4 transformation matrix // inline const Vector3 getCol2( ) const; // Get column 3 of a 3x4 transformation matrix // inline const Vector3 getCol3( ) const; // Set the column of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setCol( int col, Vector3 vec ); // Set the row of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setRow( int row, Vector4 vec ); // Get the column of a 3x4 transformation matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x4 transformation matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x4 transformation matrix referred to by column and row indices // inline Transform3 & setElem( int col, int row, float val ); // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type) // inline Transform3 & setElem( int col, int row, floatInVec val ); // Get the element of a 3x4 transformation matrix referred to by column and row indices // inline const floatInVec getElem( int col, int row ) const; // Multiply a 3x4 transformation matrix by a 3-D vector // inline const Vector3 operator *( Vector3 vec ) const; // Multiply a 3x4 transformation matrix by a 3-D point // inline const Point3 operator *( Point3 pnt ) const; // Multiply two 3x4 transformation matrices // inline const Transform3 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Transform3 & operator *=( const Transform3 & tfrm ); // Construct an identity 3x4 transformation matrix // static inline const Transform3 identity( ); // Construct a 3x4 transformation matrix to rotate around the x axis // static inline const Transform3 rotationX( float radians ); // Construct a 3x4 transformation matrix to rotate around the y axis // static inline const Transform3 rotationY( float radians ); // Construct a 3x4 transformation matrix to rotate around the z axis // static inline const Transform3 rotationZ( float radians ); // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type) // static inline const Transform3 rotationX( floatInVec radians ); // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type) // static inline const Transform3 rotationY( floatInVec radians ); // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type) // static inline const Transform3 rotationZ( floatInVec radians ); // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes // static inline const Transform3 rotationZYX( Vector3 radiansXYZ ); // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector // static inline const Transform3 rotation( float radians, Vector3 unitVec ); // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) // static inline const Transform3 rotation( floatInVec radians, Vector3 unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Transform3 rotation( Quat unitQuat ); // Construct a 3x4 transformation matrix to perform scaling // static inline const Transform3 scale( Vector3 scaleVec ); // Construct a 3x4 transformation matrix to perform translation // static inline const Transform3 translation( Vector3 translateVec ); }; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 appendScale( const Transform3 & tfrm, Vector3 scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 prependScale( Vector3 scaleVec, const Transform3 & tfrm ); // Multiply two 3x4 transformation matrices per element // inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); // Compute the absolute value of a 3x4 transformation matrix per element // inline const Transform3 absPerElem( const Transform3 & tfrm ); // Inverse of a 3x4 transformation matrix // NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. // inline const Transform3 inverse( const Transform3 & tfrm ); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. // inline const Transform3 orthoInverse( const Transform3 & tfrm ); // Conditionally select between two 3x4 transformation matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. // inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); // Conditionally select between two 3x4 transformation matrices (scalar data contained in vector data type) // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, boolInVec select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm ); // Print a 3x4 transformation matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm, const char * name ); #endif } // namespace Aos } // namespace Vectormath #include "vec_aos.h" #include "quat_aos.h" #include "mat_aos.h" #endif ================================================ FILE: samples/vectormath/ppu/cpp/vectormath_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_CPP_PPU_H #define _VECTORMATH_SOA_CPP_PPU_H #include #include #include "vectormath_aos.h" #ifdef _VECTORMATH_DEBUG #include #endif namespace Vectormath { namespace Soa { //----------------------------------------------------------------------------- // Forward Declarations // class Vector3; class Vector4; class Point3; class Quat; class Matrix3; class Matrix4; class Transform3; // A set of four 3-D vectors in structure-of-arrays format // class Vector3 { typedef vec_float4 vec_float4_t; vec_float4 mX; vec_float4 mY; vec_float4 mZ; public: // Default constructor; does no initialization // inline Vector3( ) { }; // Copy a 3-D vector // inline Vector3( const Vector3 & vec ); // Construct a 3-D vector from x, y, and z elements // inline Vector3( vec_float4 x, vec_float4 y, vec_float4 z ); // Copy elements from a 3-D point into a 3-D vector // explicit inline Vector3( const Point3 & pnt ); // Set all elements of a 3-D vector to the same scalar value // explicit inline Vector3( vec_float4 scalar ); // Replicate an AoS 3-D vector // inline Vector3( Aos::Vector3 vec ); // Insert four AoS 3-D vectors // inline Vector3( Aos::Vector3 vec0, Aos::Vector3 vec1, Aos::Vector3 vec2, Aos::Vector3 vec3 ); // Extract four AoS 3-D vectors // inline void get4Aos( Aos::Vector3 & result0, Aos::Vector3 & result1, Aos::Vector3 & result2, Aos::Vector3 & result3 ) const; // Assign one 3-D vector to another // inline Vector3 & operator =( const Vector3 & vec ); // Set the x element of a 3-D vector // inline Vector3 & setX( vec_float4 x ); // Set the y element of a 3-D vector // inline Vector3 & setY( vec_float4 y ); // Set the z element of a 3-D vector // inline Vector3 & setZ( vec_float4 z ); // Get the x element of a 3-D vector // inline vec_float4 getX( ) const; // Get the y element of a 3-D vector // inline vec_float4 getY( ) const; // Get the z element of a 3-D vector // inline vec_float4 getZ( ) const; // Set an x, y, or z element of a 3-D vector by index // inline Vector3 & setElem( int idx, vec_float4 value ); // Get an x, y, or z element of a 3-D vector by index // inline vec_float4 getElem( int idx ) const; // Subscripting operator to set or get an element // inline vec_float4_t & operator []( int idx ); // Subscripting operator to get an element // inline vec_float4 operator []( int idx ) const; // Add two 3-D vectors // inline const Vector3 operator +( const Vector3 & vec ) const; // Subtract a 3-D vector from another 3-D vector // inline const Vector3 operator -( const Vector3 & vec ) const; // Add a 3-D vector to a 3-D point // inline const Point3 operator +( const Point3 & pnt ) const; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( vec_float4 scalar ) const; // Divide a 3-D vector by a scalar // inline const Vector3 operator /( vec_float4 scalar ) const; // Perform compound assignment and addition with a 3-D vector // inline Vector3 & operator +=( const Vector3 & vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Vector3 & operator -=( const Vector3 & vec ); // Perform compound assignment and multiplication by a scalar // inline Vector3 & operator *=( vec_float4 scalar ); // Perform compound assignment and division by a scalar // inline Vector3 & operator /=( vec_float4 scalar ); // Negate all elements of a 3-D vector // inline const Vector3 operator -( ) const; // Construct x axis // static inline const Vector3 xAxis( ); // Construct y axis // static inline const Vector3 yAxis( ); // Construct z axis // static inline const Vector3 zAxis( ); }; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( vec_float4 scalar, const Vector3 & vec ); // Multiply two 3-D vectors per element // inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Divide two 3-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Compute the reciprocal of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector3 recipPerElem( const Vector3 & vec ); // Compute the square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector3 sqrtPerElem( const Vector3 & vec ); // Compute the reciprocal square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector3 rsqrtPerElem( const Vector3 & vec ); // Compute the absolute value of a 3-D vector per element // inline const Vector3 absPerElem( const Vector3 & vec ); // Copy sign from one 3-D vector to another, per element // inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Maximum of two 3-D vectors per element // inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Minimum of two 3-D vectors per element // inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Maximum element of a 3-D vector // inline vec_float4 maxElem( const Vector3 & vec ); // Minimum element of a 3-D vector // inline vec_float4 minElem( const Vector3 & vec ); // Compute the sum of all elements of a 3-D vector // inline vec_float4 sum( const Vector3 & vec ); // Compute the dot product of two 3-D vectors // inline vec_float4 dot( const Vector3 & vec0, const Vector3 & vec1 ); // Compute the square of the length of a 3-D vector // inline vec_float4 lengthSqr( const Vector3 & vec ); // Compute the length of a 3-D vector // inline vec_float4 length( const Vector3 & vec ); // Normalize a 3-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector3 normalize( const Vector3 & vec ); // Compute cross product of two 3-D vectors // inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); // Outer product of two 3-D vectors // inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); // Pre-multiply a row vector by a 3x3 matrix // inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); // Cross-product matrix of a 3-D vector // inline const Matrix3 crossMatrix( const Vector3 & vec ); // Create cross-product matrix and multiply // NOTE: // Faster than separately creating a cross-product matrix and multiplying. // inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); // Linear interpolation between two 3-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector3 lerp( vec_float4 t, const Vector3 & vec0, const Vector3 & vec1 ); // Spherical linear interpolation between two 3-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector3 slerp( vec_float4 t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); // Conditionally select between two 3-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, vec_uint4 select1 ); // Load four three-float 3-D vectors, stored in three quadwords // inline void loadXYZArray( Vector3 & vec, const vec_float4 * threeQuads ); // Store four slots of an SoA 3-D vector in three quadwords // inline void storeXYZArray( const Vector3 & vec, vec_float4 * threeQuads ); // Store eight slots of two SoA 3-D vectors as half-floats // inline void storeHalfFloats( const Vector3 & vec0, const Vector3 & vec1, vec_ushort8 * threeQuads ); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector3 & vec ); // Print a 3-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector3 & vec, const char * name ); #endif // A set of four 4-D vectors in structure-of-arrays format // class Vector4 { typedef vec_float4 vec_float4_t; vec_float4 mX; vec_float4 mY; vec_float4 mZ; vec_float4 mW; public: // Default constructor; does no initialization // inline Vector4( ) { }; // Copy a 4-D vector // inline Vector4( const Vector4 & vec ); // Construct a 4-D vector from x, y, z, and w elements // inline Vector4( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); // Construct a 4-D vector from a 3-D vector and a scalar // inline Vector4( const Vector3 & xyz, vec_float4 w ); // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 // explicit inline Vector4( const Vector3 & vec ); // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 // explicit inline Vector4( const Point3 & pnt ); // Copy elements from a quaternion into a 4-D vector // explicit inline Vector4( const Quat & quat ); // Set all elements of a 4-D vector to the same scalar value // explicit inline Vector4( vec_float4 scalar ); // Replicate an AoS 4-D vector // inline Vector4( Aos::Vector4 vec ); // Insert four AoS 4-D vectors // inline Vector4( Aos::Vector4 vec0, Aos::Vector4 vec1, Aos::Vector4 vec2, Aos::Vector4 vec3 ); // Extract four AoS 4-D vectors // inline void get4Aos( Aos::Vector4 & result0, Aos::Vector4 & result1, Aos::Vector4 & result2, Aos::Vector4 & result3 ) const; // Assign one 4-D vector to another // inline Vector4 & operator =( const Vector4 & vec ); // Set the x, y, and z elements of a 4-D vector // NOTE: // This function does not change the w element. // inline Vector4 & setXYZ( const Vector3 & vec ); // Get the x, y, and z elements of a 4-D vector // inline const Vector3 getXYZ( ) const; // Set the x element of a 4-D vector // inline Vector4 & setX( vec_float4 x ); // Set the y element of a 4-D vector // inline Vector4 & setY( vec_float4 y ); // Set the z element of a 4-D vector // inline Vector4 & setZ( vec_float4 z ); // Set the w element of a 4-D vector // inline Vector4 & setW( vec_float4 w ); // Get the x element of a 4-D vector // inline vec_float4 getX( ) const; // Get the y element of a 4-D vector // inline vec_float4 getY( ) const; // Get the z element of a 4-D vector // inline vec_float4 getZ( ) const; // Get the w element of a 4-D vector // inline vec_float4 getW( ) const; // Set an x, y, z, or w element of a 4-D vector by index // inline Vector4 & setElem( int idx, vec_float4 value ); // Get an x, y, z, or w element of a 4-D vector by index // inline vec_float4 getElem( int idx ) const; // Subscripting operator to set or get an element // inline vec_float4_t & operator []( int idx ); // Subscripting operator to get an element // inline vec_float4 operator []( int idx ) const; // Add two 4-D vectors // inline const Vector4 operator +( const Vector4 & vec ) const; // Subtract a 4-D vector from another 4-D vector // inline const Vector4 operator -( const Vector4 & vec ) const; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( vec_float4 scalar ) const; // Divide a 4-D vector by a scalar // inline const Vector4 operator /( vec_float4 scalar ) const; // Perform compound assignment and addition with a 4-D vector // inline Vector4 & operator +=( const Vector4 & vec ); // Perform compound assignment and subtraction by a 4-D vector // inline Vector4 & operator -=( const Vector4 & vec ); // Perform compound assignment and multiplication by a scalar // inline Vector4 & operator *=( vec_float4 scalar ); // Perform compound assignment and division by a scalar // inline Vector4 & operator /=( vec_float4 scalar ); // Negate all elements of a 4-D vector // inline const Vector4 operator -( ) const; // Construct x axis // static inline const Vector4 xAxis( ); // Construct y axis // static inline const Vector4 yAxis( ); // Construct z axis // static inline const Vector4 zAxis( ); // Construct w axis // static inline const Vector4 wAxis( ); }; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( vec_float4 scalar, const Vector4 & vec ); // Multiply two 4-D vectors per element // inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Divide two 4-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Compute the reciprocal of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector4 recipPerElem( const Vector4 & vec ); // Compute the square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector4 sqrtPerElem( const Vector4 & vec ); // Compute the reciprocal square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector4 rsqrtPerElem( const Vector4 & vec ); // Compute the absolute value of a 4-D vector per element // inline const Vector4 absPerElem( const Vector4 & vec ); // Copy sign from one 4-D vector to another, per element // inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Maximum of two 4-D vectors per element // inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Minimum of two 4-D vectors per element // inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Maximum element of a 4-D vector // inline vec_float4 maxElem( const Vector4 & vec ); // Minimum element of a 4-D vector // inline vec_float4 minElem( const Vector4 & vec ); // Compute the sum of all elements of a 4-D vector // inline vec_float4 sum( const Vector4 & vec ); // Compute the dot product of two 4-D vectors // inline vec_float4 dot( const Vector4 & vec0, const Vector4 & vec1 ); // Compute the square of the length of a 4-D vector // inline vec_float4 lengthSqr( const Vector4 & vec ); // Compute the length of a 4-D vector // inline vec_float4 length( const Vector4 & vec ); // Normalize a 4-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector4 normalize( const Vector4 & vec ); // Outer product of two 4-D vectors // inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); // Linear interpolation between two 4-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector4 lerp( vec_float4 t, const Vector4 & vec0, const Vector4 & vec1 ); // Spherical linear interpolation between two 4-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector4 slerp( vec_float4 t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); // Conditionally select between two 4-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, vec_uint4 select1 ); // Store four slots of an SoA 4-D vector as half-floats // inline void storeHalfFloats( const Vector4 & vec, vec_ushort8 * twoQuads ); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector4 & vec ); // Print a 4-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector4 & vec, const char * name ); #endif // A set of four 3-D points in structure-of-arrays format // class Point3 { typedef vec_float4 vec_float4_t; vec_float4 mX; vec_float4 mY; vec_float4 mZ; public: // Default constructor; does no initialization // inline Point3( ) { }; // Copy a 3-D point // inline Point3( const Point3 & pnt ); // Construct a 3-D point from x, y, and z elements // inline Point3( vec_float4 x, vec_float4 y, vec_float4 z ); // Copy elements from a 3-D vector into a 3-D point // explicit inline Point3( const Vector3 & vec ); // Set all elements of a 3-D point to the same scalar value // explicit inline Point3( vec_float4 scalar ); // Replicate an AoS 3-D point // inline Point3( Aos::Point3 pnt ); // Insert four AoS 3-D points // inline Point3( Aos::Point3 pnt0, Aos::Point3 pnt1, Aos::Point3 pnt2, Aos::Point3 pnt3 ); // Extract four AoS 3-D points // inline void get4Aos( Aos::Point3 & result0, Aos::Point3 & result1, Aos::Point3 & result2, Aos::Point3 & result3 ) const; // Assign one 3-D point to another // inline Point3 & operator =( const Point3 & pnt ); // Set the x element of a 3-D point // inline Point3 & setX( vec_float4 x ); // Set the y element of a 3-D point // inline Point3 & setY( vec_float4 y ); // Set the z element of a 3-D point // inline Point3 & setZ( vec_float4 z ); // Get the x element of a 3-D point // inline vec_float4 getX( ) const; // Get the y element of a 3-D point // inline vec_float4 getY( ) const; // Get the z element of a 3-D point // inline vec_float4 getZ( ) const; // Set an x, y, or z element of a 3-D point by index // inline Point3 & setElem( int idx, vec_float4 value ); // Get an x, y, or z element of a 3-D point by index // inline vec_float4 getElem( int idx ) const; // Subscripting operator to set or get an element // inline vec_float4_t & operator []( int idx ); // Subscripting operator to get an element // inline vec_float4 operator []( int idx ) const; // Subtract a 3-D point from another 3-D point // inline const Vector3 operator -( const Point3 & pnt ) const; // Add a 3-D point to a 3-D vector // inline const Point3 operator +( const Vector3 & vec ) const; // Subtract a 3-D vector from a 3-D point // inline const Point3 operator -( const Vector3 & vec ) const; // Perform compound assignment and addition with a 3-D vector // inline Point3 & operator +=( const Vector3 & vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Point3 & operator -=( const Vector3 & vec ); }; // Multiply two 3-D points per element // inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Divide two 3-D points per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Compute the reciprocal of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Point3 recipPerElem( const Point3 & pnt ); // Compute the square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Point3 sqrtPerElem( const Point3 & pnt ); // Compute the reciprocal square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Point3 rsqrtPerElem( const Point3 & pnt ); // Compute the absolute value of a 3-D point per element // inline const Point3 absPerElem( const Point3 & pnt ); // Copy sign from one 3-D point to another, per element // inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Maximum of two 3-D points per element // inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Minimum of two 3-D points per element // inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Maximum element of a 3-D point // inline vec_float4 maxElem( const Point3 & pnt ); // Minimum element of a 3-D point // inline vec_float4 minElem( const Point3 & pnt ); // Compute the sum of all elements of a 3-D point // inline vec_float4 sum( const Point3 & pnt ); // Apply uniform scale to a 3-D point // inline const Point3 scale( const Point3 & pnt, vec_float4 scaleVal ); // Apply non-uniform scale to a 3-D point // inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); // Scalar projection of a 3-D point on a unit-length 3-D vector // inline vec_float4 projection( const Point3 & pnt, const Vector3 & unitVec ); // Compute the square of the distance of a 3-D point from the coordinate-system origin // inline vec_float4 distSqrFromOrigin( const Point3 & pnt ); // Compute the distance of a 3-D point from the coordinate-system origin // inline vec_float4 distFromOrigin( const Point3 & pnt ); // Compute the square of the distance between two 3-D points // inline vec_float4 distSqr( const Point3 & pnt0, const Point3 & pnt1 ); // Compute the distance between two 3-D points // inline vec_float4 dist( const Point3 & pnt0, const Point3 & pnt1 ); // Linear interpolation between two 3-D points // NOTE: // Does not clamp t between 0 and 1. // inline const Point3 lerp( vec_float4 t, const Point3 & pnt0, const Point3 & pnt1 ); // Conditionally select between two 3-D points // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, vec_uint4 select1 ); // Load four three-float 3-D points, stored in three quadwords // inline void loadXYZArray( Point3 & pnt, const vec_float4 * threeQuads ); // Store four slots of an SoA 3-D point in three quadwords // inline void storeXYZArray( const Point3 & pnt, vec_float4 * threeQuads ); // Store eight slots of two SoA 3-D points as half-floats // inline void storeHalfFloats( const Point3 & pnt0, const Point3 & pnt1, vec_ushort8 * threeQuads ); #ifdef _VECTORMATH_DEBUG // Print a 3-D point // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Point3 & pnt ); // Print a 3-D point and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Point3 & pnt, const char * name ); #endif // A set of four quaternions in structure-of-arrays format // class Quat { typedef vec_float4 vec_float4_t; vec_float4 mX; vec_float4 mY; vec_float4 mZ; vec_float4 mW; public: // Default constructor; does no initialization // inline Quat( ) { }; // Copy a quaternion // inline Quat( const Quat & quat ); // Construct a quaternion from x, y, z, and w elements // inline Quat( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); // Construct a quaternion from a 3-D vector and a scalar // inline Quat( const Vector3 & xyz, vec_float4 w ); // Copy elements from a 4-D vector into a quaternion // explicit inline Quat( const Vector4 & vec ); // Convert a rotation matrix to a unit-length quaternion // explicit inline Quat( const Matrix3 & rotMat ); // Set all elements of a quaternion to the same scalar value // explicit inline Quat( vec_float4 scalar ); // Replicate an AoS quaternion // inline Quat( Aos::Quat quat ); // Insert four AoS quaternions // inline Quat( Aos::Quat quat0, Aos::Quat quat1, Aos::Quat quat2, Aos::Quat quat3 ); // Extract four AoS quaternions // inline void get4Aos( Aos::Quat & result0, Aos::Quat & result1, Aos::Quat & result2, Aos::Quat & result3 ) const; // Assign one quaternion to another // inline Quat & operator =( const Quat & quat ); // Set the x, y, and z elements of a quaternion // NOTE: // This function does not change the w element. // inline Quat & setXYZ( const Vector3 & vec ); // Get the x, y, and z elements of a quaternion // inline const Vector3 getXYZ( ) const; // Set the x element of a quaternion // inline Quat & setX( vec_float4 x ); // Set the y element of a quaternion // inline Quat & setY( vec_float4 y ); // Set the z element of a quaternion // inline Quat & setZ( vec_float4 z ); // Set the w element of a quaternion // inline Quat & setW( vec_float4 w ); // Get the x element of a quaternion // inline vec_float4 getX( ) const; // Get the y element of a quaternion // inline vec_float4 getY( ) const; // Get the z element of a quaternion // inline vec_float4 getZ( ) const; // Get the w element of a quaternion // inline vec_float4 getW( ) const; // Set an x, y, z, or w element of a quaternion by index // inline Quat & setElem( int idx, vec_float4 value ); // Get an x, y, z, or w element of a quaternion by index // inline vec_float4 getElem( int idx ) const; // Subscripting operator to set or get an element // inline vec_float4_t & operator []( int idx ); // Subscripting operator to get an element // inline vec_float4 operator []( int idx ) const; // Add two quaternions // inline const Quat operator +( const Quat & quat ) const; // Subtract a quaternion from another quaternion // inline const Quat operator -( const Quat & quat ) const; // Multiply two quaternions // inline const Quat operator *( const Quat & quat ) const; // Multiply a quaternion by a scalar // inline const Quat operator *( vec_float4 scalar ) const; // Divide a quaternion by a scalar // inline const Quat operator /( vec_float4 scalar ) const; // Perform compound assignment and addition with a quaternion // inline Quat & operator +=( const Quat & quat ); // Perform compound assignment and subtraction by a quaternion // inline Quat & operator -=( const Quat & quat ); // Perform compound assignment and multiplication by a quaternion // inline Quat & operator *=( const Quat & quat ); // Perform compound assignment and multiplication by a scalar // inline Quat & operator *=( vec_float4 scalar ); // Perform compound assignment and division by a scalar // inline Quat & operator /=( vec_float4 scalar ); // Negate all elements of a quaternion // inline const Quat operator -( ) const; // Construct an identity quaternion // static inline const Quat identity( ); // Construct a quaternion to rotate between two unit-length 3-D vectors // NOTE: // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. // static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); // Construct a quaternion to rotate around a unit-length 3-D vector // static inline const Quat rotation( vec_float4 radians, const Vector3 & unitVec ); // Construct a quaternion to rotate around the x axis // static inline const Quat rotationX( vec_float4 radians ); // Construct a quaternion to rotate around the y axis // static inline const Quat rotationY( vec_float4 radians ); // Construct a quaternion to rotate around the z axis // static inline const Quat rotationZ( vec_float4 radians ); }; // Multiply a quaternion by a scalar // inline const Quat operator *( vec_float4 scalar, const Quat & quat ); // Compute the conjugate of a quaternion // inline const Quat conj( const Quat & quat ); // Use a unit-length quaternion to rotate a 3-D vector // inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); // Compute the dot product of two quaternions // inline vec_float4 dot( const Quat & quat0, const Quat & quat1 ); // Compute the norm of a quaternion // inline vec_float4 norm( const Quat & quat ); // Compute the length of a quaternion // inline vec_float4 length( const Quat & quat ); // Normalize a quaternion // NOTE: // The result is unpredictable when all elements of quat are at or near zero. // inline const Quat normalize( const Quat & quat ); // Linear interpolation between two quaternions // NOTE: // Does not clamp t between 0 and 1. // inline const Quat lerp( vec_float4 t, const Quat & quat0, const Quat & quat1 ); // Spherical linear interpolation between two quaternions // NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. // inline const Quat slerp( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1 ); // Spherical quadrangle interpolation // inline const Quat squad( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); // Conditionally select between two quaternions // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Quat select( const Quat & quat0, const Quat & quat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG // Print a quaternion // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Quat & quat ); // Print a quaternion and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Quat & quat, const char * name ); #endif // A set of four 3x3 matrices in structure-of-arrays format // class Matrix3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; public: // Default constructor; does no initialization // inline Matrix3( ) { }; // Copy a 3x3 matrix // inline Matrix3( const Matrix3 & mat ); // Construct a 3x3 matrix containing the specified columns // inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); // Construct a 3x3 rotation matrix from a unit-length quaternion // explicit inline Matrix3( const Quat & unitQuat ); // Set all elements of a 3x3 matrix to the same scalar value // explicit inline Matrix3( vec_float4 scalar ); // Replicate an AoS 3x3 matrix // inline Matrix3( const Aos::Matrix3 & mat ); // Insert four AoS 3x3 matrices // inline Matrix3( const Aos::Matrix3 & mat0, const Aos::Matrix3 & mat1, const Aos::Matrix3 & mat2, const Aos::Matrix3 & mat3 ); // Extract four AoS 3x3 matrices // inline void get4Aos( Aos::Matrix3 & result0, Aos::Matrix3 & result1, Aos::Matrix3 & result2, Aos::Matrix3 & result3 ) const; // Assign one 3x3 matrix to another // inline Matrix3 & operator =( const Matrix3 & mat ); // Set column 0 of a 3x3 matrix // inline Matrix3 & setCol0( const Vector3 & col0 ); // Set column 1 of a 3x3 matrix // inline Matrix3 & setCol1( const Vector3 & col1 ); // Set column 2 of a 3x3 matrix // inline Matrix3 & setCol2( const Vector3 & col2 ); // Get column 0 of a 3x3 matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x3 matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x3 matrix // inline const Vector3 getCol2( ) const; // Set the column of a 3x3 matrix referred to by the specified index // inline Matrix3 & setCol( int col, const Vector3 & vec ); // Set the row of a 3x3 matrix referred to by the specified index // inline Matrix3 & setRow( int row, const Vector3 & vec ); // Get the column of a 3x3 matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x3 matrix referred to by the specified index // inline const Vector3 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x3 matrix referred to by column and row indices // inline Matrix3 & setElem( int col, int row, vec_float4 val ); // Get the element of a 3x3 matrix referred to by column and row indices // inline vec_float4 getElem( int col, int row ) const; // Add two 3x3 matrices // inline const Matrix3 operator +( const Matrix3 & mat ) const; // Subtract a 3x3 matrix from another 3x3 matrix // inline const Matrix3 operator -( const Matrix3 & mat ) const; // Negate all elements of a 3x3 matrix // inline const Matrix3 operator -( ) const; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( vec_float4 scalar ) const; // Multiply a 3x3 matrix by a 3-D vector // inline const Vector3 operator *( const Vector3 & vec ) const; // Multiply two 3x3 matrices // inline const Matrix3 operator *( const Matrix3 & mat ) const; // Perform compound assignment and addition with a 3x3 matrix // inline Matrix3 & operator +=( const Matrix3 & mat ); // Perform compound assignment and subtraction by a 3x3 matrix // inline Matrix3 & operator -=( const Matrix3 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix3 & operator *=( vec_float4 scalar ); // Perform compound assignment and multiplication by a 3x3 matrix // inline Matrix3 & operator *=( const Matrix3 & mat ); // Construct an identity 3x3 matrix // static inline const Matrix3 identity( ); // Construct a 3x3 matrix to rotate around the x axis // static inline const Matrix3 rotationX( vec_float4 radians ); // Construct a 3x3 matrix to rotate around the y axis // static inline const Matrix3 rotationY( vec_float4 radians ); // Construct a 3x3 matrix to rotate around the z axis // static inline const Matrix3 rotationZ( vec_float4 radians ); // Construct a 3x3 matrix to rotate around the x, y, and z axes // static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 3x3 matrix to rotate around a unit-length 3-D vector // static inline const Matrix3 rotation( vec_float4 radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix3 rotation( const Quat & unitQuat ); // Construct a 3x3 matrix to perform scaling // static inline const Matrix3 scale( const Vector3 & scaleVec ); }; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( vec_float4 scalar, const Matrix3 & mat ); // Append (post-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); // Multiply two 3x3 matrices per element // inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); // Compute the absolute value of a 3x3 matrix per element // inline const Matrix3 absPerElem( const Matrix3 & mat ); // Transpose of a 3x3 matrix // inline const Matrix3 transpose( const Matrix3 & mat ); // Compute the inverse of a 3x3 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix3 inverse( const Matrix3 & mat ); // Determinant of a 3x3 matrix // inline vec_float4 determinant( const Matrix3 & mat ); // Conditionally select between two 3x3 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat ); // Print a 3x3 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat, const char * name ); #endif // A set of four 4x4 matrices in structure-of-arrays format // class Matrix4 { Vector4 mCol0; Vector4 mCol1; Vector4 mCol2; Vector4 mCol3; public: // Default constructor; does no initialization // inline Matrix4( ) { }; // Copy a 4x4 matrix // inline Matrix4( const Matrix4 & mat ); // Construct a 4x4 matrix containing the specified columns // inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); // Construct a 4x4 matrix from a 3x4 transformation matrix // explicit inline Matrix4( const Transform3 & mat ); // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector // inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector // inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); // Set all elements of a 4x4 matrix to the same scalar value // explicit inline Matrix4( vec_float4 scalar ); // Replicate an AoS 4x4 matrix // inline Matrix4( const Aos::Matrix4 & mat ); // Insert four AoS 4x4 matrices // inline Matrix4( const Aos::Matrix4 & mat0, const Aos::Matrix4 & mat1, const Aos::Matrix4 & mat2, const Aos::Matrix4 & mat3 ); // Extract four AoS 4x4 matrices // inline void get4Aos( Aos::Matrix4 & result0, Aos::Matrix4 & result1, Aos::Matrix4 & result2, Aos::Matrix4 & result3 ) const; // Assign one 4x4 matrix to another // inline Matrix4 & operator =( const Matrix4 & mat ); // Set the upper-left 3x3 submatrix // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 4x4 matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setTranslation( const Vector3 & translateVec ); // Get the translation component of a 4x4 matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 4x4 matrix // inline Matrix4 & setCol0( const Vector4 & col0 ); // Set column 1 of a 4x4 matrix // inline Matrix4 & setCol1( const Vector4 & col1 ); // Set column 2 of a 4x4 matrix // inline Matrix4 & setCol2( const Vector4 & col2 ); // Set column 3 of a 4x4 matrix // inline Matrix4 & setCol3( const Vector4 & col3 ); // Get column 0 of a 4x4 matrix // inline const Vector4 getCol0( ) const; // Get column 1 of a 4x4 matrix // inline const Vector4 getCol1( ) const; // Get column 2 of a 4x4 matrix // inline const Vector4 getCol2( ) const; // Get column 3 of a 4x4 matrix // inline const Vector4 getCol3( ) const; // Set the column of a 4x4 matrix referred to by the specified index // inline Matrix4 & setCol( int col, const Vector4 & vec ); // Set the row of a 4x4 matrix referred to by the specified index // inline Matrix4 & setRow( int row, const Vector4 & vec ); // Get the column of a 4x4 matrix referred to by the specified index // inline const Vector4 getCol( int col ) const; // Get the row of a 4x4 matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector4 & operator []( int col ); // Subscripting operator to get a column // inline const Vector4 operator []( int col ) const; // Set the element of a 4x4 matrix referred to by column and row indices // inline Matrix4 & setElem( int col, int row, vec_float4 val ); // Get the element of a 4x4 matrix referred to by column and row indices // inline vec_float4 getElem( int col, int row ) const; // Add two 4x4 matrices // inline const Matrix4 operator +( const Matrix4 & mat ) const; // Subtract a 4x4 matrix from another 4x4 matrix // inline const Matrix4 operator -( const Matrix4 & mat ) const; // Negate all elements of a 4x4 matrix // inline const Matrix4 operator -( ) const; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( vec_float4 scalar ) const; // Multiply a 4x4 matrix by a 4-D vector // inline const Vector4 operator *( const Vector4 & vec ) const; // Multiply a 4x4 matrix by a 3-D vector // inline const Vector4 operator *( const Vector3 & vec ) const; // Multiply a 4x4 matrix by a 3-D point // inline const Vector4 operator *( const Point3 & pnt ) const; // Multiply two 4x4 matrices // inline const Matrix4 operator *( const Matrix4 & mat ) const; // Multiply a 4x4 matrix by a 3x4 transformation matrix // inline const Matrix4 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and addition with a 4x4 matrix // inline Matrix4 & operator +=( const Matrix4 & mat ); // Perform compound assignment and subtraction by a 4x4 matrix // inline Matrix4 & operator -=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix4 & operator *=( vec_float4 scalar ); // Perform compound assignment and multiplication by a 4x4 matrix // inline Matrix4 & operator *=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Matrix4 & operator *=( const Transform3 & tfrm ); // Construct an identity 4x4 matrix // static inline const Matrix4 identity( ); // Construct a 4x4 matrix to rotate around the x axis // static inline const Matrix4 rotationX( vec_float4 radians ); // Construct a 4x4 matrix to rotate around the y axis // static inline const Matrix4 rotationY( vec_float4 radians ); // Construct a 4x4 matrix to rotate around the z axis // static inline const Matrix4 rotationZ( vec_float4 radians ); // Construct a 4x4 matrix to rotate around the x, y, and z axes // static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 4x4 matrix to rotate around a unit-length 3-D vector // static inline const Matrix4 rotation( vec_float4 radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix4 rotation( const Quat & unitQuat ); // Construct a 4x4 matrix to perform scaling // static inline const Matrix4 scale( const Vector3 & scaleVec ); // Construct a 4x4 matrix to perform translation // static inline const Matrix4 translation( const Vector3 & translateVec ); // Construct viewing matrix based on eye position, position looked at, and up direction // static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); // Construct a perspective projection matrix // static inline const Matrix4 perspective( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ); // Construct a perspective projection matrix based on frustum // static inline const Matrix4 frustum( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); // Construct an orthographic projection matrix // static inline const Matrix4 orthographic( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); }; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( vec_float4 scalar, const Matrix4 & mat ); // Append (post-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); // Multiply two 4x4 matrices per element // inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); // Compute the absolute value of a 4x4 matrix per element // inline const Matrix4 absPerElem( const Matrix4 & mat ); // Transpose of a 4x4 matrix // inline const Matrix4 transpose( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix4 inverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix // NOTE: // 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. // inline const Matrix4 affineInverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. // inline const Matrix4 orthoInverse( const Matrix4 & mat ); // Determinant of a 4x4 matrix // inline vec_float4 determinant( const Matrix4 & mat ); // Conditionally select between two 4x4 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat ); // Print a 4x4 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat, const char * name ); #endif // A set of four 3x4 transformation matrices in structure-of-arrays format // class Transform3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; Vector3 mCol3; public: // Default constructor; does no initialization // inline Transform3( ) { }; // Copy a 3x4 transformation matrix // inline Transform3( const Transform3 & tfrm ); // Construct a 3x4 transformation matrix containing the specified columns // inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector // inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector // inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); // Set all elements of a 3x4 transformation matrix to the same scalar value // explicit inline Transform3( vec_float4 scalar ); // Replicate an AoS 3x4 transformation matrix // inline Transform3( const Aos::Transform3 & tfrm ); // Insert four AoS 3x4 transformation matrices // inline Transform3( const Aos::Transform3 & tfrm0, const Aos::Transform3 & tfrm1, const Aos::Transform3 & tfrm2, const Aos::Transform3 & tfrm3 ); // Extract four AoS 3x4 transformation matrices // inline void get4Aos( Aos::Transform3 & result0, Aos::Transform3 & result1, Aos::Transform3 & result2, Aos::Transform3 & result3 ) const; // Assign one 3x4 transformation matrix to another // inline Transform3 & operator =( const Transform3 & tfrm ); // Set the upper-left 3x3 submatrix // inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // inline Transform3 & setTranslation( const Vector3 & translateVec ); // Get the translation component of a 3x4 transformation matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 3x4 transformation matrix // inline Transform3 & setCol0( const Vector3 & col0 ); // Set column 1 of a 3x4 transformation matrix // inline Transform3 & setCol1( const Vector3 & col1 ); // Set column 2 of a 3x4 transformation matrix // inline Transform3 & setCol2( const Vector3 & col2 ); // Set column 3 of a 3x4 transformation matrix // inline Transform3 & setCol3( const Vector3 & col3 ); // Get column 0 of a 3x4 transformation matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x4 transformation matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x4 transformation matrix // inline const Vector3 getCol2( ) const; // Get column 3 of a 3x4 transformation matrix // inline const Vector3 getCol3( ) const; // Set the column of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setCol( int col, const Vector3 & vec ); // Set the row of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setRow( int row, const Vector4 & vec ); // Get the column of a 3x4 transformation matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x4 transformation matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x4 transformation matrix referred to by column and row indices // inline Transform3 & setElem( int col, int row, vec_float4 val ); // Get the element of a 3x4 transformation matrix referred to by column and row indices // inline vec_float4 getElem( int col, int row ) const; // Multiply a 3x4 transformation matrix by a 3-D vector // inline const Vector3 operator *( const Vector3 & vec ) const; // Multiply a 3x4 transformation matrix by a 3-D point // inline const Point3 operator *( const Point3 & pnt ) const; // Multiply two 3x4 transformation matrices // inline const Transform3 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Transform3 & operator *=( const Transform3 & tfrm ); // Construct an identity 3x4 transformation matrix // static inline const Transform3 identity( ); // Construct a 3x4 transformation matrix to rotate around the x axis // static inline const Transform3 rotationX( vec_float4 radians ); // Construct a 3x4 transformation matrix to rotate around the y axis // static inline const Transform3 rotationY( vec_float4 radians ); // Construct a 3x4 transformation matrix to rotate around the z axis // static inline const Transform3 rotationZ( vec_float4 radians ); // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes // static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector // static inline const Transform3 rotation( vec_float4 radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Transform3 rotation( const Quat & unitQuat ); // Construct a 3x4 transformation matrix to perform scaling // static inline const Transform3 scale( const Vector3 & scaleVec ); // Construct a 3x4 transformation matrix to perform translation // static inline const Transform3 translation( const Vector3 & translateVec ); }; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); // Multiply two 3x4 transformation matrices per element // inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); // Compute the absolute value of a 3x4 transformation matrix per element // inline const Transform3 absPerElem( const Transform3 & tfrm ); // Inverse of a 3x4 transformation matrix // NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. // inline const Transform3 inverse( const Transform3 & tfrm ); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. // inline const Transform3 orthoInverse( const Transform3 & tfrm ); // Conditionally select between two 3x4 transformation matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm ); // Print a 3x4 transformation matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm, const char * name ); #endif } // namespace Soa } // namespace Vectormath #include "vec_soa.h" #include "quat_soa.h" #include "mat_soa.h" #endif ================================================ FILE: samples/vectormath/scalar/c/mat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_C_H #define _VECTORMATH_MAT_AOS_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants */ #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( &result->col0, &mat->col0 ); vmathV3Copy( &result->col1, &mat->col1 ); vmathV3Copy( &result->col2, &mat->col2 ); } static inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar ) { vmathV3MakeFromScalar( &result->col0, scalar ); vmathV3MakeFromScalar( &result->col1, scalar ); vmathV3MakeFromScalar( &result->col2, scalar ); } static inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat ) { float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; qx = unitQuat->x; qy = unitQuat->y; qz = unitQuat->z; qw = unitQuat->w; qx2 = ( qx + qx ); qy2 = ( qy + qy ); qz2 = ( qz + qz ); qxqx2 = ( qx * qx2 ); qxqy2 = ( qx * qy2 ); qxqz2 = ( qx * qz2 ); qxqw2 = ( qw * qx2 ); qyqy2 = ( qy * qy2 ); qyqz2 = ( qy * qz2 ); qyqw2 = ( qw * qy2 ); qzqz2 = ( qz * qz2 ); qzqw2 = ( qw * qz2 ); vmathV3MakeFromElems( &result->col0, ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) ); vmathV3MakeFromElems( &result->col1, ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) ); vmathV3MakeFromElems( &result->col2, ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) ); } static inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col0, _col0 ); vmathV3Copy( &result->col1, _col1 ); vmathV3Copy( &result->col2, _col2 ); } static inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *_col0 ) { vmathV3Copy( &result->col0, _col0 ); } static inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *_col1 ) { vmathV3Copy( &result->col1, _col1 ); } static inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col2, _col2 ); } static inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec ) { vmathV3Copy( (&result->col0 + col), vec ); } static inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec ) { vmathV3SetElem( &result->col0, row, vmathV3GetElem( vec, 0 ) ); vmathV3SetElem( &result->col1, row, vmathV3GetElem( vec, 1 ) ); vmathV3SetElem( &result->col2, row, vmathV3GetElem( vec, 2 ) ); } static inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val ) { VmathVector3 tmpV3_0; vmathM3GetCol( &tmpV3_0, result, col ); vmathV3SetElem( &tmpV3_0, row, val ); vmathM3SetCol( result, col, &tmpV3_0 ); } static inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row ) { VmathVector3 tmpV3_0; vmathM3GetCol( &tmpV3_0, mat, col ); return vmathV3GetElem( &tmpV3_0, row ); } static inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col0 ); } static inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col1 ); } static inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col2 ); } static inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col ) { vmathV3Copy( result, (&mat->col0 + col) ); } static inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row ) { vmathV3MakeFromElems( result, vmathV3GetElem( &mat->col0, row ), vmathV3GetElem( &mat->col1, row ), vmathV3GetElem( &mat->col2, row ) ); } static inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat ) { VmathMatrix3 tmpResult; vmathV3MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x ); vmathV3MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y ); vmathV3MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z ); vmathM3Copy( result, &tmpResult ); } static inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat ) { VmathVector3 tmp0, tmp1, tmp2; float detinv; vmathV3Cross( &tmp0, &mat->col1, &mat->col2 ); vmathV3Cross( &tmp1, &mat->col2, &mat->col0 ); vmathV3Cross( &tmp2, &mat->col0, &mat->col1 ); detinv = ( 1.0f / vmathV3Dot( &mat->col2, &tmp2 ) ); vmathV3MakeFromElems( &result->col0, ( tmp0.x * detinv ), ( tmp1.x * detinv ), ( tmp2.x * detinv ) ); vmathV3MakeFromElems( &result->col1, ( tmp0.y * detinv ), ( tmp1.y * detinv ), ( tmp2.y * detinv ) ); vmathV3MakeFromElems( &result->col2, ( tmp0.z * detinv ), ( tmp1.z * detinv ), ( tmp2.z * detinv ) ); } static inline float vmathM3Determinant( const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0; vmathV3Cross( &tmpV3_0, &mat->col0, &mat->col1 ); return vmathV3Dot( &mat->col2, &tmpV3_0 ); } static inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3Add( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3Sub( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3Neg( &result->col0, &mat->col0 ); vmathV3Neg( &result->col1, &mat->col1 ); vmathV3Neg( &result->col2, &mat->col2 ); } static inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3AbsPerElem( &result->col0, &mat->col0 ); vmathV3AbsPerElem( &result->col1, &mat->col1 ); vmathV3AbsPerElem( &result->col2, &mat->col2 ); } static inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar ) { vmathV3ScalarMul( &result->col0, &mat->col0, scalar ); vmathV3ScalarMul( &result->col1, &mat->col1, scalar ); vmathV3ScalarMul( &result->col2, &mat->col2, scalar ); } static inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec ) { float tmpX, tmpY, tmpZ; tmpX = ( ( ( mat->col0.x * vec->x ) + ( mat->col1.x * vec->y ) ) + ( mat->col2.x * vec->z ) ); tmpY = ( ( ( mat->col0.y * vec->x ) + ( mat->col1.y * vec->y ) ) + ( mat->col2.y * vec->z ) ); tmpZ = ( ( ( mat->col0.z * vec->x ) + ( mat->col1.z * vec->y ) ) + ( mat->col2.z * vec->z ) ); vmathV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { VmathMatrix3 tmpResult; vmathM3MulV3( &tmpResult.col0, mat0, &mat1->col0 ); vmathM3MulV3( &tmpResult.col1, mat0, &mat1->col1 ); vmathM3MulV3( &tmpResult.col2, mat0, &mat1->col2 ); vmathM3Copy( result, &tmpResult ); } static inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3MakeIdentity( VmathMatrix3 *result ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); } static inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV3MakeXAxis( &result->col0 ); vmathV3MakeFromElems( &result->col1, 0.0f, c, s ); vmathV3MakeFromElems( &result->col2, 0.0f, -s, c ); } static inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV3MakeFromElems( &result->col0, c, 0.0f, -s ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeFromElems( &result->col2, s, 0.0f, c ); } static inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV3MakeFromElems( &result->col0, c, s, 0.0f ); vmathV3MakeFromElems( &result->col1, -s, c, 0.0f ); vmathV3MakeZAxis( &result->col2 ); } static inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ ) { float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sX = sinf( radiansXYZ->x ); cX = cosf( radiansXYZ->x ); sY = sinf( radiansXYZ->y ); cY = cosf( radiansXYZ->y ); sZ = sinf( radiansXYZ->z ); cZ = cosf( radiansXYZ->z ); tmp0 = ( cZ * sY ); tmp1 = ( sZ * sY ); vmathV3MakeFromElems( &result->col0, ( cZ * cY ), ( sZ * cY ), -sY ); vmathV3MakeFromElems( &result->col1, ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ); vmathV3MakeFromElems( &result->col2, ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ); } static inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec ) { float x, y, z, s, c, oneMinusC, xy, yz, zx; s = sinf( radians ); c = cosf( radians ); x = unitVec->x; y = unitVec->y; z = unitVec->z; xy = ( x * y ); yz = ( y * z ); zx = ( z * x ); oneMinusC = ( 1.0f - c ); vmathV3MakeFromElems( &result->col0, ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ); vmathV3MakeFromElems( &result->col1, ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ); vmathV3MakeFromElems( &result->col2, ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) ); } static inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat ) { vmathM3MakeFromQ( result, unitQuat ); } static inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec ) { vmathV3MakeFromElems( &result->col0, scaleVec->x, 0.0f, 0.0f ); vmathV3MakeFromElems( &result->col1, 0.0f, scaleVec->y, 0.0f ); vmathV3MakeFromElems( &result->col2, 0.0f, 0.0f, scaleVec->z ); } static inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec ) { vmathV3ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) ); vmathV3ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) ); vmathV3ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) ); } static inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat ) { vmathV3MulPerElem( &result->col0, &mat->col0, scaleVec ); vmathV3MulPerElem( &result->col1, &mat->col1, scaleVec ); vmathV3MulPerElem( &result->col2, &mat->col2, scaleVec ); } static inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 ) { vmathV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathM3Print( const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2; vmathM3GetRow( &tmpV3_0, mat, 0 ); vmathV3Print( &tmpV3_0 ); vmathM3GetRow( &tmpV3_1, mat, 1 ); vmathV3Print( &tmpV3_1 ); vmathM3GetRow( &tmpV3_2, mat, 2 ); vmathV3Print( &tmpV3_2 ); } static inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name ) { printf("%s:\n", name); vmathM3Print( mat ); } #endif static inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( &result->col0, &mat->col0 ); vmathV4Copy( &result->col1, &mat->col1 ); vmathV4Copy( &result->col2, &mat->col2 ); vmathV4Copy( &result->col3, &mat->col3 ); } static inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar ) { vmathV4MakeFromScalar( &result->col0, scalar ); vmathV4MakeFromScalar( &result->col1, scalar ); vmathV4MakeFromScalar( &result->col2, scalar ); vmathV4MakeFromScalar( &result->col3, scalar ); } static inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat ) { vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, &mat->col3, 1.0f ); } static inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *_col0, const VmathVector4 *_col1, const VmathVector4 *_col2, const VmathVector4 *_col3 ) { vmathV4Copy( &result->col0, _col0 ); vmathV4Copy( &result->col1, _col1 ); vmathV4Copy( &result->col2, _col2 ); vmathV4Copy( &result->col3, _col3 ); } static inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec ) { vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ) { VmathMatrix3 mat; vmathM3MakeFromQ( &mat, unitQuat ); vmathV4MakeFromV3Scalar( &result->col0, &mat.col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat.col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat.col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *_col0 ) { vmathV4Copy( &result->col0, _col0 ); } static inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *_col1 ) { vmathV4Copy( &result->col1, _col1 ); } static inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *_col2 ) { vmathV4Copy( &result->col2, _col2 ); } static inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *_col3 ) { vmathV4Copy( &result->col3, _col3 ); } static inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec ) { vmathV4Copy( (&result->col0 + col), vec ); } static inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec ) { vmathV4SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) ); vmathV4SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) ); vmathV4SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) ); vmathV4SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) ); } static inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val ) { VmathVector4 tmpV3_0; vmathM4GetCol( &tmpV3_0, result, col ); vmathV4SetElem( &tmpV3_0, row, val ); vmathM4SetCol( result, col, &tmpV3_0 ); } static inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row ) { VmathVector4 tmpV4_0; vmathM4GetCol( &tmpV4_0, mat, col ); return vmathV4GetElem( &tmpV4_0, row ); } static inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col0 ); } static inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col1 ); } static inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col2 ); } static inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col3 ); } static inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col ) { vmathV4Copy( result, (&mat->col0 + col) ); } static inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row ) { vmathV4MakeFromElems( result, vmathV4GetElem( &mat->col0, row ), vmathV4GetElem( &mat->col1, row ), vmathV4GetElem( &mat->col2, row ), vmathV4GetElem( &mat->col3, row ) ); } static inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat ) { VmathMatrix4 tmpResult; vmathV4MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x, mat->col3.x ); vmathV4MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y, mat->col3.y ); vmathV4MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z, mat->col3.z ); vmathV4MakeFromElems( &tmpResult.col3, mat->col0.w, mat->col1.w, mat->col2.w, mat->col3.w ); vmathM4Copy( result, &tmpResult ); } static inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { VmathVector4 res0, res1, res2, res3; float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; mA = mat->col0.x; mB = mat->col0.y; mC = mat->col0.z; mD = mat->col0.w; mE = mat->col1.x; mF = mat->col1.y; mG = mat->col1.z; mH = mat->col1.w; mI = mat->col2.x; mJ = mat->col2.y; mK = mat->col2.z; mL = mat->col2.w; mM = mat->col3.x; mN = mat->col3.y; mO = mat->col3.z; mP = mat->col3.w; tmp0 = ( ( mK * mD ) - ( mC * mL ) ); tmp1 = ( ( mO * mH ) - ( mG * mP ) ); tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); tmp3 = ( ( mF * mO ) - ( mN * mG ) ); tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); tmp5 = ( ( mN * mH ) - ( mF * mP ) ); vmathV4SetX( &res0, ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) ); vmathV4SetY( &res0, ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) ); vmathV4SetZ( &res0, ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) ); vmathV4SetW( &res0, ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) ); detInv = ( 1.0f / ( ( ( ( mA * res0.x ) + ( mE * res0.y ) ) + ( mI * res0.z ) ) + ( mM * res0.w ) ) ); vmathV4SetX( &res1, ( mI * tmp1 ) ); vmathV4SetY( &res1, ( mM * tmp0 ) ); vmathV4SetZ( &res1, ( mA * tmp1 ) ); vmathV4SetW( &res1, ( mE * tmp0 ) ); vmathV4SetX( &res3, ( mI * tmp3 ) ); vmathV4SetY( &res3, ( mM * tmp2 ) ); vmathV4SetZ( &res3, ( mA * tmp3 ) ); vmathV4SetW( &res3, ( mE * tmp2 ) ); vmathV4SetX( &res2, ( mI * tmp5 ) ); vmathV4SetY( &res2, ( mM * tmp4 ) ); vmathV4SetZ( &res2, ( mA * tmp5 ) ); vmathV4SetW( &res2, ( mE * tmp4 ) ); tmp0 = ( ( mI * mB ) - ( mA * mJ ) ); tmp1 = ( ( mM * mF ) - ( mE * mN ) ); tmp2 = ( ( mI * mD ) - ( mA * mL ) ); tmp3 = ( ( mM * mH ) - ( mE * mP ) ); tmp4 = ( ( mI * mC ) - ( mA * mK ) ); tmp5 = ( ( mM * mG ) - ( mE * mO ) ); vmathV4SetX( &res2, ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.x ) ); vmathV4SetY( &res2, ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.y ) ); vmathV4SetZ( &res2, ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.z ) ); vmathV4SetW( &res2, ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.w ) ); vmathV4SetX( &res3, ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.x ) ); vmathV4SetY( &res3, ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.y ) ); vmathV4SetZ( &res3, ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.z ) ); vmathV4SetW( &res3, ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.w ) ); vmathV4SetX( &res1, ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.x ) ); vmathV4SetY( &res1, ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.y ) ); vmathV4SetZ( &res1, ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.z ) ); vmathV4SetW( &res1, ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.w ) ); vmathV4ScalarMul( &result->col0, &res0, detInv ); vmathV4ScalarMul( &result->col1, &res1, detInv ); vmathV4ScalarMul( &result->col2, &res2, detInv ); vmathV4ScalarMul( &result->col3, &res3, detInv ); } static inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { VmathTransform3 affineMat, tmpT3_0; VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathT3SetCol0( &affineMat, &tmpV3_0 ); vmathV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathT3SetCol1( &affineMat, &tmpV3_1 ); vmathV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathT3SetCol2( &affineMat, &tmpV3_2 ); vmathV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathT3SetCol3( &affineMat, &tmpV3_3 ); vmathT3Inverse( &tmpT3_0, &affineMat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { VmathTransform3 affineMat, tmpT3_0; VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathT3SetCol0( &affineMat, &tmpV3_0 ); vmathV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathT3SetCol1( &affineMat, &tmpV3_1 ); vmathV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathT3SetCol2( &affineMat, &tmpV3_2 ); vmathV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathT3SetCol3( &affineMat, &tmpV3_3 ); vmathT3OrthoInverse( &tmpT3_0, &affineMat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline float vmathM4Determinant( const VmathMatrix4 *mat ) { 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; mA = mat->col0.x; mB = mat->col0.y; mC = mat->col0.z; mD = mat->col0.w; mE = mat->col1.x; mF = mat->col1.y; mG = mat->col1.z; mH = mat->col1.w; mI = mat->col2.x; mJ = mat->col2.y; mK = mat->col2.z; mL = mat->col2.w; mM = mat->col3.x; mN = mat->col3.y; mO = mat->col3.z; mP = mat->col3.w; tmp0 = ( ( mK * mD ) - ( mC * mL ) ); tmp1 = ( ( mO * mH ) - ( mG * mP ) ); tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); tmp3 = ( ( mF * mO ) - ( mN * mG ) ); tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); tmp5 = ( ( mN * mH ) - ( mF * mP ) ); dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ); dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ); dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ); dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ); return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) ); } static inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4Add( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4Add( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4Sub( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4Sub( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4Neg( &result->col0, &mat->col0 ); vmathV4Neg( &result->col1, &mat->col1 ); vmathV4Neg( &result->col2, &mat->col2 ); vmathV4Neg( &result->col3, &mat->col3 ); } static inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4AbsPerElem( &result->col0, &mat->col0 ); vmathV4AbsPerElem( &result->col1, &mat->col1 ); vmathV4AbsPerElem( &result->col2, &mat->col2 ); vmathV4AbsPerElem( &result->col3, &mat->col3 ); } static inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar ) { vmathV4ScalarMul( &result->col0, &mat->col0, scalar ); vmathV4ScalarMul( &result->col1, &mat->col1, scalar ); vmathV4ScalarMul( &result->col2, &mat->col2, scalar ); vmathV4ScalarMul( &result->col3, &mat->col3, scalar ); } static inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec ) { float tmpX, tmpY, tmpZ, tmpW; tmpX = ( ( ( ( mat->col0.x * vec->x ) + ( mat->col1.x * vec->y ) ) + ( mat->col2.x * vec->z ) ) + ( mat->col3.x * vec->w ) ); tmpY = ( ( ( ( mat->col0.y * vec->x ) + ( mat->col1.y * vec->y ) ) + ( mat->col2.y * vec->z ) ) + ( mat->col3.y * vec->w ) ); tmpZ = ( ( ( ( mat->col0.z * vec->x ) + ( mat->col1.z * vec->y ) ) + ( mat->col2.z * vec->z ) ) + ( mat->col3.z * vec->w ) ); tmpW = ( ( ( ( mat->col0.w * vec->x ) + ( mat->col1.w * vec->y ) ) + ( mat->col2.w * vec->z ) ) + ( mat->col3.w * vec->w ) ); vmathV4MakeFromElems( result, tmpX, tmpY, tmpZ, tmpW ); } static inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec ) { result->x = ( ( ( mat->col0.x * vec->x ) + ( mat->col1.x * vec->y ) ) + ( mat->col2.x * vec->z ) ); result->y = ( ( ( mat->col0.y * vec->x ) + ( mat->col1.y * vec->y ) ) + ( mat->col2.y * vec->z ) ); result->z = ( ( ( mat->col0.z * vec->x ) + ( mat->col1.z * vec->y ) ) + ( mat->col2.z * vec->z ) ); result->w = ( ( ( mat->col0.w * vec->x ) + ( mat->col1.w * vec->y ) ) + ( mat->col2.w * vec->z ) ); } static inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt ) { result->x = ( ( ( ( mat->col0.x * pnt->x ) + ( mat->col1.x * pnt->y ) ) + ( mat->col2.x * pnt->z ) ) + mat->col3.x ); result->y = ( ( ( ( mat->col0.y * pnt->x ) + ( mat->col1.y * pnt->y ) ) + ( mat->col2.y * pnt->z ) ) + mat->col3.y ); result->z = ( ( ( ( mat->col0.z * pnt->x ) + ( mat->col1.z * pnt->y ) ) + ( mat->col2.z * pnt->z ) ) + mat->col3.z ); result->w = ( ( ( ( mat->col0.w * pnt->x ) + ( mat->col1.w * pnt->y ) ) + ( mat->col2.w * pnt->z ) ) + mat->col3.w ); } static inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { VmathMatrix4 tmpResult; vmathM4MulV4( &tmpResult.col0, mat0, &mat1->col0 ); vmathM4MulV4( &tmpResult.col1, mat0, &mat1->col1 ); vmathM4MulV4( &tmpResult.col2, mat0, &mat1->col2 ); vmathM4MulV4( &tmpResult.col3, mat0, &mat1->col3 ); vmathM4Copy( result, &tmpResult ); } static inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm1 ) { VmathMatrix4 tmpResult; VmathPoint3 tmpP3_0; vmathM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 ); vmathM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 ); vmathM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 ); vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathM4MulP3( &tmpResult.col3, mat, &tmpP3_0 ); vmathM4Copy( result, &tmpResult ); } static inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4MakeIdentity( VmathMatrix4 *result ) { vmathV4MakeXAxis( &result->col0 ); vmathV4MakeYAxis( &result->col1 ); vmathV4MakeZAxis( &result->col2 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 ) { vmathV4SetXYZ( &result->col0, &mat3->col0 ); vmathV4SetXYZ( &result->col1, &mat3->col1 ); vmathV4SetXYZ( &result->col2, &mat3->col2 ); } static inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat ) { vmathV4GetXYZ( &result->col0, &mat->col0 ); vmathV4GetXYZ( &result->col1, &mat->col1 ); vmathV4GetXYZ( &result->col2, &mat->col2 ); } static inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ) { vmathV4SetXYZ( &result->col3, translateVec ); } static inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat ) { vmathV4GetXYZ( result, &mat->col3 ); } static inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV4MakeXAxis( &result->col0 ); vmathV4MakeFromElems( &result->col1, 0.0f, c, s, 0.0f ); vmathV4MakeFromElems( &result->col2, 0.0f, -s, c, 0.0f ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV4MakeFromElems( &result->col0, c, 0.0f, -s, 0.0f ); vmathV4MakeYAxis( &result->col1 ); vmathV4MakeFromElems( &result->col2, s, 0.0f, c, 0.0f ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV4MakeFromElems( &result->col0, c, s, 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col1, -s, c, 0.0f, 0.0f ); vmathV4MakeZAxis( &result->col2 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ ) { float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sX = sinf( radiansXYZ->x ); cX = cosf( radiansXYZ->x ); sY = sinf( radiansXYZ->y ); cY = cosf( radiansXYZ->y ); sZ = sinf( radiansXYZ->z ); cZ = cosf( radiansXYZ->z ); tmp0 = ( cZ * sY ); tmp1 = ( sZ * sY ); vmathV4MakeFromElems( &result->col0, ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ); vmathV4MakeFromElems( &result->col1, ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ); vmathV4MakeFromElems( &result->col2, ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec ) { float x, y, z, s, c, oneMinusC, xy, yz, zx; s = sinf( radians ); c = cosf( radians ); x = unitVec->x; y = unitVec->y; z = unitVec->z; xy = ( x * y ); yz = ( y * z ); zx = ( z * x ); oneMinusC = ( 1.0f - c ); vmathV4MakeFromElems( &result->col0, ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ); vmathV4MakeFromElems( &result->col1, ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ); vmathV4MakeFromElems( &result->col2, ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat ) { VmathTransform3 tmpT3_0; vmathT3MakeRotationQ( &tmpT3_0, unitQuat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec ) { vmathV4MakeFromElems( &result->col0, scaleVec->x, 0.0f, 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col1, 0.0f, scaleVec->y, 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col2, 0.0f, 0.0f, scaleVec->z, 0.0f ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec ) { vmathV4ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) ); vmathV4ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) ); vmathV4ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) ); vmathV4Copy( &result->col3, &mat->col3 ); } static inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat ) { VmathVector4 scale4; vmathV4MakeFromV3Scalar( &scale4, scaleVec, 1.0f ); vmathV4MulPerElem( &result->col0, &mat->col0, &scale4 ); vmathV4MulPerElem( &result->col1, &mat->col1, &scale4 ); vmathV4MulPerElem( &result->col2, &mat->col2, &scale4 ); vmathV4MulPerElem( &result->col3, &mat->col3, &scale4 ); } static inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ) { vmathV4MakeXAxis( &result->col0 ); vmathV4MakeYAxis( &result->col1 ); vmathV4MakeZAxis( &result->col2 ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec ) { VmathMatrix4 m4EyeFrame; VmathVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1; VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; vmathV3Normalize( &v3Y, upVec ); vmathP3Sub( &tmpV3_0, eyePos, lookAtPos ); vmathV3Normalize( &v3Z, &tmpV3_0 ); vmathV3Cross( &tmpV3_1, &v3Y, &v3Z ); vmathV3Normalize( &v3X, &tmpV3_1 ); vmathV3Cross( &v3Y, &v3Z, &v3X ); vmathV4MakeFromV3( &tmpV4_0, &v3X ); vmathV4MakeFromV3( &tmpV4_1, &v3Y ); vmathV4MakeFromV3( &tmpV4_2, &v3Z ); vmathV4MakeFromP3( &tmpV4_3, eyePos ); vmathM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 ); vmathM4OrthoInverse( result, &m4EyeFrame ); } static inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar ) { float f, rangeInv; f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) ); rangeInv = ( 1.0f / ( zNear - zFar ) ); vmathV4MakeFromElems( &result->col0, ( f / aspect ), 0.0f, 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col1, 0.0f, f, 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col2, 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ); vmathV4MakeFromElems( &result->col3, 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f ); } static inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ) { float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; sum_rl = ( right + left ); sum_tb = ( top + bottom ); sum_nf = ( zNear + zFar ); inv_rl = ( 1.0f / ( right - left ) ); inv_tb = ( 1.0f / ( top - bottom ) ); inv_nf = ( 1.0f / ( zNear - zFar ) ); n2 = ( zNear + zNear ); vmathV4MakeFromElems( &result->col0, ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col1, 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col2, ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ); vmathV4MakeFromElems( &result->col3, 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f ); } static inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ) { float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; sum_rl = ( right + left ); sum_tb = ( top + bottom ); sum_nf = ( zNear + zFar ); inv_rl = ( 1.0f / ( right - left ) ); inv_tb = ( 1.0f / ( top - bottom ) ); inv_nf = ( 1.0f / ( zNear - zFar ) ); vmathV4MakeFromElems( &result->col0, ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col1, 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ); vmathV4MakeFromElems( &result->col2, 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ); vmathV4MakeFromElems( &result->col3, ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f ); } static inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 ) { vmathV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); vmathV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathM4Print( const VmathMatrix4 *mat ) { VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; vmathM4GetRow( &tmpV4_0, mat, 0 ); vmathV4Print( &tmpV4_0 ); vmathM4GetRow( &tmpV4_1, mat, 1 ); vmathV4Print( &tmpV4_1 ); vmathM4GetRow( &tmpV4_2, mat, 2 ); vmathV4Print( &tmpV4_2 ); vmathM4GetRow( &tmpV4_3, mat, 3 ); vmathV4Print( &tmpV4_3 ); } static inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name ) { printf("%s:\n", name); vmathM4Print( mat ); } #endif static inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( &result->col0, &tfrm->col0 ); vmathV3Copy( &result->col1, &tfrm->col1 ); vmathV3Copy( &result->col2, &tfrm->col2 ); vmathV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar ) { vmathV3MakeFromScalar( &result->col0, scalar ); vmathV3MakeFromScalar( &result->col1, scalar ); vmathV3MakeFromScalar( &result->col2, scalar ); vmathV3MakeFromScalar( &result->col3, scalar ); } static inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2, const VmathVector3 *_col3 ) { vmathV3Copy( &result->col0, _col0 ); vmathV3Copy( &result->col1, _col1 ); vmathV3Copy( &result->col2, _col2 ); vmathV3Copy( &result->col3, _col3 ); } static inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec ) { vmathT3SetUpper3x3( result, tfrm ); vmathT3SetTranslation( result, translateVec ); } static inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ) { VmathMatrix3 tmpM3_0; vmathM3MakeFromQ( &tmpM3_0, unitQuat ); vmathT3SetUpper3x3( result, &tmpM3_0 ); vmathT3SetTranslation( result, translateVec ); } static inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *_col0 ) { vmathV3Copy( &result->col0, _col0 ); } static inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *_col1 ) { vmathV3Copy( &result->col1, _col1 ); } static inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col2, _col2 ); } static inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *_col3 ) { vmathV3Copy( &result->col3, _col3 ); } static inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec ) { vmathV3Copy( (&result->col0 + col), vec ); } static inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec ) { vmathV3SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) ); vmathV3SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) ); vmathV3SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) ); vmathV3SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) ); } static inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val ) { VmathVector3 tmpV3_0; vmathT3GetCol( &tmpV3_0, result, col ); vmathV3SetElem( &tmpV3_0, row, val ); vmathT3SetCol( result, col, &tmpV3_0 ); } static inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row ) { VmathVector3 tmpV3_0; vmathT3GetCol( &tmpV3_0, tfrm, col ); return vmathV3GetElem( &tmpV3_0, row ); } static inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col0 ); } static inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col1 ); } static inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col2 ); } static inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col3 ); } static inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col ) { vmathV3Copy( result, (&tfrm->col0 + col) ); } static inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row ) { vmathV4MakeFromElems( result, vmathV3GetElem( &tfrm->col0, row ), vmathV3GetElem( &tfrm->col1, row ), vmathV3GetElem( &tfrm->col2, row ), vmathV3GetElem( &tfrm->col3, row ) ); } static inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm ) { VmathVector3 tmp0, tmp1, tmp2, inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5; float detinv; vmathV3Cross( &tmp0, &tfrm->col1, &tfrm->col2 ); vmathV3Cross( &tmp1, &tfrm->col2, &tfrm->col0 ); vmathV3Cross( &tmp2, &tfrm->col0, &tfrm->col1 ); detinv = ( 1.0f / vmathV3Dot( &tfrm->col2, &tmp2 ) ); vmathV3MakeFromElems( &inv0, ( tmp0.x * detinv ), ( tmp1.x * detinv ), ( tmp2.x * detinv ) ); vmathV3MakeFromElems( &inv1, ( tmp0.y * detinv ), ( tmp1.y * detinv ), ( tmp2.y * detinv ) ); vmathV3MakeFromElems( &inv2, ( tmp0.z * detinv ), ( tmp1.z * detinv ), ( tmp2.z * detinv ) ); vmathV3Copy( &result->col0, &inv0 ); vmathV3Copy( &result->col1, &inv1 ); vmathV3Copy( &result->col2, &inv2 ); vmathV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x ); vmathV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y ); vmathV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z ); vmathV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 ); vmathV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 ); vmathV3Neg( &tmpV3_5, &tmpV3_4 ); vmathV3Copy( &result->col3, &tmpV3_5 ); } static inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm ) { VmathVector3 inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5; vmathV3MakeFromElems( &inv0, tfrm->col0.x, tfrm->col1.x, tfrm->col2.x ); vmathV3MakeFromElems( &inv1, tfrm->col0.y, tfrm->col1.y, tfrm->col2.y ); vmathV3MakeFromElems( &inv2, tfrm->col0.z, tfrm->col1.z, tfrm->col2.z ); vmathV3Copy( &result->col0, &inv0 ); vmathV3Copy( &result->col1, &inv1 ); vmathV3Copy( &result->col2, &inv2 ); vmathV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x ); vmathV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y ); vmathV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z ); vmathV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 ); vmathV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 ); vmathV3Neg( &tmpV3_5, &tmpV3_4 ); vmathV3Copy( &result->col3, &tmpV3_5 ); } static inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vmathV3AbsPerElem( &result->col0, &tfrm->col0 ); vmathV3AbsPerElem( &result->col1, &tfrm->col1 ); vmathV3AbsPerElem( &result->col2, &tfrm->col2 ); vmathV3AbsPerElem( &result->col3, &tfrm->col3 ); } static inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec ) { float tmpX, tmpY, tmpZ; tmpX = ( ( ( tfrm->col0.x * vec->x ) + ( tfrm->col1.x * vec->y ) ) + ( tfrm->col2.x * vec->z ) ); tmpY = ( ( ( tfrm->col0.y * vec->x ) + ( tfrm->col1.y * vec->y ) ) + ( tfrm->col2.y * vec->z ) ); tmpZ = ( ( ( tfrm->col0.z * vec->x ) + ( tfrm->col1.z * vec->y ) ) + ( tfrm->col2.z * vec->z ) ); vmathV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt ) { float tmpX, tmpY, tmpZ; tmpX = ( ( ( ( tfrm->col0.x * pnt->x ) + ( tfrm->col1.x * pnt->y ) ) + ( tfrm->col2.x * pnt->z ) ) + tfrm->col3.x ); tmpY = ( ( ( ( tfrm->col0.y * pnt->x ) + ( tfrm->col1.y * pnt->y ) ) + ( tfrm->col2.y * pnt->z ) ) + tfrm->col3.y ); tmpZ = ( ( ( ( tfrm->col0.z * pnt->x ) + ( tfrm->col1.z * pnt->y ) ) + ( tfrm->col2.z * pnt->z ) ) + tfrm->col3.z ); vmathP3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ) { VmathTransform3 tmpResult; VmathPoint3 tmpP3_0, tmpP3_1; vmathT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 ); vmathT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 ); vmathT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 ); vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 ); vmathV3MakeFromP3( &tmpResult.col3, &tmpP3_1 ); vmathT3Copy( result, &tmpResult ); } static inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ) { vmathV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 ); vmathV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 ); vmathV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 ); vmathV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 ); } static inline void vmathT3MakeIdentity( VmathTransform3 *result ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *tfrm ) { vmathV3Copy( &result->col0, &tfrm->col0 ); vmathV3Copy( &result->col1, &tfrm->col1 ); vmathV3Copy( &result->col2, &tfrm->col2 ); } static inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm ) { vmathM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 ); } static inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ) { vmathV3Copy( &result->col3, translateVec ); } static inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col3 ); } static inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV3MakeXAxis( &result->col0 ); vmathV3MakeFromElems( &result->col1, 0.0f, c, s ); vmathV3MakeFromElems( &result->col2, 0.0f, -s, c ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV3MakeFromElems( &result->col0, c, 0.0f, -s ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeFromElems( &result->col2, s, 0.0f, c ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); vmathV3MakeFromElems( &result->col0, c, s, 0.0f ); vmathV3MakeFromElems( &result->col1, -s, c, 0.0f ); vmathV3MakeZAxis( &result->col2 ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ ) { float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sX = sinf( radiansXYZ->x ); cX = cosf( radiansXYZ->x ); sY = sinf( radiansXYZ->y ); cY = cosf( radiansXYZ->y ); sZ = sinf( radiansXYZ->z ); cZ = cosf( radiansXYZ->z ); tmp0 = ( cZ * sY ); tmp1 = ( sZ * sY ); vmathV3MakeFromElems( &result->col0, ( cZ * cY ), ( sZ * cY ), -sY ); vmathV3MakeFromElems( &result->col1, ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ); vmathV3MakeFromElems( &result->col2, ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec ) { VmathMatrix3 tmpM3_0; VmathVector3 tmpV3_0; vmathM3MakeRotationAxis( &tmpM3_0, radians, unitVec ); vmathV3MakeFromScalar( &tmpV3_0, 0.0f ); vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat ) { VmathMatrix3 tmpM3_0; VmathVector3 tmpV3_0; vmathM3MakeFromQ( &tmpM3_0, unitQuat ); vmathV3MakeFromScalar( &tmpV3_0, 0.0f ); vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec ) { vmathV3MakeFromElems( &result->col0, scaleVec->x, 0.0f, 0.0f ); vmathV3MakeFromElems( &result->col1, 0.0f, scaleVec->y, 0.0f ); vmathV3MakeFromElems( &result->col2, 0.0f, 0.0f, scaleVec->z ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec ) { vmathV3ScalarMul( &result->col0, &tfrm->col0, vmathV3GetX( scaleVec ) ); vmathV3ScalarMul( &result->col1, &tfrm->col1, vmathV3GetY( scaleVec ) ); vmathV3ScalarMul( &result->col2, &tfrm->col2, vmathV3GetZ( scaleVec ) ); vmathV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm ) { vmathV3MulPerElem( &result->col0, &tfrm->col0, scaleVec ); vmathV3MulPerElem( &result->col1, &tfrm->col1, scaleVec ); vmathV3MulPerElem( &result->col2, &tfrm->col2, scaleVec ); vmathV3MulPerElem( &result->col3, &tfrm->col3, scaleVec ); } static inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); vmathV3Copy( &result->col3, translateVec ); } static inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 ) { vmathV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 ); vmathV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 ); vmathV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 ); vmathV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathT3Print( const VmathTransform3 *tfrm ) { VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2; vmathT3GetRow( &tmpV4_0, tfrm, 0 ); vmathV4Print( &tmpV4_0 ); vmathT3GetRow( &tmpV4_1, tfrm, 1 ); vmathV4Print( &tmpV4_1 ); vmathT3GetRow( &tmpV4_2, tfrm, 2 ); vmathV4Print( &tmpV4_2 ); } static inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name ) { printf("%s:\n", name); vmathT3Print( tfrm ); } #endif static inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *tfrm ) { float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; int negTrace, ZgtX, ZgtY, YgtX; int largestXorY, largestYorZ, largestZorX; xx = tfrm->col0.x; yx = tfrm->col0.y; zx = tfrm->col0.z; xy = tfrm->col1.x; yy = tfrm->col1.y; zy = tfrm->col1.z; xz = tfrm->col2.x; yz = tfrm->col2.y; zz = tfrm->col2.z; trace = ( ( xx + yy ) + zz ); negTrace = ( trace < 0.0f ); ZgtX = zz > xx; ZgtY = zz > yy; YgtX = yy > xx; largestXorY = ( !ZgtX || !ZgtY ) && negTrace; largestYorZ = ( YgtX || ZgtX ) && negTrace; largestZorX = ( ZgtY || !YgtX ) && negTrace; if ( largestXorY ) { zz = -zz; xy = -xy; } if ( largestYorZ ) { xx = -xx; yz = -yz; } if ( largestZorX ) { yy = -yy; zx = -zx; } radicand = ( ( ( xx + yy ) + zz ) + 1.0f ); scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) ); tmpx = ( ( zy - yz ) * scale ); tmpy = ( ( xz - zx ) * scale ); tmpz = ( ( yx - xy ) * scale ); tmpw = ( radicand * scale ); qx = tmpx; qy = tmpy; qz = tmpz; qw = tmpw; if ( largestXorY ) { qx = tmpw; qy = tmpz; qz = tmpy; qw = tmpx; } if ( largestYorZ ) { tmpx = qx; tmpz = qz; qx = qy; qy = tmpx; qz = qw; qw = tmpz; } result->x = qx; result->y = qy; result->z = qz; result->w = qw; } static inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *tfrm0, const VmathVector3 *tfrm1 ) { vmathV3ScalarMul( &result->col0, tfrm0, vmathV3GetX( tfrm1 ) ); vmathV3ScalarMul( &result->col1, tfrm0, vmathV3GetY( tfrm1 ) ); vmathV3ScalarMul( &result->col2, tfrm0, vmathV3GetZ( tfrm1 ) ); } static inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *tfrm0, const VmathVector4 *tfrm1 ) { vmathV4ScalarMul( &result->col0, tfrm0, vmathV4GetX( tfrm1 ) ); vmathV4ScalarMul( &result->col1, tfrm0, vmathV4GetY( tfrm1 ) ); vmathV4ScalarMul( &result->col2, tfrm0, vmathV4GetZ( tfrm1 ) ); vmathV4ScalarMul( &result->col3, tfrm0, vmathV4GetW( tfrm1 ) ); } static inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ) { float tmpX, tmpY, tmpZ; tmpX = ( ( ( vec->x * mat->col0.x ) + ( vec->y * mat->col0.y ) ) + ( vec->z * mat->col0.z ) ); tmpY = ( ( ( vec->x * mat->col1.x ) + ( vec->y * mat->col1.y ) ) + ( vec->z * mat->col1.z ) ); tmpZ = ( ( ( vec->x * mat->col2.x ) + ( vec->y * mat->col2.y ) ) + ( vec->z * mat->col2.z ) ); vmathV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec ) { vmathV3MakeFromElems( &result->col0, 0.0f, vec->z, -vec->y ); vmathV3MakeFromElems( &result->col1, -vec->z, 0.0f, vec->x ); vmathV3MakeFromElems( &result->col2, vec->y, -vec->x, 0.0f ); } static inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2; vmathV3Cross( &tmpV3_0, vec, &mat->col0 ); vmathV3Cross( &tmpV3_1, vec, &mat->col1 ); vmathV3Cross( &tmpV3_2, vec, &mat->col2 ); vmathM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 ); } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/scalar/c/mat_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_V_C_H #define _VECTORMATH_MAT_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants */ #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar ) { VmathMatrix3 result; vmathM3MakeFromScalar(&result, scalar); return result; } static inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat ) { VmathMatrix3 result; vmathM3MakeFromQ(&result, &unitQuat); return result; } static inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2 ) { VmathMatrix3 result; vmathM3MakeFromCols(&result, &_col0, &_col1, &_col2); return result; } static inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 _col0 ) { vmathM3SetCol0(result, &_col0); } static inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 _col1 ) { vmathM3SetCol1(result, &_col1); } static inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 _col2 ) { vmathM3SetCol2(result, &_col2); } static inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec ) { vmathM3SetCol(result, col, &vec); } static inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec ) { vmathM3SetRow(result, row, &vec); } static inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val ) { vmathM3SetElem(result, col, row, val); } static inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row ) { return vmathM3GetElem(&mat, col, row); } static inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol0(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol1(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol2(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col ) { VmathVector3 result; vmathM3GetCol(&result, &mat, col); return result; } static inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row ) { VmathVector3 result; vmathM3GetRow(&result, &mat, row); return result; } static inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Transpose(&result, &mat); return result; } static inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Inverse(&result, &mat); return result; } static inline float vmathM3Determinant_V( VmathMatrix3 mat ) { return vmathM3Determinant(&mat); } static inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Add(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Sub(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Neg(&result, &mat); return result; } static inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3AbsPerElem(&result, &mat); return result; } static inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar ) { VmathMatrix3 result; vmathM3ScalarMul(&result, &mat, scalar); return result; } static inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec ) { VmathVector3 result; vmathM3MulV3(&result, &mat, &vec); return result; } static inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Mul(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3MakeIdentity_V( ) { VmathMatrix3 result; vmathM3MakeIdentity(&result); return result; } static inline VmathMatrix3 vmathM3MakeRotationX_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationX(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationY_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationY(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationZ(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathMatrix3 result; vmathM3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathMatrix3 result; vmathM3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat ) { VmathMatrix3 result; vmathM3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec ) { VmathMatrix3 result; vmathM3MakeScale(&result, &scaleVec); return result; } static inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec ) { VmathMatrix3 result; vmathM3AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 ) { VmathMatrix3 result; vmathM3Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathM3Print_V( VmathMatrix3 mat ) { vmathM3Print(&mat); } static inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name ) { vmathM3Prints(&mat, name); } #endif static inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar ) { VmathMatrix4 result; vmathM4MakeFromScalar(&result, scalar); return result; } static inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat ) { VmathMatrix4 result; vmathM4MakeFromT3(&result, &mat); return result; } static inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 _col0, VmathVector4 _col1, VmathVector4 _col2, VmathVector4 _col3 ) { VmathMatrix4 result; vmathM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeFromM3V3(&result, &mat, &translateVec); return result; } static inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 _col0 ) { vmathM4SetCol0(result, &_col0); } static inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 _col1 ) { vmathM4SetCol1(result, &_col1); } static inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 _col2 ) { vmathM4SetCol2(result, &_col2); } static inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 _col3 ) { vmathM4SetCol3(result, &_col3); } static inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec ) { vmathM4SetCol(result, col, &vec); } static inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec ) { vmathM4SetRow(result, row, &vec); } static inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val ) { vmathM4SetElem(result, col, row, val); } static inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row ) { return vmathM4GetElem(&mat, col, row); } static inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol0(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol1(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol2(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol3(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col ) { VmathVector4 result; vmathM4GetCol(&result, &mat, col); return result; } static inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row ) { VmathVector4 result; vmathM4GetRow(&result, &mat, row); return result; } static inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Transpose(&result, &mat); return result; } static inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Inverse(&result, &mat); return result; } static inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4AffineInverse(&result, &mat); return result; } static inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4OrthoInverse(&result, &mat); return result; } static inline float vmathM4Determinant_V( VmathMatrix4 mat ) { return vmathM4Determinant(&mat); } static inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Add(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Sub(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Neg(&result, &mat); return result; } static inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4AbsPerElem(&result, &mat); return result; } static inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar ) { VmathMatrix4 result; vmathM4ScalarMul(&result, &mat, scalar); return result; } static inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec ) { VmathVector4 result; vmathM4MulV4(&result, &mat, &vec); return result; } static inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec ) { VmathVector4 result; vmathM4MulV3(&result, &mat, &vec); return result; } static inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt ) { VmathVector4 result; vmathM4MulP3(&result, &mat, &pnt); return result; } static inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Mul(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm1 ) { VmathMatrix4 result; vmathM4MulT3(&result, &mat, &tfrm1); return result; } static inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4MakeIdentity_V( ) { VmathMatrix4 result; vmathM4MakeIdentity(&result); return result; } static inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 ) { vmathM4SetUpper3x3(result, &mat3); } static inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat ) { VmathMatrix3 result; vmathM4GetUpper3x3(&result, &mat); return result; } static inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec ) { vmathM4SetTranslation(result, &translateVec); } static inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat ) { VmathVector3 result; vmathM4GetTranslation(&result, &mat); return result; } static inline VmathMatrix4 vmathM4MakeRotationX_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationX(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationY_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationY(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationZ(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathMatrix4 result; vmathM4MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathMatrix4 result; vmathM4MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat ) { VmathMatrix4 result; vmathM4MakeRotationQ(&result, &unitQuat); return result; } static inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec ) { VmathMatrix4 result; vmathM4MakeScale(&result, &scaleVec); return result; } static inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec ) { VmathMatrix4 result; vmathM4AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeTranslation(&result, &translateVec); return result; } static inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec ) { VmathMatrix4 result; vmathM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec); return result; } static inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 ) { VmathMatrix4 result; vmathM4Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathM4Print_V( VmathMatrix4 mat ) { vmathM4Print(&mat); } static inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name ) { vmathM4Prints(&mat, name); } #endif static inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar ) { VmathTransform3 result; vmathT3MakeFromScalar(&result, scalar); return result; } static inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2, VmathVector3 _col3 ) { VmathTransform3 result; vmathT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeFromM3V3(&result, &tfrm, &translateVec); return result; } static inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 _col0 ) { vmathT3SetCol0(result, &_col0); } static inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 _col1 ) { vmathT3SetCol1(result, &_col1); } static inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 _col2 ) { vmathT3SetCol2(result, &_col2); } static inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 _col3 ) { vmathT3SetCol3(result, &_col3); } static inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec ) { vmathT3SetCol(result, col, &vec); } static inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec ) { vmathT3SetRow(result, row, &vec); } static inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val ) { vmathT3SetElem(result, col, row, val); } static inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row ) { return vmathT3GetElem(&tfrm, col, row); } static inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol0(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol1(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol2(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol3(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col ) { VmathVector3 result; vmathT3GetCol(&result, &tfrm, col); return result; } static inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row ) { VmathVector4 result; vmathT3GetRow(&result, &tfrm, row); return result; } static inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3Inverse(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3OrthoInverse(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3AbsPerElem(&result, &tfrm); return result; } static inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec ) { VmathVector3 result; vmathT3MulV3(&result, &tfrm, &vec); return result; } static inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt ) { VmathPoint3 result; vmathT3MulP3(&result, &tfrm, &pnt); return result; } static inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ) { VmathTransform3 result; vmathT3Mul(&result, &tfrm0, &tfrm1); return result; } static inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ) { VmathTransform3 result; vmathT3MulPerElem(&result, &tfrm0, &tfrm1); return result; } static inline VmathTransform3 vmathT3MakeIdentity_V( ) { VmathTransform3 result; vmathT3MakeIdentity(&result); return result; } static inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 tfrm ) { vmathT3SetUpper3x3(result, &tfrm); } static inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm ) { VmathMatrix3 result; vmathT3GetUpper3x3(&result, &tfrm); return result; } static inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec ) { vmathT3SetTranslation(result, &translateVec); } static inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetTranslation(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3MakeRotationX_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationX(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationY_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationY(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationZ_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationZ(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathTransform3 result; vmathT3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathTransform3 result; vmathT3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat ) { VmathTransform3 result; vmathT3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec ) { VmathTransform3 result; vmathT3MakeScale(&result, &scaleVec); return result; } static inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec ) { VmathTransform3 result; vmathT3AppendScale(&result, &tfrm, &scaleVec); return result; } static inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3PrependScale(&result, &scaleVec, &tfrm); return result; } static inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeTranslation(&result, &translateVec); return result; } static inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 ) { VmathTransform3 result; vmathT3Select(&result, &tfrm0, &tfrm1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathT3Print_V( VmathTransform3 tfrm ) { vmathT3Print(&tfrm); } static inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name ) { vmathT3Prints(&tfrm, name); } #endif static inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 tfrm ) { VmathQuat result; vmathQMakeFromM3(&result, &tfrm); return result; } static inline VmathMatrix3 vmathV3Outer_V( VmathVector3 tfrm0, VmathVector3 tfrm1 ) { VmathMatrix3 result; vmathV3Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathMatrix4 vmathV4Outer_V( VmathVector4 tfrm0, VmathVector4 tfrm1 ) { VmathMatrix4 result; vmathV4Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat ) { VmathVector3 result; vmathV3RowMul(&result, &vec, &mat); return result; } static inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec ) { VmathMatrix3 result; vmathV3CrossMatrix(&result, &vec); return result; } static inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat ) { VmathMatrix3 result; vmathV3CrossMatrixMul(&result, &vec, &mat); return result; } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/scalar/c/quat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_C_H #define _VECTORMATH_QUAT_AOS_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat ) { result->x = quat->x; result->y = quat->y; result->z = quat->z; result->w = quat->w; } static inline void vmathQMakeFromElems( VmathQuat *result, float _x, float _y, float _z, float _w ) { result->x = _x; result->y = _y; result->z = _z; result->w = _w; } static inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float _w ) { vmathQSetXYZ( result, xyz ); vmathQSetW( result, _w ); } static inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = vec->w; } static inline void vmathQMakeFromScalar( VmathQuat *result, float scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; result->w = scalar; } static inline void vmathQMakeIdentity( VmathQuat *result ) { vmathQMakeFromElems( result, 0.0f, 0.0f, 0.0f, 1.0f ); } static inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 ) { VmathQuat tmpQ_0, tmpQ_1; vmathQSub( &tmpQ_0, quat1, quat0 ); vmathQScalarMul( &tmpQ_1, &tmpQ_0, t ); vmathQAdd( result, quat0, &tmpQ_1 ); } static inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 ) { VmathQuat start, tmpQ_0, tmpQ_1; float recipSinAngle, scale0, scale1, cosAngle, angle; cosAngle = vmathQDot( unitQuat0, unitQuat1 ); if ( cosAngle < 0.0f ) { cosAngle = -cosAngle; vmathQNeg( &start, unitQuat0 ); } else { vmathQCopy( &start, unitQuat0 ); } if ( cosAngle < _VECTORMATH_SLERP_TOL ) { angle = acosf( cosAngle ); recipSinAngle = ( 1.0f / sinf( angle ) ); scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); } else { scale0 = ( 1.0f - t ); scale1 = t; } vmathQScalarMul( &tmpQ_0, &start, scale0 ); vmathQScalarMul( &tmpQ_1, unitQuat1, scale1 ); vmathQAdd( result, &tmpQ_0, &tmpQ_1 ); } static inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 ) { VmathQuat tmp0, tmp1; vmathQSlerp( &tmp0, t, unitQuat0, unitQuat3 ); vmathQSlerp( &tmp1, t, unitQuat1, unitQuat2 ); vmathQSlerp( result, ( ( 2.0f * t ) * ( 1.0f - t ) ), &tmp0, &tmp1 ); } static inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat ) { vmathV3MakeFromElems( result, quat->x, quat->y, quat->z ); } static inline void vmathQSetX( VmathQuat *result, float _x ) { result->x = _x; } static inline float vmathQGetX( const VmathQuat *quat ) { return quat->x; } static inline void vmathQSetY( VmathQuat *result, float _y ) { result->y = _y; } static inline float vmathQGetY( const VmathQuat *quat ) { return quat->y; } static inline void vmathQSetZ( VmathQuat *result, float _z ) { result->z = _z; } static inline float vmathQGetZ( const VmathQuat *quat ) { return quat->z; } static inline void vmathQSetW( VmathQuat *result, float _w ) { result->w = _w; } static inline float vmathQGetW( const VmathQuat *quat ) { return quat->w; } static inline void vmathQSetElem( VmathQuat *result, int idx, float value ) { *(&result->x + idx) = value; } static inline float vmathQGetElem( const VmathQuat *quat, int idx ) { return *(&quat->x + idx); } static inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { result->x = ( quat0->x + quat1->x ); result->y = ( quat0->y + quat1->y ); result->z = ( quat0->z + quat1->z ); result->w = ( quat0->w + quat1->w ); } static inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { result->x = ( quat0->x - quat1->x ); result->y = ( quat0->y - quat1->y ); result->z = ( quat0->z - quat1->z ); result->w = ( quat0->w - quat1->w ); } static inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar ) { result->x = ( quat->x * scalar ); result->y = ( quat->y * scalar ); result->z = ( quat->z * scalar ); result->w = ( quat->w * scalar ); } static inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar ) { result->x = ( quat->x / scalar ); result->y = ( quat->y / scalar ); result->z = ( quat->z / scalar ); result->w = ( quat->w / scalar ); } static inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat ) { result->x = -quat->x; result->y = -quat->y; result->z = -quat->z; result->w = -quat->w; } static inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 ) { float result; result = ( quat0->x * quat1->x ); result = ( result + ( quat0->y * quat1->y ) ); result = ( result + ( quat0->z * quat1->z ) ); result = ( result + ( quat0->w * quat1->w ) ); return result; } static inline float vmathQNorm( const VmathQuat *quat ) { float result; result = ( quat->x * quat->x ); result = ( result + ( quat->y * quat->y ) ); result = ( result + ( quat->z * quat->z ) ); result = ( result + ( quat->w * quat->w ) ); return result; } static inline float vmathQLength( const VmathQuat *quat ) { return sqrtf( vmathQNorm( quat ) ); } static inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat ) { float lenSqr, lenInv; lenSqr = vmathQNorm( quat ); lenInv = ( 1.0f / sqrtf( lenSqr ) ); result->x = ( quat->x * lenInv ); result->y = ( quat->y * lenInv ); result->z = ( quat->z * lenInv ); result->w = ( quat->w * lenInv ); } static inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ) { VmathVector3 tmpV3_0, tmpV3_1; float cosHalfAngleX2, recipCosHalfAngleX2; cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + vmathV3Dot( unitVec0, unitVec1 ) ) ) ); recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); vmathV3Cross( &tmpV3_0, unitVec0, unitVec1 ); vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, recipCosHalfAngleX2 ); vmathQMakeFromV3Scalar( result, &tmpV3_1, ( cosHalfAngleX2 * 0.5f ) ); } static inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec ) { VmathVector3 tmpV3_0; float s, c, angle; angle = ( radians * 0.5f ); s = sinf( angle ); c = cosf( angle ); vmathV3ScalarMul( &tmpV3_0, unitVec, s ); vmathQMakeFromV3Scalar( result, &tmpV3_0, c ); } static inline void vmathQMakeRotationX( VmathQuat *result, float radians ) { float s, c, angle; angle = ( radians * 0.5f ); s = sinf( angle ); c = cosf( angle ); vmathQMakeFromElems( result, s, 0.0f, 0.0f, c ); } static inline void vmathQMakeRotationY( VmathQuat *result, float radians ) { float s, c, angle; angle = ( radians * 0.5f ); s = sinf( angle ); c = cosf( angle ); vmathQMakeFromElems( result, 0.0f, s, 0.0f, c ); } static inline void vmathQMakeRotationZ( VmathQuat *result, float radians ) { float s, c, angle; angle = ( radians * 0.5f ); s = sinf( angle ); c = cosf( angle ); vmathQMakeFromElems( result, 0.0f, 0.0f, s, c ); } static inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { float tmpX, tmpY, tmpZ, tmpW; tmpX = ( ( ( ( quat0->w * quat1->x ) + ( quat0->x * quat1->w ) ) + ( quat0->y * quat1->z ) ) - ( quat0->z * quat1->y ) ); tmpY = ( ( ( ( quat0->w * quat1->y ) + ( quat0->y * quat1->w ) ) + ( quat0->z * quat1->x ) ) - ( quat0->x * quat1->z ) ); tmpZ = ( ( ( ( quat0->w * quat1->z ) + ( quat0->z * quat1->w ) ) + ( quat0->x * quat1->y ) ) - ( quat0->y * quat1->x ) ); tmpW = ( ( ( ( quat0->w * quat1->w ) - ( quat0->x * quat1->x ) ) - ( quat0->y * quat1->y ) ) - ( quat0->z * quat1->z ) ); vmathQMakeFromElems( result, tmpX, tmpY, tmpZ, tmpW ); } static inline void vmathQRotate( VmathVector3 *result, const VmathQuat *quat, const VmathVector3 *vec ) { float tmpX, tmpY, tmpZ, tmpW; tmpX = ( ( ( quat->w * vec->x ) + ( quat->y * vec->z ) ) - ( quat->z * vec->y ) ); tmpY = ( ( ( quat->w * vec->y ) + ( quat->z * vec->x ) ) - ( quat->x * vec->z ) ); tmpZ = ( ( ( quat->w * vec->z ) + ( quat->x * vec->y ) ) - ( quat->y * vec->x ) ); tmpW = ( ( ( quat->x * vec->x ) + ( quat->y * vec->y ) ) + ( quat->z * vec->z ) ); result->x = ( ( ( ( tmpW * quat->x ) + ( tmpX * quat->w ) ) - ( tmpY * quat->z ) ) + ( tmpZ * quat->y ) ); result->y = ( ( ( ( tmpW * quat->y ) + ( tmpY * quat->w ) ) - ( tmpZ * quat->x ) ) + ( tmpX * quat->z ) ); result->z = ( ( ( ( tmpW * quat->z ) + ( tmpZ * quat->w ) ) - ( tmpX * quat->y ) ) + ( tmpY * quat->x ) ); } static inline void vmathQConj( VmathQuat *result, const VmathQuat *quat ) { vmathQMakeFromElems( result, -quat->x, -quat->y, -quat->z, quat->w ); } static inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 ) { result->x = ( select1 )? quat1->x : quat0->x; result->y = ( select1 )? quat1->y : quat0->y; result->z = ( select1 )? quat1->z : quat0->z; result->w = ( select1 )? quat1->w : quat0->w; } #ifdef _VECTORMATH_DEBUG static inline void vmathQPrint( const VmathQuat *quat ) { printf( "( %f %f %f %f )\n", quat->x, quat->y, quat->z, quat->w ); } static inline void vmathQPrints( const VmathQuat *quat, const char *name ) { printf( "%s: ( %f %f %f %f )\n", name, quat->x, quat->y, quat->z, quat->w ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/scalar/c/quat_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_V_C_H #define _VECTORMATH_QUAT_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathQuat vmathQMakeFromElems_V( float _x, float _y, float _z, float _w ) { VmathQuat result; vmathQMakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float _w ) { VmathQuat result; vmathQMakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec ) { VmathQuat result; vmathQMakeFromV4(&result, &vec); return result; } static inline VmathQuat vmathQMakeFromScalar_V( float scalar ) { VmathQuat result; vmathQMakeFromScalar(&result, scalar); return result; } static inline VmathQuat vmathQMakeIdentity_V( ) { VmathQuat result; vmathQMakeIdentity(&result); return result; } static inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQLerp(&result, t, &quat0, &quat1); return result; } static inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 ) { VmathQuat result; vmathQSlerp(&result, t, &unitQuat0, &unitQuat1); return result; } static inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 ) { VmathQuat result; vmathQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3); return result; } static inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec ) { vmathQSetXYZ(result, &vec); } static inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat ) { VmathVector3 result; vmathQGetXYZ(&result, &quat); return result; } static inline void vmathQSetX_V( VmathQuat *result, float _x ) { vmathQSetX(result, _x); } static inline float vmathQGetX_V( VmathQuat quat ) { return vmathQGetX(&quat); } static inline void vmathQSetY_V( VmathQuat *result, float _y ) { vmathQSetY(result, _y); } static inline float vmathQGetY_V( VmathQuat quat ) { return vmathQGetY(&quat); } static inline void vmathQSetZ_V( VmathQuat *result, float _z ) { vmathQSetZ(result, _z); } static inline float vmathQGetZ_V( VmathQuat quat ) { return vmathQGetZ(&quat); } static inline void vmathQSetW_V( VmathQuat *result, float _w ) { vmathQSetW(result, _w); } static inline float vmathQGetW_V( VmathQuat quat ) { return vmathQGetW(&quat); } static inline void vmathQSetElem_V( VmathQuat *result, int idx, float value ) { vmathQSetElem(result, idx, value); } static inline float vmathQGetElem_V( VmathQuat quat, int idx ) { return vmathQGetElem(&quat, idx); } static inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQAdd(&result, &quat0, &quat1); return result; } static inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQSub(&result, &quat0, &quat1); return result; } static inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar ) { VmathQuat result; vmathQScalarMul(&result, &quat, scalar); return result; } static inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar ) { VmathQuat result; vmathQScalarDiv(&result, &quat, scalar); return result; } static inline VmathQuat vmathQNeg_V( VmathQuat quat ) { VmathQuat result; vmathQNeg(&result, &quat); return result; } static inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 ) { return vmathQDot(&quat0, &quat1); } static inline float vmathQNorm_V( VmathQuat quat ) { return vmathQNorm(&quat); } static inline float vmathQLength_V( VmathQuat quat ) { return vmathQLength(&quat); } static inline VmathQuat vmathQNormalize_V( VmathQuat quat ) { VmathQuat result; vmathQNormalize(&result, &quat); return result; } static inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 ) { VmathQuat result; vmathQMakeRotationArc(&result, &unitVec0, &unitVec1); return result; } static inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathQuat result; vmathQMakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathQuat vmathQMakeRotationX_V( float radians ) { VmathQuat result; vmathQMakeRotationX(&result, radians); return result; } static inline VmathQuat vmathQMakeRotationY_V( float radians ) { VmathQuat result; vmathQMakeRotationY(&result, radians); return result; } static inline VmathQuat vmathQMakeRotationZ_V( float radians ) { VmathQuat result; vmathQMakeRotationZ(&result, radians); return result; } static inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQMul(&result, &quat0, &quat1); return result; } static inline VmathVector3 vmathQRotate_V( VmathQuat quat, VmathVector3 vec ) { VmathVector3 result; vmathQRotate(&result, &quat, &vec); return result; } static inline VmathQuat vmathQConj_V( VmathQuat quat ) { VmathQuat result; vmathQConj(&result, &quat); return result; } static inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 ) { VmathQuat result; vmathQSelect(&result, &quat0, &quat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathQPrint_V( VmathQuat quat ) { vmathQPrint(&quat); } static inline void vmathQPrints_V( VmathQuat quat, const char *name ) { vmathQPrints(&quat, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/scalar/c/vec_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_C_H #define _VECTORMATH_VEC_AOS_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants */ #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathV3MakeFromElems( VmathVector3 *result, float _x, float _y, float _z ) { result->x = _x; result->y = _y; result->z = _z; } static inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; } static inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; } static inline void vmathV3MakeXAxis( VmathVector3 *result ) { vmathV3MakeFromElems( result, 1.0f, 0.0f, 0.0f ); } static inline void vmathV3MakeYAxis( VmathVector3 *result ) { vmathV3MakeFromElems( result, 0.0f, 1.0f, 0.0f ); } static inline void vmathV3MakeZAxis( VmathVector3 *result ) { vmathV3MakeFromElems( result, 0.0f, 0.0f, 1.0f ); } static inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { VmathVector3 tmpV3_0, tmpV3_1; vmathV3Sub( &tmpV3_0, vec1, vec0 ); vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathV3Add( result, vec0, &tmpV3_1 ); } static inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ) { VmathVector3 tmpV3_0, tmpV3_1; float recipSinAngle, scale0, scale1, cosAngle, angle; cosAngle = vmathV3Dot( unitVec0, unitVec1 ); if ( cosAngle < _VECTORMATH_SLERP_TOL ) { angle = acosf( cosAngle ); recipSinAngle = ( 1.0f / sinf( angle ) ); scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); } else { scale0 = ( 1.0f - t ); scale1 = t; } vmathV3ScalarMul( &tmpV3_0, unitVec0, scale0 ); vmathV3ScalarMul( &tmpV3_1, unitVec1, scale1 ); vmathV3Add( result, &tmpV3_0, &tmpV3_1 ); } static inline void vmathV3SetX( VmathVector3 *result, float _x ) { result->x = _x; } static inline float vmathV3GetX( const VmathVector3 *vec ) { return vec->x; } static inline void vmathV3SetY( VmathVector3 *result, float _y ) { result->y = _y; } static inline float vmathV3GetY( const VmathVector3 *vec ) { return vec->y; } static inline void vmathV3SetZ( VmathVector3 *result, float _z ) { result->z = _z; } static inline float vmathV3GetZ( const VmathVector3 *vec ) { return vec->z; } static inline void vmathV3SetElem( VmathVector3 *result, int idx, float value ) { *(&result->x + idx) = value; } static inline float vmathV3GetElem( const VmathVector3 *vec, int idx ) { return *(&vec->x + idx); } static inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->x = ( vec0->x + vec1->x ); result->y = ( vec0->y + vec1->y ); result->z = ( vec0->z + vec1->z ); } static inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->x = ( vec0->x - vec1->x ); result->y = ( vec0->y - vec1->y ); result->z = ( vec0->z - vec1->z ); } static inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt1 ) { result->x = ( vec->x + pnt1->x ); result->y = ( vec->y + pnt1->y ); result->z = ( vec->z + pnt1->z ); } static inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar ) { result->x = ( vec->x * scalar ); result->y = ( vec->y * scalar ); result->z = ( vec->z * scalar ); } static inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar ) { result->x = ( vec->x / scalar ); result->y = ( vec->y / scalar ); result->z = ( vec->z / scalar ); } static inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec ) { result->x = -vec->x; result->y = -vec->y; result->z = -vec->z; } static inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->x = ( vec0->x * vec1->x ); result->y = ( vec0->y * vec1->y ); result->z = ( vec0->z * vec1->z ); } static inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->x = ( vec0->x / vec1->x ); result->y = ( vec0->y / vec1->y ); result->z = ( vec0->z / vec1->z ); } static inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->x = ( 1.0f / vec->x ); result->y = ( 1.0f / vec->y ); result->z = ( 1.0f / vec->z ); } static inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->x = sqrtf( vec->x ); result->y = sqrtf( vec->y ); result->z = sqrtf( vec->z ); } static inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->x = ( 1.0f / sqrtf( vec->x ) ); result->y = ( 1.0f / sqrtf( vec->y ) ); result->z = ( 1.0f / sqrtf( vec->z ) ); } static inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->x = fabsf( vec->x ); result->y = fabsf( vec->y ); result->z = fabsf( vec->z ); } static inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->x = ( vec1->x < 0.0f )? -fabsf( vec0->x ) : fabsf( vec0->x ); result->y = ( vec1->y < 0.0f )? -fabsf( vec0->y ) : fabsf( vec0->y ); result->z = ( vec1->z < 0.0f )? -fabsf( vec0->z ) : fabsf( vec0->z ); } static inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->x = (vec0->x > vec1->x)? vec0->x : vec1->x; result->y = (vec0->y > vec1->y)? vec0->y : vec1->y; result->z = (vec0->z > vec1->z)? vec0->z : vec1->z; } static inline float vmathV3MaxElem( const VmathVector3 *vec ) { float result; result = (vec->x > vec->y)? vec->x : vec->y; result = (vec->z > result)? vec->z : result; return result; } static inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->x = (vec0->x < vec1->x)? vec0->x : vec1->x; result->y = (vec0->y < vec1->y)? vec0->y : vec1->y; result->z = (vec0->z < vec1->z)? vec0->z : vec1->z; } static inline float vmathV3MinElem( const VmathVector3 *vec ) { float result; result = (vec->x < vec->y)? vec->x : vec->y; result = (vec->z < result)? vec->z : result; return result; } static inline float vmathV3Sum( const VmathVector3 *vec ) { float result; result = ( vec->x + vec->y ); result = ( result + vec->z ); return result; } static inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 ) { float result; result = ( vec0->x * vec1->x ); result = ( result + ( vec0->y * vec1->y ) ); result = ( result + ( vec0->z * vec1->z ) ); return result; } static inline float vmathV3LengthSqr( const VmathVector3 *vec ) { float result; result = ( vec->x * vec->x ); result = ( result + ( vec->y * vec->y ) ); result = ( result + ( vec->z * vec->z ) ); return result; } static inline float vmathV3Length( const VmathVector3 *vec ) { return sqrtf( vmathV3LengthSqr( vec ) ); } static inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec ) { float lenSqr, lenInv; lenSqr = vmathV3LengthSqr( vec ); lenInv = ( 1.0f / sqrtf( lenSqr ) ); result->x = ( vec->x * lenInv ); result->y = ( vec->y * lenInv ); result->z = ( vec->z * lenInv ); } static inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { float tmpX, tmpY, tmpZ; tmpX = ( ( vec0->y * vec1->z ) - ( vec0->z * vec1->y ) ); tmpY = ( ( vec0->z * vec1->x ) - ( vec0->x * vec1->z ) ); tmpZ = ( ( vec0->x * vec1->y ) - ( vec0->y * vec1->x ) ); vmathV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 ) { result->x = ( select1 )? vec1->x : vec0->x; result->y = ( select1 )? vec1->y : vec0->y; result->z = ( select1 )? vec1->z : vec0->z; } #ifdef _VECTORMATH_DEBUG static inline void vmathV3Print( const VmathVector3 *vec ) { printf( "( %f %f %f )\n", vec->x, vec->y, vec->z ); } static inline void vmathV3Prints( const VmathVector3 *vec, const char *name ) { printf( "%s: ( %f %f %f )\n", name, vec->x, vec->y, vec->z ); } #endif static inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = vec->w; } static inline void vmathV4MakeFromElems( VmathVector4 *result, float _x, float _y, float _z, float _w ) { result->x = _x; result->y = _y; result->z = _z; result->w = _w; } static inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float _w ) { vmathV4SetXYZ( result, xyz ); vmathV4SetW( result, _w ); } static inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = 0.0f; } static inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; result->w = 1.0f; } static inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat ) { result->x = quat->x; result->y = quat->y; result->z = quat->z; result->w = quat->w; } static inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; result->w = scalar; } static inline void vmathV4MakeXAxis( VmathVector4 *result ) { vmathV4MakeFromElems( result, 1.0f, 0.0f, 0.0f, 0.0f ); } static inline void vmathV4MakeYAxis( VmathVector4 *result ) { vmathV4MakeFromElems( result, 0.0f, 1.0f, 0.0f, 0.0f ); } static inline void vmathV4MakeZAxis( VmathVector4 *result ) { vmathV4MakeFromElems( result, 0.0f, 0.0f, 1.0f, 0.0f ); } static inline void vmathV4MakeWAxis( VmathVector4 *result ) { vmathV4MakeFromElems( result, 0.0f, 0.0f, 0.0f, 1.0f ); } static inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { VmathVector4 tmpV4_0, tmpV4_1; vmathV4Sub( &tmpV4_0, vec1, vec0 ); vmathV4ScalarMul( &tmpV4_1, &tmpV4_0, t ); vmathV4Add( result, vec0, &tmpV4_1 ); } static inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 ) { VmathVector4 tmpV4_0, tmpV4_1; float recipSinAngle, scale0, scale1, cosAngle, angle; cosAngle = vmathV4Dot( unitVec0, unitVec1 ); if ( cosAngle < _VECTORMATH_SLERP_TOL ) { angle = acosf( cosAngle ); recipSinAngle = ( 1.0f / sinf( angle ) ); scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); } else { scale0 = ( 1.0f - t ); scale1 = t; } vmathV4ScalarMul( &tmpV4_0, unitVec0, scale0 ); vmathV4ScalarMul( &tmpV4_1, unitVec1, scale1 ); vmathV4Add( result, &tmpV4_0, &tmpV4_1 ); } static inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec ) { vmathV3MakeFromElems( result, vec->x, vec->y, vec->z ); } static inline void vmathV4SetX( VmathVector4 *result, float _x ) { result->x = _x; } static inline float vmathV4GetX( const VmathVector4 *vec ) { return vec->x; } static inline void vmathV4SetY( VmathVector4 *result, float _y ) { result->y = _y; } static inline float vmathV4GetY( const VmathVector4 *vec ) { return vec->y; } static inline void vmathV4SetZ( VmathVector4 *result, float _z ) { result->z = _z; } static inline float vmathV4GetZ( const VmathVector4 *vec ) { return vec->z; } static inline void vmathV4SetW( VmathVector4 *result, float _w ) { result->w = _w; } static inline float vmathV4GetW( const VmathVector4 *vec ) { return vec->w; } static inline void vmathV4SetElem( VmathVector4 *result, int idx, float value ) { *(&result->x + idx) = value; } static inline float vmathV4GetElem( const VmathVector4 *vec, int idx ) { return *(&vec->x + idx); } static inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->x = ( vec0->x + vec1->x ); result->y = ( vec0->y + vec1->y ); result->z = ( vec0->z + vec1->z ); result->w = ( vec0->w + vec1->w ); } static inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->x = ( vec0->x - vec1->x ); result->y = ( vec0->y - vec1->y ); result->z = ( vec0->z - vec1->z ); result->w = ( vec0->w - vec1->w ); } static inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar ) { result->x = ( vec->x * scalar ); result->y = ( vec->y * scalar ); result->z = ( vec->z * scalar ); result->w = ( vec->w * scalar ); } static inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar ) { result->x = ( vec->x / scalar ); result->y = ( vec->y / scalar ); result->z = ( vec->z / scalar ); result->w = ( vec->w / scalar ); } static inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec ) { result->x = -vec->x; result->y = -vec->y; result->z = -vec->z; result->w = -vec->w; } static inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->x = ( vec0->x * vec1->x ); result->y = ( vec0->y * vec1->y ); result->z = ( vec0->z * vec1->z ); result->w = ( vec0->w * vec1->w ); } static inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->x = ( vec0->x / vec1->x ); result->y = ( vec0->y / vec1->y ); result->z = ( vec0->z / vec1->z ); result->w = ( vec0->w / vec1->w ); } static inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->x = ( 1.0f / vec->x ); result->y = ( 1.0f / vec->y ); result->z = ( 1.0f / vec->z ); result->w = ( 1.0f / vec->w ); } static inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->x = sqrtf( vec->x ); result->y = sqrtf( vec->y ); result->z = sqrtf( vec->z ); result->w = sqrtf( vec->w ); } static inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->x = ( 1.0f / sqrtf( vec->x ) ); result->y = ( 1.0f / sqrtf( vec->y ) ); result->z = ( 1.0f / sqrtf( vec->z ) ); result->w = ( 1.0f / sqrtf( vec->w ) ); } static inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->x = fabsf( vec->x ); result->y = fabsf( vec->y ); result->z = fabsf( vec->z ); result->w = fabsf( vec->w ); } static inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->x = ( vec1->x < 0.0f )? -fabsf( vec0->x ) : fabsf( vec0->x ); result->y = ( vec1->y < 0.0f )? -fabsf( vec0->y ) : fabsf( vec0->y ); result->z = ( vec1->z < 0.0f )? -fabsf( vec0->z ) : fabsf( vec0->z ); result->w = ( vec1->w < 0.0f )? -fabsf( vec0->w ) : fabsf( vec0->w ); } static inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->x = (vec0->x > vec1->x)? vec0->x : vec1->x; result->y = (vec0->y > vec1->y)? vec0->y : vec1->y; result->z = (vec0->z > vec1->z)? vec0->z : vec1->z; result->w = (vec0->w > vec1->w)? vec0->w : vec1->w; } static inline float vmathV4MaxElem( const VmathVector4 *vec ) { float result; result = (vec->x > vec->y)? vec->x : vec->y; result = (vec->z > result)? vec->z : result; result = (vec->w > result)? vec->w : result; return result; } static inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->x = (vec0->x < vec1->x)? vec0->x : vec1->x; result->y = (vec0->y < vec1->y)? vec0->y : vec1->y; result->z = (vec0->z < vec1->z)? vec0->z : vec1->z; result->w = (vec0->w < vec1->w)? vec0->w : vec1->w; } static inline float vmathV4MinElem( const VmathVector4 *vec ) { float result; result = (vec->x < vec->y)? vec->x : vec->y; result = (vec->z < result)? vec->z : result; result = (vec->w < result)? vec->w : result; return result; } static inline float vmathV4Sum( const VmathVector4 *vec ) { float result; result = ( vec->x + vec->y ); result = ( result + vec->z ); result = ( result + vec->w ); return result; } static inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 ) { float result; result = ( vec0->x * vec1->x ); result = ( result + ( vec0->y * vec1->y ) ); result = ( result + ( vec0->z * vec1->z ) ); result = ( result + ( vec0->w * vec1->w ) ); return result; } static inline float vmathV4LengthSqr( const VmathVector4 *vec ) { float result; result = ( vec->x * vec->x ); result = ( result + ( vec->y * vec->y ) ); result = ( result + ( vec->z * vec->z ) ); result = ( result + ( vec->w * vec->w ) ); return result; } static inline float vmathV4Length( const VmathVector4 *vec ) { return sqrtf( vmathV4LengthSqr( vec ) ); } static inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec ) { float lenSqr, lenInv; lenSqr = vmathV4LengthSqr( vec ); lenInv = ( 1.0f / sqrtf( lenSqr ) ); result->x = ( vec->x * lenInv ); result->y = ( vec->y * lenInv ); result->z = ( vec->z * lenInv ); result->w = ( vec->w * lenInv ); } static inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 ) { result->x = ( select1 )? vec1->x : vec0->x; result->y = ( select1 )? vec1->y : vec0->y; result->z = ( select1 )? vec1->z : vec0->z; result->w = ( select1 )? vec1->w : vec0->w; } #ifdef _VECTORMATH_DEBUG static inline void vmathV4Print( const VmathVector4 *vec ) { printf( "( %f %f %f %f )\n", vec->x, vec->y, vec->z, vec->w ); } static inline void vmathV4Prints( const VmathVector4 *vec, const char *name ) { printf( "%s: ( %f %f %f %f )\n", name, vec->x, vec->y, vec->z, vec->w ); } #endif static inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; } static inline void vmathP3MakeFromElems( VmathPoint3 *result, float _x, float _y, float _z ) { result->x = _x; result->y = _y; result->z = _z; } static inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; } static inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0, tmpV3_1; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathP3AddV3( result, pnt0, &tmpV3_1 ); } static inline void vmathP3SetX( VmathPoint3 *result, float _x ) { result->x = _x; } static inline float vmathP3GetX( const VmathPoint3 *pnt ) { return pnt->x; } static inline void vmathP3SetY( VmathPoint3 *result, float _y ) { result->y = _y; } static inline float vmathP3GetY( const VmathPoint3 *pnt ) { return pnt->y; } static inline void vmathP3SetZ( VmathPoint3 *result, float _z ) { result->z = _z; } static inline float vmathP3GetZ( const VmathPoint3 *pnt ) { return pnt->z; } static inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value ) { *(&result->x + idx) = value; } static inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx ) { return *(&pnt->x + idx); } static inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->x = ( pnt0->x - pnt1->x ); result->y = ( pnt0->y - pnt1->y ); result->z = ( pnt0->z - pnt1->z ); } static inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 ) { result->x = ( pnt->x + vec1->x ); result->y = ( pnt->y + vec1->y ); result->z = ( pnt->z + vec1->z ); } static inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 ) { result->x = ( pnt->x - vec1->x ); result->y = ( pnt->y - vec1->y ); result->z = ( pnt->z - vec1->z ); } static inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->x = ( pnt0->x * pnt1->x ); result->y = ( pnt0->y * pnt1->y ); result->z = ( pnt0->z * pnt1->z ); } static inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->x = ( pnt0->x / pnt1->x ); result->y = ( pnt0->y / pnt1->y ); result->z = ( pnt0->z / pnt1->z ); } static inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->x = ( 1.0f / pnt->x ); result->y = ( 1.0f / pnt->y ); result->z = ( 1.0f / pnt->z ); } static inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->x = sqrtf( pnt->x ); result->y = sqrtf( pnt->y ); result->z = sqrtf( pnt->z ); } static inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->x = ( 1.0f / sqrtf( pnt->x ) ); result->y = ( 1.0f / sqrtf( pnt->y ) ); result->z = ( 1.0f / sqrtf( pnt->z ) ); } static inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->x = fabsf( pnt->x ); result->y = fabsf( pnt->y ); result->z = fabsf( pnt->z ); } static inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->x = ( pnt1->x < 0.0f )? -fabsf( pnt0->x ) : fabsf( pnt0->x ); result->y = ( pnt1->y < 0.0f )? -fabsf( pnt0->y ) : fabsf( pnt0->y ); result->z = ( pnt1->z < 0.0f )? -fabsf( pnt0->z ) : fabsf( pnt0->z ); } static inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->x = (pnt0->x > pnt1->x)? pnt0->x : pnt1->x; result->y = (pnt0->y > pnt1->y)? pnt0->y : pnt1->y; result->z = (pnt0->z > pnt1->z)? pnt0->z : pnt1->z; } static inline float vmathP3MaxElem( const VmathPoint3 *pnt ) { float result; result = (pnt->x > pnt->y)? pnt->x : pnt->y; result = (pnt->z > result)? pnt->z : result; return result; } static inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->x = (pnt0->x < pnt1->x)? pnt0->x : pnt1->x; result->y = (pnt0->y < pnt1->y)? pnt0->y : pnt1->y; result->z = (pnt0->z < pnt1->z)? pnt0->z : pnt1->z; } static inline float vmathP3MinElem( const VmathPoint3 *pnt ) { float result; result = (pnt->x < pnt->y)? pnt->x : pnt->y; result = (pnt->z < result)? pnt->z : result; return result; } static inline float vmathP3Sum( const VmathPoint3 *pnt ) { float result; result = ( pnt->x + pnt->y ); result = ( result + pnt->z ); return result; } static inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal ) { VmathPoint3 tmpP3_0; vmathP3MakeFromScalar( &tmpP3_0, scaleVal ); vmathP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec ) { VmathPoint3 tmpP3_0; vmathP3MakeFromV3( &tmpP3_0, scaleVec ); vmathP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec ) { float result; result = ( pnt->x * unitVec->x ); result = ( result + ( pnt->y * unitVec->y ) ); result = ( result + ( pnt->z * unitVec->z ) ); return result; } static inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt ) { VmathVector3 tmpV3_0; vmathV3MakeFromP3( &tmpV3_0, pnt ); return vmathV3LengthSqr( &tmpV3_0 ); } static inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt ) { VmathVector3 tmpV3_0; vmathV3MakeFromP3( &tmpV3_0, pnt ); return vmathV3Length( &tmpV3_0 ); } static inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathV3LengthSqr( &tmpV3_0 ); } static inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathV3Length( &tmpV3_0 ); } static inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 ) { result->x = ( select1 )? pnt1->x : pnt0->x; result->y = ( select1 )? pnt1->y : pnt0->y; result->z = ( select1 )? pnt1->z : pnt0->z; } #ifdef _VECTORMATH_DEBUG static inline void vmathP3Print( const VmathPoint3 *pnt ) { printf( "( %f %f %f )\n", pnt->x, pnt->y, pnt->z ); } static inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name ) { printf( "%s: ( %f %f %f )\n", name, pnt->x, pnt->y, pnt->z ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/scalar/c/vec_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_V_C_H #define _VECTORMATH_VEC_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants */ #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathVector3 vmathV3MakeFromElems_V( float _x, float _y, float _z ) { VmathVector3 result; vmathV3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt ) { VmathVector3 result; vmathV3MakeFromP3(&result, &pnt); return result; } static inline VmathVector3 vmathV3MakeFromScalar_V( float scalar ) { VmathVector3 result; vmathV3MakeFromScalar(&result, scalar); return result; } static inline VmathVector3 vmathV3MakeXAxis_V( ) { VmathVector3 result; vmathV3MakeXAxis(&result); return result; } static inline VmathVector3 vmathV3MakeYAxis_V( ) { VmathVector3 result; vmathV3MakeYAxis(&result); return result; } static inline VmathVector3 vmathV3MakeZAxis_V( ) { VmathVector3 result; vmathV3MakeZAxis(&result); return result; } static inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 ) { VmathVector3 result; vmathV3Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline void vmathV3SetX_V( VmathVector3 *result, float _x ) { vmathV3SetX(result, _x); } static inline float vmathV3GetX_V( VmathVector3 vec ) { return vmathV3GetX(&vec); } static inline void vmathV3SetY_V( VmathVector3 *result, float _y ) { vmathV3SetY(result, _y); } static inline float vmathV3GetY_V( VmathVector3 vec ) { return vmathV3GetY(&vec); } static inline void vmathV3SetZ_V( VmathVector3 *result, float _z ) { vmathV3SetZ(result, _z); } static inline float vmathV3GetZ_V( VmathVector3 vec ) { return vmathV3GetZ(&vec); } static inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value ) { vmathV3SetElem(result, idx, value); } static inline float vmathV3GetElem_V( VmathVector3 vec, int idx ) { return vmathV3GetElem(&vec, idx); } static inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Add(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Sub(&result, &vec0, &vec1); return result; } static inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathV3AddP3(&result, &vec, &pnt1); return result; } static inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar ) { VmathVector3 result; vmathV3ScalarMul(&result, &vec, scalar); return result; } static inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar ) { VmathVector3 result; vmathV3ScalarDiv(&result, &vec, scalar); return result; } static inline VmathVector3 vmathV3Neg_V( VmathVector3 vec ) { VmathVector3 result; vmathV3Neg(&result, &vec); return result; } static inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3RecipPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3SqrtPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3RsqrtPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3AbsPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MaxPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV3MaxElem_V( VmathVector3 vec ) { return vmathV3MaxElem(&vec); } static inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MinPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV3MinElem_V( VmathVector3 vec ) { return vmathV3MinElem(&vec); } static inline float vmathV3Sum_V( VmathVector3 vec ) { return vmathV3Sum(&vec); } static inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 ) { return vmathV3Dot(&vec0, &vec1); } static inline float vmathV3LengthSqr_V( VmathVector3 vec ) { return vmathV3LengthSqr(&vec); } static inline float vmathV3Length_V( VmathVector3 vec ) { return vmathV3Length(&vec); } static inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec ) { VmathVector3 result; vmathV3Normalize(&result, &vec); return result; } static inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Cross(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 ) { VmathVector3 result; vmathV3Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathV3Print_V( VmathVector3 vec ) { vmathV3Print(&vec); } static inline void vmathV3Prints_V( VmathVector3 vec, const char *name ) { vmathV3Prints(&vec, name); } #endif static inline VmathVector4 vmathV4MakeFromElems_V( float _x, float _y, float _z, float _w ) { VmathVector4 result; vmathV4MakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float _w ) { VmathVector4 result; vmathV4MakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec ) { VmathVector4 result; vmathV4MakeFromV3(&result, &vec); return result; } static inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt ) { VmathVector4 result; vmathV4MakeFromP3(&result, &pnt); return result; } static inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat ) { VmathVector4 result; vmathV4MakeFromQ(&result, &quat); return result; } static inline VmathVector4 vmathV4MakeFromScalar_V( float scalar ) { VmathVector4 result; vmathV4MakeFromScalar(&result, scalar); return result; } static inline VmathVector4 vmathV4MakeXAxis_V( ) { VmathVector4 result; vmathV4MakeXAxis(&result); return result; } static inline VmathVector4 vmathV4MakeYAxis_V( ) { VmathVector4 result; vmathV4MakeYAxis(&result); return result; } static inline VmathVector4 vmathV4MakeZAxis_V( ) { VmathVector4 result; vmathV4MakeZAxis(&result); return result; } static inline VmathVector4 vmathV4MakeWAxis_V( ) { VmathVector4 result; vmathV4MakeWAxis(&result); return result; } static inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 ) { VmathVector4 result; vmathV4Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec ) { vmathV4SetXYZ(result, &vec); } static inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec ) { VmathVector3 result; vmathV4GetXYZ(&result, &vec); return result; } static inline void vmathV4SetX_V( VmathVector4 *result, float _x ) { vmathV4SetX(result, _x); } static inline float vmathV4GetX_V( VmathVector4 vec ) { return vmathV4GetX(&vec); } static inline void vmathV4SetY_V( VmathVector4 *result, float _y ) { vmathV4SetY(result, _y); } static inline float vmathV4GetY_V( VmathVector4 vec ) { return vmathV4GetY(&vec); } static inline void vmathV4SetZ_V( VmathVector4 *result, float _z ) { vmathV4SetZ(result, _z); } static inline float vmathV4GetZ_V( VmathVector4 vec ) { return vmathV4GetZ(&vec); } static inline void vmathV4SetW_V( VmathVector4 *result, float _w ) { vmathV4SetW(result, _w); } static inline float vmathV4GetW_V( VmathVector4 vec ) { return vmathV4GetW(&vec); } static inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value ) { vmathV4SetElem(result, idx, value); } static inline float vmathV4GetElem_V( VmathVector4 vec, int idx ) { return vmathV4GetElem(&vec, idx); } static inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Add(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Sub(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar ) { VmathVector4 result; vmathV4ScalarMul(&result, &vec, scalar); return result; } static inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar ) { VmathVector4 result; vmathV4ScalarDiv(&result, &vec, scalar); return result; } static inline VmathVector4 vmathV4Neg_V( VmathVector4 vec ) { VmathVector4 result; vmathV4Neg(&result, &vec); return result; } static inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4RecipPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4SqrtPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4RsqrtPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4AbsPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MaxPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV4MaxElem_V( VmathVector4 vec ) { return vmathV4MaxElem(&vec); } static inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MinPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV4MinElem_V( VmathVector4 vec ) { return vmathV4MinElem(&vec); } static inline float vmathV4Sum_V( VmathVector4 vec ) { return vmathV4Sum(&vec); } static inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 ) { return vmathV4Dot(&vec0, &vec1); } static inline float vmathV4LengthSqr_V( VmathVector4 vec ) { return vmathV4LengthSqr(&vec); } static inline float vmathV4Length_V( VmathVector4 vec ) { return vmathV4Length(&vec); } static inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec ) { VmathVector4 result; vmathV4Normalize(&result, &vec); return result; } static inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 ) { VmathVector4 result; vmathV4Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathV4Print_V( VmathVector4 vec ) { vmathV4Print(&vec); } static inline void vmathV4Prints_V( VmathVector4 vec, const char *name ) { vmathV4Prints(&vec, name); } #endif static inline VmathPoint3 vmathP3MakeFromElems_V( float _x, float _y, float _z ) { VmathPoint3 result; vmathP3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec ) { VmathPoint3 result; vmathP3MakeFromV3(&result, &vec); return result; } static inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar ) { VmathPoint3 result; vmathP3MakeFromScalar(&result, scalar); return result; } static inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3Lerp(&result, t, &pnt0, &pnt1); return result; } static inline void vmathP3SetX_V( VmathPoint3 *result, float _x ) { vmathP3SetX(result, _x); } static inline float vmathP3GetX_V( VmathPoint3 pnt ) { return vmathP3GetX(&pnt); } static inline void vmathP3SetY_V( VmathPoint3 *result, float _y ) { vmathP3SetY(result, _y); } static inline float vmathP3GetY_V( VmathPoint3 pnt ) { return vmathP3GetY(&pnt); } static inline void vmathP3SetZ_V( VmathPoint3 *result, float _z ) { vmathP3SetZ(result, _z); } static inline float vmathP3GetZ_V( VmathPoint3 pnt ) { return vmathP3GetZ(&pnt); } static inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value ) { vmathP3SetElem(result, idx, value); } static inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx ) { return vmathP3GetElem(&pnt, idx); } static inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathVector3 result; vmathP3Sub(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec1 ) { VmathPoint3 result; vmathP3AddV3(&result, &pnt, &vec1); return result; } static inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec1 ) { VmathPoint3 result; vmathP3SubV3(&result, &pnt, &vec1); return result; } static inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MulPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3DivPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3RecipPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3SqrtPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3RsqrtPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3AbsPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3CopySignPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MaxPerElem(&result, &pnt0, &pnt1); return result; } static inline float vmathP3MaxElem_V( VmathPoint3 pnt ) { return vmathP3MaxElem(&pnt); } static inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MinPerElem(&result, &pnt0, &pnt1); return result; } static inline float vmathP3MinElem_V( VmathPoint3 pnt ) { return vmathP3MinElem(&pnt); } static inline float vmathP3Sum_V( VmathPoint3 pnt ) { return vmathP3Sum(&pnt); } static inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal ) { VmathPoint3 result; vmathP3Scale(&result, &pnt, scaleVal); return result; } static inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec ) { VmathPoint3 result; vmathP3NonUniformScale(&result, &pnt, &scaleVec); return result; } static inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec ) { return vmathP3Projection(&pnt, &unitVec); } static inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt ) { return vmathP3DistSqrFromOrigin(&pnt); } static inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt ) { return vmathP3DistFromOrigin(&pnt); } static inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { return vmathP3DistSqr(&pnt0, &pnt1); } static inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { return vmathP3Dist(&pnt0, &pnt1); } static inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 ) { VmathPoint3 result; vmathP3Select(&result, &pnt0, &pnt1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathP3Print_V( VmathPoint3 pnt ) { vmathP3Print(&pnt); } static inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name ) { vmathP3Prints(&pnt, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/scalar/c/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_C_SCALAR_H #define _VECTORMATH_AOS_C_SCALAR_H #include #ifdef _VECTORMATH_DEBUG #include #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_AOS_C_TYPES_H #define _VECTORMATH_AOS_C_TYPES_H /* A 3-D vector in array-of-structures format */ typedef struct _VmathVector3 { float x; float y; float z; #ifndef __GNUC__ float d; #endif } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif VmathVector3; /* A 4-D vector in array-of-structures format */ typedef struct _VmathVector4 { float x; float y; float z; float w; } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif VmathVector4; /* A 3-D point in array-of-structures format */ typedef struct _VmathPoint3 { float x; float y; float z; #ifndef __GNUC__ float d; #endif } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif VmathPoint3; /* A quaternion in array-of-structures format */ typedef struct _VmathQuat { float x; float y; float z; float w; } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif VmathQuat; /* A 3x3 matrix in array-of-structures format */ typedef struct _VmathMatrix3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; } VmathMatrix3; /* A 4x4 matrix in array-of-structures format */ typedef struct _VmathMatrix4 { VmathVector4 col0; VmathVector4 col1; VmathVector4 col2; VmathVector4 col3; } VmathMatrix4; /* A 3x4 transformation matrix in array-of-structures format */ typedef struct _VmathTransform3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; VmathVector3 col3; } VmathTransform3; #endif /* * Copy a 3-D vector */ static inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec ); /* * Construct a 3-D vector from x, y, and z elements */ static inline void vmathV3MakeFromElems( VmathVector3 *result, float x, float y, float z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar ); /* * Set the x element of a 3-D vector */ static inline void vmathV3SetX( VmathVector3 *result, float x ); /* * Set the y element of a 3-D vector */ static inline void vmathV3SetY( VmathVector3 *result, float y ); /* * Set the z element of a 3-D vector */ static inline void vmathV3SetZ( VmathVector3 *result, float z ); /* * Get the x element of a 3-D vector */ static inline float vmathV3GetX( const VmathVector3 *vec ); /* * Get the y element of a 3-D vector */ static inline float vmathV3GetY( const VmathVector3 *vec ); /* * Get the z element of a 3-D vector */ static inline float vmathV3GetZ( const VmathVector3 *vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathV3SetElem( VmathVector3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline float vmathV3GetElem( const VmathVector3 *vec, int idx ); /* * Add two 3-D vectors */ static inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt ); /* * Multiply a 3-D vector by a scalar */ static inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar ); /* * Divide a 3-D vector by a scalar */ static inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar ); /* * Negate all elements of a 3-D vector */ static inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec ); /* * Construct x axis */ static inline void vmathV3MakeXAxis( VmathVector3 *result ); /* * Construct y axis */ static inline void vmathV3MakeYAxis( VmathVector3 *result ); /* * Construct z axis */ static inline void vmathV3MakeZAxis( VmathVector3 *result ); /* * Multiply two 3-D vectors per element */ static inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Maximum of two 3-D vectors per element */ static inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Minimum of two 3-D vectors per element */ static inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Maximum element of a 3-D vector */ static inline float vmathV3MaxElem( const VmathVector3 *vec ); /* * Minimum element of a 3-D vector */ static inline float vmathV3MinElem( const VmathVector3 *vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline float vmathV3Sum( const VmathVector3 *vec ); /* * Compute the dot product of two 3-D vectors */ static inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline float vmathV3LengthSqr( const VmathVector3 *vec ); /* * Compute the length of a 3-D vector */ static inline float vmathV3Length( const VmathVector3 *vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute cross product of two 3-D vectors */ static inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Outer product of two 3-D vectors */ static inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix */ static inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ); /* * Cross-product matrix of a 3-D vector */ static inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ); /* * Conditionally select between two 3-D vectors */ static inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Print( const VmathVector3 *vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Prints( const VmathVector3 *vec, const char *name ); #endif /* * Copy a 4-D vector */ static inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec ); /* * Construct a 4-D vector from x, y, z, and w elements */ static inline void vmathV4MakeFromElems( VmathVector4 *result, float x, float y, float z, float w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec ); /* * Set the x element of a 4-D vector */ static inline void vmathV4SetX( VmathVector4 *result, float x ); /* * Set the y element of a 4-D vector */ static inline void vmathV4SetY( VmathVector4 *result, float y ); /* * Set the z element of a 4-D vector */ static inline void vmathV4SetZ( VmathVector4 *result, float z ); /* * Set the w element of a 4-D vector */ static inline void vmathV4SetW( VmathVector4 *result, float w ); /* * Get the x element of a 4-D vector */ static inline float vmathV4GetX( const VmathVector4 *vec ); /* * Get the y element of a 4-D vector */ static inline float vmathV4GetY( const VmathVector4 *vec ); /* * Get the z element of a 4-D vector */ static inline float vmathV4GetZ( const VmathVector4 *vec ); /* * Get the w element of a 4-D vector */ static inline float vmathV4GetW( const VmathVector4 *vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathV4SetElem( VmathVector4 *result, int idx, float value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline float vmathV4GetElem( const VmathVector4 *vec, int idx ); /* * Add two 4-D vectors */ static inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar ); /* * Divide a 4-D vector by a scalar */ static inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar ); /* * Negate all elements of a 4-D vector */ static inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec ); /* * Construct x axis */ static inline void vmathV4MakeXAxis( VmathVector4 *result ); /* * Construct y axis */ static inline void vmathV4MakeYAxis( VmathVector4 *result ); /* * Construct z axis */ static inline void vmathV4MakeZAxis( VmathVector4 *result ); /* * Construct w axis */ static inline void vmathV4MakeWAxis( VmathVector4 *result ); /* * Multiply two 4-D vectors per element */ static inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Maximum of two 4-D vectors per element */ static inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Minimum of two 4-D vectors per element */ static inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Maximum element of a 4-D vector */ static inline float vmathV4MaxElem( const VmathVector4 *vec ); /* * Minimum element of a 4-D vector */ static inline float vmathV4MinElem( const VmathVector4 *vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline float vmathV4Sum( const VmathVector4 *vec ); /* * Compute the dot product of two 4-D vectors */ static inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline float vmathV4LengthSqr( const VmathVector4 *vec ); /* * Compute the length of a 4-D vector */ static inline float vmathV4Length( const VmathVector4 *vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec ); /* * Outer product of two 4-D vectors */ static inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 ); /* * Conditionally select between two 4-D vectors */ static inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Print( const VmathVector4 *vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Prints( const VmathVector4 *vec, const char *name ); #endif /* * Copy a 3-D point */ static inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Construct a 3-D point from x, y, and z elements */ static inline void vmathP3MakeFromElems( VmathPoint3 *result, float x, float y, float z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar ); /* * Set the x element of a 3-D point */ static inline void vmathP3SetX( VmathPoint3 *result, float x ); /* * Set the y element of a 3-D point */ static inline void vmathP3SetY( VmathPoint3 *result, float y ); /* * Set the z element of a 3-D point */ static inline void vmathP3SetZ( VmathPoint3 *result, float z ); /* * Get the x element of a 3-D point */ static inline float vmathP3GetX( const VmathPoint3 *pnt ); /* * Get the y element of a 3-D point */ static inline float vmathP3GetY( const VmathPoint3 *pnt ); /* * Get the z element of a 3-D point */ static inline float vmathP3GetZ( const VmathPoint3 *pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec ); /* * Multiply two 3-D points per element */ static inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Maximum of two 3-D points per element */ static inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Minimum of two 3-D points per element */ static inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Maximum element of a 3-D point */ static inline float vmathP3MaxElem( const VmathPoint3 *pnt ); /* * Minimum element of a 3-D point */ static inline float vmathP3MinElem( const VmathPoint3 *pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline float vmathP3Sum( const VmathPoint3 *pnt ); /* * Apply uniform scale to a 3-D point */ static inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt ); /* * Compute the square of the distance between two 3-D points */ static inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Compute the distance between two 3-D points */ static inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Conditionally select between two 3-D points */ static inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Print( const VmathPoint3 *pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name ); #endif /* * Copy a quaternion */ static inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat ); /* * Construct a quaternion from x, y, z, and w elements */ static inline void vmathQMakeFromElems( VmathQuat *result, float x, float y, float z, float w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline void vmathQMakeFromScalar( VmathQuat *result, float scalar ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec ); /* * Get the x, y, and z elements of a quaternion */ static inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat ); /* * Set the x element of a quaternion */ static inline void vmathQSetX( VmathQuat *result, float x ); /* * Set the y element of a quaternion */ static inline void vmathQSetY( VmathQuat *result, float y ); /* * Set the z element of a quaternion */ static inline void vmathQSetZ( VmathQuat *result, float z ); /* * Set the w element of a quaternion */ static inline void vmathQSetW( VmathQuat *result, float w ); /* * Get the x element of a quaternion */ static inline float vmathQGetX( const VmathQuat *quat ); /* * Get the y element of a quaternion */ static inline float vmathQGetY( const VmathQuat *quat ); /* * Get the z element of a quaternion */ static inline float vmathQGetZ( const VmathQuat *quat ); /* * Get the w element of a quaternion */ static inline float vmathQGetW( const VmathQuat *quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathQSetElem( VmathQuat *result, int idx, float value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline float vmathQGetElem( const VmathQuat *quat, int idx ); /* * Add two quaternions */ static inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Subtract a quaternion from another quaternion */ static inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Multiply two quaternions */ static inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Multiply a quaternion by a scalar */ static inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar ); /* * Divide a quaternion by a scalar */ static inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar ); /* * Negate all elements of a quaternion */ static inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat ); /* * Construct an identity quaternion */ static inline void vmathQMakeIdentity( VmathQuat *result ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline void vmathQMakeRotationX( VmathQuat *result, float radians ); /* * Construct a quaternion to rotate around the y axis */ static inline void vmathQMakeRotationY( VmathQuat *result, float radians ); /* * Construct a quaternion to rotate around the z axis */ static inline void vmathQMakeRotationZ( VmathQuat *result, float radians ); /* * Compute the conjugate of a quaternion */ static inline void vmathQConj( VmathQuat *result, const VmathQuat *quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline void vmathQRotate( VmathVector3 *result, const VmathQuat *unitQuat, const VmathVector3 *vec ); /* * Compute the dot product of two quaternions */ static inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Compute the norm of a quaternion */ static inline float vmathQNorm( const VmathQuat *quat ); /* * Compute the length of a quaternion */ static inline float vmathQLength( const VmathQuat *quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 ); /* * Conditionally select between two quaternions */ static inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrint( const VmathQuat *quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrints( const VmathQuat *quat, const char *name ); #endif /* * Copy a 3x3 matrix */ static inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Construct a 3x3 matrix containing the specified columns */ static inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *col2 ); /* * Get column 0 of a 3x3 matrix */ static inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Get column 1 of a 3x3 matrix */ static inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Get column 2 of a 3x3 matrix */ static inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row ); /* * Add two 3x3 matrices */ static inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec ); /* * Multiply two 3x3 matrices */ static inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Construct an identity 3x3 matrix */ static inline void vmathM3MakeIdentity( VmathMatrix3 *result ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat ); /* * Multiply two 3x3 matrices per element */ static inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Transpose of a 3x3 matrix */ static inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Determinant of a 3x3 matrix */ static inline float vmathM3Determinant( const VmathMatrix3 *mat ); /* * Conditionally select between two 3x3 matrices */ static inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Print( const VmathMatrix3 *mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name ); #endif /* * Copy a 4x4 matrix */ static inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Construct a 4x4 matrix containing the specified columns */ static inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *col0, const VmathVector4 *col1, const VmathVector4 *col2, const VmathVector4 *col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *col3 ); /* * Get column 0 of a 4x4 matrix */ static inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 1 of a 4x4 matrix */ static inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 2 of a 4x4 matrix */ static inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 3 of a 4x4 matrix */ static inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row ); /* * Add two 4x4 matrices */ static inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt ); /* * Multiply two 4x4 matrices */ static inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm ); /* * Construct an identity 4x4 matrix */ static inline void vmathM4MakeIdentity( VmathMatrix4 *result ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec ); /* * Construct a perspective projection matrix */ static inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ); /* * Construct an orthographic projection matrix */ static inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat ); /* * Multiply two 4x4 matrices per element */ static inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Transpose of a 4x4 matrix */ static inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Determinant of a 4x4 matrix */ static inline float vmathM4Determinant( const VmathMatrix4 *mat ); /* * Conditionally select between two 4x4 matrices */ static inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Print( const VmathMatrix4 *mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name ); #endif /* * Copy a 3x4 transformation matrix */ static inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2, const VmathVector3 *col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm ); /* * Set translation component */ static inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt ); /* * Multiply two 3x4 transformation matrices */ static inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline void vmathT3MakeIdentity( VmathTransform3 *result ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Conditionally select between two 3x4 transformation matrices */ static inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Print( const VmathTransform3 *tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vec_aos.h" #include "quat_aos.h" #include "mat_aos.h" #endif ================================================ FILE: samples/vectormath/scalar/c/vectormath_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_C_V_SCALAR_H #define _VECTORMATH_AOS_C_V_SCALAR_H #include #ifdef _VECTORMATH_DEBUG #include #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_AOS_C_TYPES_H #define _VECTORMATH_AOS_C_TYPES_H /* A 3-D vector in array-of-structures format */ typedef struct _VmathVector3 { float x; float y; float z; #ifndef __GNUC__ float d; #endif } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif VmathVector3; /* A 4-D vector in array-of-structures format */ typedef struct _VmathVector4 { float x; float y; float z; float w; } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif VmathVector4; /* A 3-D point in array-of-structures format */ typedef struct _VmathPoint3 { float x; float y; float z; #ifndef __GNUC__ float d; #endif } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif VmathPoint3; /* A quaternion in array-of-structures format */ typedef struct _VmathQuat { float x; float y; float z; float w; } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif VmathQuat; /* A 3x3 matrix in array-of-structures format */ typedef struct _VmathMatrix3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; } VmathMatrix3; /* A 4x4 matrix in array-of-structures format */ typedef struct _VmathMatrix4 { VmathVector4 col0; VmathVector4 col1; VmathVector4 col2; VmathVector4 col3; } VmathMatrix4; /* A 3x4 transformation matrix in array-of-structures format */ typedef struct _VmathTransform3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; VmathVector3 col3; } VmathTransform3; #endif /* * Construct a 3-D vector from x, y, and z elements */ static inline VmathVector3 vmathV3MakeFromElems_V( float x, float y, float z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline VmathVector3 vmathV3MakeFromScalar_V( float scalar ); /* * Set the x element of a 3-D vector */ static inline void vmathV3SetX_V( VmathVector3 *result, float x ); /* * Set the y element of a 3-D vector */ static inline void vmathV3SetY_V( VmathVector3 *result, float y ); /* * Set the z element of a 3-D vector */ static inline void vmathV3SetZ_V( VmathVector3 *result, float z ); /* * Get the x element of a 3-D vector */ static inline float vmathV3GetX_V( VmathVector3 vec ); /* * Get the y element of a 3-D vector */ static inline float vmathV3GetY_V( VmathVector3 vec ); /* * Get the z element of a 3-D vector */ static inline float vmathV3GetZ_V( VmathVector3 vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline float vmathV3GetElem_V( VmathVector3 vec, int idx ); /* * Add two 3-D vectors */ static inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt ); /* * Multiply a 3-D vector by a scalar */ static inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar ); /* * Divide a 3-D vector by a scalar */ static inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar ); /* * Negate all elements of a 3-D vector */ static inline VmathVector3 vmathV3Neg_V( VmathVector3 vec ); /* * Construct x axis */ static inline VmathVector3 vmathV3MakeXAxis_V( ); /* * Construct y axis */ static inline VmathVector3 vmathV3MakeYAxis_V( ); /* * Construct z axis */ static inline VmathVector3 vmathV3MakeZAxis_V( ); /* * Multiply two 3-D vectors per element */ static inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Maximum of two 3-D vectors per element */ static inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Minimum of two 3-D vectors per element */ static inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Maximum element of a 3-D vector */ static inline float vmathV3MaxElem_V( VmathVector3 vec ); /* * Minimum element of a 3-D vector */ static inline float vmathV3MinElem_V( VmathVector3 vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline float vmathV3Sum_V( VmathVector3 vec ); /* * Compute the dot product of two 3-D vectors */ static inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline float vmathV3LengthSqr_V( VmathVector3 vec ); /* * Compute the length of a 3-D vector */ static inline float vmathV3Length_V( VmathVector3 vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec ); /* * Compute cross product of two 3-D vectors */ static inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Outer product of two 3-D vectors */ static inline VmathMatrix3 vmathV3Outer_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix */ static inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat ); /* * Cross-product matrix of a 3-D vector */ static inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 ); /* * Conditionally select between two 3-D vectors */ static inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Print_V( VmathVector3 vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Prints_V( VmathVector3 vec, const char *name ); #endif /* * Construct a 4-D vector from x, y, z, and w elements */ static inline VmathVector4 vmathV4MakeFromElems_V( float x, float y, float z, float w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline VmathVector4 vmathV4MakeFromScalar_V( float scalar ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec ); /* * Set the x element of a 4-D vector */ static inline void vmathV4SetX_V( VmathVector4 *result, float x ); /* * Set the y element of a 4-D vector */ static inline void vmathV4SetY_V( VmathVector4 *result, float y ); /* * Set the z element of a 4-D vector */ static inline void vmathV4SetZ_V( VmathVector4 *result, float z ); /* * Set the w element of a 4-D vector */ static inline void vmathV4SetW_V( VmathVector4 *result, float w ); /* * Get the x element of a 4-D vector */ static inline float vmathV4GetX_V( VmathVector4 vec ); /* * Get the y element of a 4-D vector */ static inline float vmathV4GetY_V( VmathVector4 vec ); /* * Get the z element of a 4-D vector */ static inline float vmathV4GetZ_V( VmathVector4 vec ); /* * Get the w element of a 4-D vector */ static inline float vmathV4GetW_V( VmathVector4 vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline float vmathV4GetElem_V( VmathVector4 vec, int idx ); /* * Add two 4-D vectors */ static inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar ); /* * Divide a 4-D vector by a scalar */ static inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar ); /* * Negate all elements of a 4-D vector */ static inline VmathVector4 vmathV4Neg_V( VmathVector4 vec ); /* * Construct x axis */ static inline VmathVector4 vmathV4MakeXAxis_V( ); /* * Construct y axis */ static inline VmathVector4 vmathV4MakeYAxis_V( ); /* * Construct z axis */ static inline VmathVector4 vmathV4MakeZAxis_V( ); /* * Construct w axis */ static inline VmathVector4 vmathV4MakeWAxis_V( ); /* * Multiply two 4-D vectors per element */ static inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Maximum of two 4-D vectors per element */ static inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Minimum of two 4-D vectors per element */ static inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Maximum element of a 4-D vector */ static inline float vmathV4MaxElem_V( VmathVector4 vec ); /* * Minimum element of a 4-D vector */ static inline float vmathV4MinElem_V( VmathVector4 vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline float vmathV4Sum_V( VmathVector4 vec ); /* * Compute the dot product of two 4-D vectors */ static inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline float vmathV4LengthSqr_V( VmathVector4 vec ); /* * Compute the length of a 4-D vector */ static inline float vmathV4Length_V( VmathVector4 vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec ); /* * Outer product of two 4-D vectors */ static inline VmathMatrix4 vmathV4Outer_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 ); /* * Conditionally select between two 4-D vectors */ static inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Print_V( VmathVector4 vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Prints_V( VmathVector4 vec, const char *name ); #endif /* * Construct a 3-D point from x, y, and z elements */ static inline VmathPoint3 vmathP3MakeFromElems_V( float x, float y, float z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar ); /* * Set the x element of a 3-D point */ static inline void vmathP3SetX_V( VmathPoint3 *result, float x ); /* * Set the y element of a 3-D point */ static inline void vmathP3SetY_V( VmathPoint3 *result, float y ); /* * Set the z element of a 3-D point */ static inline void vmathP3SetZ_V( VmathPoint3 *result, float z ); /* * Get the x element of a 3-D point */ static inline float vmathP3GetX_V( VmathPoint3 pnt ); /* * Get the y element of a 3-D point */ static inline float vmathP3GetY_V( VmathPoint3 pnt ); /* * Get the z element of a 3-D point */ static inline float vmathP3GetZ_V( VmathPoint3 pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec ); /* * Multiply two 3-D points per element */ static inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Maximum of two 3-D points per element */ static inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Minimum of two 3-D points per element */ static inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Maximum element of a 3-D point */ static inline float vmathP3MaxElem_V( VmathPoint3 pnt ); /* * Minimum element of a 3-D point */ static inline float vmathP3MinElem_V( VmathPoint3 pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline float vmathP3Sum_V( VmathPoint3 pnt ); /* * Apply uniform scale to a 3-D point */ static inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt ); /* * Compute the square of the distance between two 3-D points */ static inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Compute the distance between two 3-D points */ static inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Conditionally select between two 3-D points */ static inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Print_V( VmathPoint3 pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name ); #endif /* * Construct a quaternion from x, y, z, and w elements */ static inline VmathQuat vmathQMakeFromElems_V( float x, float y, float z, float w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline VmathQuat vmathQMakeFromScalar_V( float scalar ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec ); /* * Get the x, y, and z elements of a quaternion */ static inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat ); /* * Set the x element of a quaternion */ static inline void vmathQSetX_V( VmathQuat *result, float x ); /* * Set the y element of a quaternion */ static inline void vmathQSetY_V( VmathQuat *result, float y ); /* * Set the z element of a quaternion */ static inline void vmathQSetZ_V( VmathQuat *result, float z ); /* * Set the w element of a quaternion */ static inline void vmathQSetW_V( VmathQuat *result, float w ); /* * Get the x element of a quaternion */ static inline float vmathQGetX_V( VmathQuat quat ); /* * Get the y element of a quaternion */ static inline float vmathQGetY_V( VmathQuat quat ); /* * Get the z element of a quaternion */ static inline float vmathQGetZ_V( VmathQuat quat ); /* * Get the w element of a quaternion */ static inline float vmathQGetW_V( VmathQuat quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathQSetElem_V( VmathQuat *result, int idx, float value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline float vmathQGetElem_V( VmathQuat quat, int idx ); /* * Add two quaternions */ static inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 ); /* * Subtract a quaternion from another quaternion */ static inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 ); /* * Multiply two quaternions */ static inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 ); /* * Multiply a quaternion by a scalar */ static inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar ); /* * Divide a quaternion by a scalar */ static inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar ); /* * Negate all elements of a quaternion */ static inline VmathQuat vmathQNeg_V( VmathQuat quat ); /* * Construct an identity quaternion */ static inline VmathQuat vmathQMakeIdentity_V( ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline VmathQuat vmathQMakeRotationX_V( float radians ); /* * Construct a quaternion to rotate around the y axis */ static inline VmathQuat vmathQMakeRotationY_V( float radians ); /* * Construct a quaternion to rotate around the z axis */ static inline VmathQuat vmathQMakeRotationZ_V( float radians ); /* * Compute the conjugate of a quaternion */ static inline VmathQuat vmathQConj_V( VmathQuat quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline VmathVector3 vmathQRotate_V( VmathQuat unitQuat, VmathVector3 vec ); /* * Compute the dot product of two quaternions */ static inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 ); /* * Compute the norm of a quaternion */ static inline float vmathQNorm_V( VmathQuat quat ); /* * Compute the length of a quaternion */ static inline float vmathQLength_V( VmathQuat quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline VmathQuat vmathQNormalize_V( VmathQuat quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 ); /* * Conditionally select between two quaternions */ static inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrint_V( VmathQuat quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrints_V( VmathQuat quat, const char *name ); #endif /* * Construct a 3x3 matrix containing the specified columns */ static inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 col2 ); /* * Get column 0 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat ); /* * Get column 1 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat ); /* * Get column 2 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row ); /* * Add two 3x3 matrices */ static inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec ); /* * Multiply two 3x3 matrices */ static inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Construct an identity 3x3 matrix */ static inline VmathMatrix3 vmathM3MakeIdentity_V( ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline VmathMatrix3 vmathM3MakeRotationX_V( float radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline VmathMatrix3 vmathM3MakeRotationY_V( float radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat ); /* * Multiply two 3x3 matrices per element */ static inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat ); /* * Transpose of a 3x3 matrix */ static inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat ); /* * Determinant of a 3x3 matrix */ static inline float vmathM3Determinant_V( VmathMatrix3 mat ); /* * Conditionally select between two 3x3 matrices */ static inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Print_V( VmathMatrix3 mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name ); #endif /* * Construct a 4x4 matrix containing the specified columns */ static inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 col0, VmathVector4 col1, VmathVector4 col2, VmathVector4 col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 col3 ); /* * Get column 0 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat ); /* * Get column 1 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat ); /* * Get column 2 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat ); /* * Get column 3 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row ); /* * Add two 4x4 matrices */ static inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt ); /* * Multiply two 4x4 matrices */ static inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm ); /* * Construct an identity 4x4 matrix */ static inline VmathMatrix4 vmathM4MakeIdentity_V( ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline VmathMatrix4 vmathM4MakeRotationX_V( float radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline VmathMatrix4 vmathM4MakeRotationY_V( float radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec ); /* * Construct a perspective projection matrix */ static inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar ); /* * Construct an orthographic projection matrix */ static inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat ); /* * Multiply two 4x4 matrices per element */ static inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat ); /* * Transpose of a 4x4 matrix */ static inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat ); /* * Determinant of a 4x4 matrix */ static inline float vmathM4Determinant_V( VmathMatrix4 mat ); /* * Conditionally select between two 4x4 matrices */ static inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Print_V( VmathMatrix4 mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name ); #endif /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2, VmathVector3 col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm ); /* * Set translation component */ static inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt ); /* * Multiply two 3x4 transformation matrices */ static inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline VmathTransform3 vmathT3MakeIdentity_V( ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline VmathTransform3 vmathT3MakeRotationX_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline VmathTransform3 vmathT3MakeRotationY_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline VmathTransform3 vmathT3MakeRotationZ_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm ); /* * Conditionally select between two 3x4 transformation matrices */ static inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Print_V( VmathTransform3 tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vectormath_aos.h" #include "vec_aos_v.h" #include "quat_aos_v.h" #include "mat_aos_v.h" #endif ================================================ FILE: samples/vectormath/scalar/cpp/mat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_CPP_H #define _VECTORMATH_MAT_AOS_CPP_H namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // Constants #define _VECTORMATH_PI_OVER_2 1.570796327f //----------------------------------------------------------------------------- // Definitions inline Matrix3::Matrix3( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; } inline Matrix3::Matrix3( float scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); } inline Matrix3::Matrix3( const Quat & unitQuat ) { float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; qx = unitQuat.getX(); qy = unitQuat.getY(); qz = unitQuat.getZ(); qw = unitQuat.getW(); qx2 = ( qx + qx ); qy2 = ( qy + qy ); qz2 = ( qz + qz ); qxqx2 = ( qx * qx2 ); qxqy2 = ( qx * qy2 ); qxqz2 = ( qx * qz2 ); qxqw2 = ( qw * qx2 ); qyqy2 = ( qy * qy2 ); qyqz2 = ( qy * qz2 ); qyqw2 = ( qw * qy2 ); qzqz2 = ( qz * qz2 ); qzqw2 = ( qw * qz2 ); mCol0 = Vector3( ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) ); mCol1 = Vector3( ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) ); mCol2 = Vector3( ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) ); } inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; } inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) { mCol0 = _col0; return *this; } inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) { mCol1 = _col1; return *this; } inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) { mCol2 = _col2; return *this; } inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); return *this; } inline Matrix3 & Matrix3::setElem( int col, int row, float val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline float Matrix3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Matrix3::getCol0( ) const { return mCol0; } inline const Vector3 Matrix3::getCol1( ) const { return mCol1; } inline const Vector3 Matrix3::getCol2( ) const { return mCol2; } inline const Vector3 Matrix3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector3 Matrix3::getRow( int row ) const { return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); } inline Vector3 & Matrix3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Matrix3::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; return *this; } inline const Matrix3 transpose( const Matrix3 & mat ) { return Matrix3( Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) ); } inline const Matrix3 inverse( const Matrix3 & mat ) { Vector3 tmp0, tmp1, tmp2; float detinv; tmp0 = cross( mat.getCol1(), mat.getCol2() ); tmp1 = cross( mat.getCol2(), mat.getCol0() ); tmp2 = cross( mat.getCol0(), mat.getCol1() ); detinv = ( 1.0f / dot( mat.getCol2(), tmp2 ) ); return Matrix3( Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ), Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ), Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ) ); } inline float determinant( const Matrix3 & mat ) { return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); } inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const { return Matrix3( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ) ); } inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const { return Matrix3( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) { *this = *this + mat; return *this; } inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) { *this = *this - mat; return *this; } inline const Matrix3 Matrix3::operator -( ) const { return Matrix3( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ) ); } inline const Matrix3 absPerElem( const Matrix3 & mat ) { return Matrix3( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ) ); } inline const Matrix3 Matrix3::operator *( float scalar ) const { return Matrix3( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ) ); } inline Matrix3 & Matrix3::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) { return mat * scalar; } inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const { return Vector3( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) ); } inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const { return Matrix3( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) { *this = *this * mat; return *this; } inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) { return Matrix3( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ) ); } inline const Matrix3 Matrix3::identity( ) { return Matrix3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationX( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Matrix3( Vector3::xAxis( ), Vector3( 0.0f, c, s ), Vector3( 0.0f, -s, c ) ); } inline const Matrix3 Matrix3::rotationY( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Matrix3( Vector3( c, 0.0f, -s ), Vector3::yAxis( ), Vector3( s, 0.0f, c ) ); } inline const Matrix3 Matrix3::rotationZ( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Matrix3( Vector3( c, s, 0.0f ), Vector3( -s, c, 0.0f ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) { float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sX = sinf( radiansXYZ.getX() ); cX = cosf( radiansXYZ.getX() ); sY = sinf( radiansXYZ.getY() ); cY = cosf( radiansXYZ.getY() ); sZ = sinf( radiansXYZ.getZ() ); cZ = cosf( radiansXYZ.getZ() ); tmp0 = ( cZ * sY ); tmp1 = ( sZ * sY ); return Matrix3( Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ) ); } inline const Matrix3 Matrix3::rotation( float radians, const Vector3 & unitVec ) { float x, y, z, s, c, oneMinusC, xy, yz, zx; s = sinf( radians ); c = cosf( radians ); x = unitVec.getX(); y = unitVec.getY(); z = unitVec.getZ(); xy = ( x * y ); yz = ( y * z ); zx = ( z * x ); oneMinusC = ( 1.0f - c ); return Matrix3( Vector3( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ), Vector3( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ), Vector3( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) ) ); } inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) { return Matrix3( unitQuat ); } inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) { return Matrix3( Vector3( scaleVec.getX(), 0.0f, 0.0f ), Vector3( 0.0f, scaleVec.getY(), 0.0f ), Vector3( 0.0f, 0.0f, scaleVec.getZ() ) ); } inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) { return Matrix3( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ) ); } inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) { return Matrix3( mulPerElem( mat.getCol0(), scaleVec ), mulPerElem( mat.getCol1(), scaleVec ), mulPerElem( mat.getCol2(), scaleVec ) ); } inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) { return Matrix3( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix3 & mat ) { print( mat.getRow( 0 ) ); print( mat.getRow( 1 ) ); print( mat.getRow( 2 ) ); } inline void print( const Matrix3 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Matrix4::Matrix4( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; } inline Matrix4::Matrix4( float scalar ) { mCol0 = Vector4( scalar ); mCol1 = Vector4( scalar ); mCol2 = Vector4( scalar ); mCol3 = Vector4( scalar ); } inline Matrix4::Matrix4( const Transform3 & mat ) { mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( mat.getCol3(), 1.0f ); } inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) { mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( translateVec, 1.0f ); } inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) { Matrix3 mat; mat = Matrix3( unitQuat ); mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( translateVec, 1.0f ); } inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) { mCol0 = _col0; return *this; } inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) { mCol1 = _col1; return *this; } inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) { mCol2 = _col2; return *this; } inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) { mCol3 = _col3; return *this; } inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Matrix4 & Matrix4::setElem( int col, int row, float val ) { Vector4 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline float Matrix4::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector4 Matrix4::getCol0( ) const { return mCol0; } inline const Vector4 Matrix4::getCol1( ) const { return mCol1; } inline const Vector4 Matrix4::getCol2( ) const { return mCol2; } inline const Vector4 Matrix4::getCol3( ) const { return mCol3; } inline const Vector4 Matrix4::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Matrix4::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector4 & Matrix4::operator []( int col ) { return *(&mCol0 + col); } inline const Vector4 Matrix4::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; return *this; } inline const Matrix4 transpose( const Matrix4 & mat ) { return Matrix4( Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) ); } inline const Matrix4 inverse( const Matrix4 & mat ) { Vector4 res0, res1, res2, res3; float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; mA = mat.getCol0().getX(); mB = mat.getCol0().getY(); mC = mat.getCol0().getZ(); mD = mat.getCol0().getW(); mE = mat.getCol1().getX(); mF = mat.getCol1().getY(); mG = mat.getCol1().getZ(); mH = mat.getCol1().getW(); mI = mat.getCol2().getX(); mJ = mat.getCol2().getY(); mK = mat.getCol2().getZ(); mL = mat.getCol2().getW(); mM = mat.getCol3().getX(); mN = mat.getCol3().getY(); mO = mat.getCol3().getZ(); mP = mat.getCol3().getW(); tmp0 = ( ( mK * mD ) - ( mC * mL ) ); tmp1 = ( ( mO * mH ) - ( mG * mP ) ); tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); tmp3 = ( ( mF * mO ) - ( mN * mG ) ); tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); tmp5 = ( ( mN * mH ) - ( mF * mP ) ); res0.setX( ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) ); res0.setY( ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) ); res0.setZ( ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) ); res0.setW( ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) ); detInv = ( 1.0f / ( ( ( ( mA * res0.getX() ) + ( mE * res0.getY() ) ) + ( mI * res0.getZ() ) ) + ( mM * res0.getW() ) ) ); res1.setX( ( mI * tmp1 ) ); res1.setY( ( mM * tmp0 ) ); res1.setZ( ( mA * tmp1 ) ); res1.setW( ( mE * tmp0 ) ); res3.setX( ( mI * tmp3 ) ); res3.setY( ( mM * tmp2 ) ); res3.setZ( ( mA * tmp3 ) ); res3.setW( ( mE * tmp2 ) ); res2.setX( ( mI * tmp5 ) ); res2.setY( ( mM * tmp4 ) ); res2.setZ( ( mA * tmp5 ) ); res2.setW( ( mE * tmp4 ) ); tmp0 = ( ( mI * mB ) - ( mA * mJ ) ); tmp1 = ( ( mM * mF ) - ( mE * mN ) ); tmp2 = ( ( mI * mD ) - ( mA * mL ) ); tmp3 = ( ( mM * mH ) - ( mE * mP ) ); tmp4 = ( ( mI * mC ) - ( mA * mK ) ); tmp5 = ( ( mM * mG ) - ( mE * mO ) ); res2.setX( ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.getX() ) ); res2.setY( ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.getY() ) ); res2.setZ( ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.getZ() ) ); res2.setW( ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.getW() ) ); res3.setX( ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.getX() ) ); res3.setY( ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.getY() ) ); res3.setZ( ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.getZ() ) ); res3.setW( ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.getW() ) ); res1.setX( ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.getX() ) ); res1.setY( ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.getY() ) ); res1.setZ( ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.getZ() ) ); res1.setW( ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.getW() ) ); return Matrix4( ( res0 * detInv ), ( res1 * detInv ), ( res2 * detInv ), ( res3 * detInv ) ); } inline const Matrix4 affineInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( inverse( affineMat ) ); } inline const Matrix4 orthoInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( orthoInverse( affineMat ) ); } inline float determinant( const Matrix4 & mat ) { 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; mA = mat.getCol0().getX(); mB = mat.getCol0().getY(); mC = mat.getCol0().getZ(); mD = mat.getCol0().getW(); mE = mat.getCol1().getX(); mF = mat.getCol1().getY(); mG = mat.getCol1().getZ(); mH = mat.getCol1().getW(); mI = mat.getCol2().getX(); mJ = mat.getCol2().getY(); mK = mat.getCol2().getZ(); mL = mat.getCol2().getW(); mM = mat.getCol3().getX(); mN = mat.getCol3().getY(); mO = mat.getCol3().getZ(); mP = mat.getCol3().getW(); tmp0 = ( ( mK * mD ) - ( mC * mL ) ); tmp1 = ( ( mO * mH ) - ( mG * mP ) ); tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); tmp3 = ( ( mF * mO ) - ( mN * mG ) ); tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); tmp5 = ( ( mN * mH ) - ( mF * mP ) ); dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ); dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ); dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ); dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ); return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) ); } inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const { return Matrix4( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ), ( mCol3 + mat.mCol3 ) ); } inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const { return Matrix4( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ), ( mCol3 - mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) { *this = *this + mat; return *this; } inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) { *this = *this - mat; return *this; } inline const Matrix4 Matrix4::operator -( ) const { return Matrix4( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ), ( -mCol3 ) ); } inline const Matrix4 absPerElem( const Matrix4 & mat ) { return Matrix4( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ), absPerElem( mat.getCol3() ) ); } inline const Matrix4 Matrix4::operator *( float scalar ) const { return Matrix4( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ), ( mCol3 * scalar ) ); } inline Matrix4 & Matrix4::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) { return mat * scalar; } inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const { return Vector4( ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ), ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ), ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ), ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) ) ); } inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const { return Vector4( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ), ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) ); } inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const { return Vector4( ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ), ( ( ( ( mCol0.getW() * pnt.getX() ) + ( mCol1.getW() * pnt.getY() ) ) + ( mCol2.getW() * pnt.getZ() ) ) + mCol3.getW() ) ); } inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const { return Matrix4( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ), ( *this * mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) { *this = *this * mat; return *this; } inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const { return Matrix4( ( *this * tfrm.getCol0() ), ( *this * tfrm.getCol1() ), ( *this * tfrm.getCol2() ), ( *this * Point3( tfrm.getCol3() ) ) ); } inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) { return Matrix4( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ), mulPerElem( mat0.getCol3(), mat1.getCol3() ) ); } inline const Matrix4 Matrix4::identity( ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) { mCol0.setXYZ( mat3.getCol0() ); mCol1.setXYZ( mat3.getCol1() ); mCol2.setXYZ( mat3.getCol2() ); return *this; } inline const Matrix3 Matrix4::getUpper3x3( ) const { return Matrix3( mCol0.getXYZ( ), mCol1.getXYZ( ), mCol2.getXYZ( ) ); } inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) { mCol3.setXYZ( translateVec ); return *this; } inline const Vector3 Matrix4::getTranslation( ) const { return mCol3.getXYZ( ); } inline const Matrix4 Matrix4::rotationX( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Matrix4( Vector4::xAxis( ), Vector4( 0.0f, c, s, 0.0f ), Vector4( 0.0f, -s, c, 0.0f ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationY( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Matrix4( Vector4( c, 0.0f, -s, 0.0f ), Vector4::yAxis( ), Vector4( s, 0.0f, c, 0.0f ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZ( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Matrix4( Vector4( c, s, 0.0f, 0.0f ), Vector4( -s, c, 0.0f, 0.0f ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) { float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sX = sinf( radiansXYZ.getX() ); cX = cosf( radiansXYZ.getX() ); sY = sinf( radiansXYZ.getY() ); cY = cosf( radiansXYZ.getY() ); sZ = sinf( radiansXYZ.getZ() ); cZ = cosf( radiansXYZ.getZ() ); tmp0 = ( cZ * sY ); tmp1 = ( sZ * sY ); return Matrix4( Vector4( ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ), Vector4( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ), Vector4( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( float radians, const Vector3 & unitVec ) { float x, y, z, s, c, oneMinusC, xy, yz, zx; s = sinf( radians ); c = cosf( radians ); x = unitVec.getX(); y = unitVec.getY(); z = unitVec.getZ(); xy = ( x * y ); yz = ( y * z ); zx = ( z * x ); oneMinusC = ( 1.0f - c ); return Matrix4( Vector4( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ), Vector4( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ), Vector4( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) { return Matrix4( Transform3::rotation( unitQuat ) ); } inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) { return Matrix4( Vector4( scaleVec.getX(), 0.0f, 0.0f, 0.0f ), Vector4( 0.0f, scaleVec.getY(), 0.0f, 0.0f ), Vector4( 0.0f, 0.0f, scaleVec.getZ(), 0.0f ), Vector4::wAxis( ) ); } inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) { return Matrix4( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ), mat.getCol3() ); } inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) { Vector4 scale4; scale4 = Vector4( scaleVec, 1.0f ); return Matrix4( mulPerElem( mat.getCol0(), scale4 ), mulPerElem( mat.getCol1(), scale4 ), mulPerElem( mat.getCol2(), scale4 ), mulPerElem( mat.getCol3(), scale4 ) ); } inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4( translateVec, 1.0f ) ); } inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) { Matrix4 m4EyeFrame; Vector3 v3X, v3Y, v3Z; v3Y = normalize( upVec ); v3Z = normalize( ( eyePos - lookAtPos ) ); v3X = normalize( cross( v3Y, v3Z ) ); v3Y = cross( v3Z, v3X ); m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); return orthoInverse( m4EyeFrame ); } inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) { float f, rangeInv; f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) ); rangeInv = ( 1.0f / ( zNear - zFar ) ); return Matrix4( Vector4( ( f / aspect ), 0.0f, 0.0f, 0.0f ), Vector4( 0.0f, f, 0.0f, 0.0f ), Vector4( 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ), Vector4( 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f ) ); } inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) { float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; sum_rl = ( right + left ); sum_tb = ( top + bottom ); sum_nf = ( zNear + zFar ); inv_rl = ( 1.0f / ( right - left ) ); inv_tb = ( 1.0f / ( top - bottom ) ); inv_nf = ( 1.0f / ( zNear - zFar ) ); n2 = ( zNear + zNear ); return Matrix4( Vector4( ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ), Vector4( 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ), Vector4( ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ), Vector4( 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f ) ); } inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) { float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; sum_rl = ( right + left ); sum_tb = ( top + bottom ); sum_nf = ( zNear + zFar ); inv_rl = ( 1.0f / ( right - left ) ); inv_tb = ( 1.0f / ( top - bottom ) ); inv_nf = ( 1.0f / ( zNear - zFar ) ); return Matrix4( Vector4( ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ), Vector4( 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ), Vector4( 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ), Vector4( ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f ) ); } inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) { return Matrix4( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ), select( mat0.getCol3(), mat1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix4 & mat ) { print( mat.getRow( 0 ) ); print( mat.getRow( 1 ) ); print( mat.getRow( 2 ) ); print( mat.getRow( 3 ) ); } inline void print( const Matrix4 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Transform3::Transform3( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; } inline Transform3::Transform3( float scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); mCol3 = Vector3( scalar ); } inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) { this->setUpper3x3( tfrm ); this->setTranslation( translateVec ); } inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) { this->setUpper3x3( Matrix3( unitQuat ) ); this->setTranslation( translateVec ); } inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) { mCol0 = _col0; return *this; } inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) { mCol1 = _col1; return *this; } inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) { mCol2 = _col2; return *this; } inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) { mCol3 = _col3; return *this; } inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Transform3 & Transform3::setElem( int col, int row, float val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline float Transform3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Transform3::getCol0( ) const { return mCol0; } inline const Vector3 Transform3::getCol1( ) const { return mCol1; } inline const Vector3 Transform3::getCol2( ) const { return mCol2; } inline const Vector3 Transform3::getCol3( ) const { return mCol3; } inline const Vector3 Transform3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Transform3::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector3 & Transform3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Transform3::operator []( int col ) const { return *(&mCol0 + col); } inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; return *this; } inline const Transform3 inverse( const Transform3 & tfrm ) { Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; float detinv; tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); detinv = ( 1.0f / dot( tfrm.getCol2(), tmp2 ) ); inv0 = Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ); inv1 = Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ); inv2 = Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ); return Transform3( inv0, inv1, inv2, Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) ); } inline const Transform3 orthoInverse( const Transform3 & tfrm ) { Vector3 inv0, inv1, inv2; inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); return Transform3( inv0, inv1, inv2, Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) ); } inline const Transform3 absPerElem( const Transform3 & tfrm ) { return Transform3( absPerElem( tfrm.getCol0() ), absPerElem( tfrm.getCol1() ), absPerElem( tfrm.getCol2() ), absPerElem( tfrm.getCol3() ) ); } inline const Vector3 Transform3::operator *( const Vector3 & vec ) const { return Vector3( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) ); } inline const Point3 Transform3::operator *( const Point3 & pnt ) const { return Point3( ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ) ); } inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const { return Transform3( ( *this * tfrm.mCol0 ), ( *this * tfrm.mCol1 ), ( *this * tfrm.mCol2 ), Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) ); } inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) { return Transform3( mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) ); } inline const Transform3 Transform3::identity( ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), Vector3( 0.0f ) ); } inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) { mCol0 = tfrm.getCol0(); mCol1 = tfrm.getCol1(); mCol2 = tfrm.getCol2(); return *this; } inline const Matrix3 Transform3::getUpper3x3( ) const { return Matrix3( mCol0, mCol1, mCol2 ); } inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) { mCol3 = translateVec; return *this; } inline const Vector3 Transform3::getTranslation( ) const { return mCol3; } inline const Transform3 Transform3::rotationX( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Transform3( Vector3::xAxis( ), Vector3( 0.0f, c, s ), Vector3( 0.0f, -s, c ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationY( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Transform3( Vector3( c, 0.0f, -s ), Vector3::yAxis( ), Vector3( s, 0.0f, c ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationZ( float radians ) { float s, c; s = sinf( radians ); c = cosf( radians ); return Transform3( Vector3( c, s, 0.0f ), Vector3( -s, c, 0.0f ), Vector3::zAxis( ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) { float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sX = sinf( radiansXYZ.getX() ); cX = cosf( radiansXYZ.getX() ); sY = sinf( radiansXYZ.getY() ); cY = cosf( radiansXYZ.getY() ); sZ = sinf( radiansXYZ.getZ() ); cZ = cosf( radiansXYZ.getZ() ); tmp0 = ( cZ * sY ); tmp1 = ( sZ * sY ); return Transform3( Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotation( float radians, const Vector3 & unitVec ) { return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotation( const Quat & unitQuat ) { return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) { return Transform3( Vector3( scaleVec.getX(), 0.0f, 0.0f ), Vector3( 0.0f, scaleVec.getY(), 0.0f ), Vector3( 0.0f, 0.0f, scaleVec.getZ() ), Vector3( 0.0f ) ); } inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) { return Transform3( ( tfrm.getCol0() * scaleVec.getX( ) ), ( tfrm.getCol1() * scaleVec.getY( ) ), ( tfrm.getCol2() * scaleVec.getZ( ) ), tfrm.getCol3() ); } inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) { return Transform3( mulPerElem( tfrm.getCol0(), scaleVec ), mulPerElem( tfrm.getCol1(), scaleVec ), mulPerElem( tfrm.getCol2(), scaleVec ), mulPerElem( tfrm.getCol3(), scaleVec ) ); } inline const Transform3 Transform3::translation( const Vector3 & translateVec ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), translateVec ); } inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) { return Transform3( select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Transform3 & tfrm ) { print( tfrm.getRow( 0 ) ); print( tfrm.getRow( 1 ) ); print( tfrm.getRow( 2 ) ); } inline void print( const Transform3 & tfrm, const char * name ) { printf("%s:\n", name); print( tfrm ); } #endif inline Quat::Quat( const Matrix3 & tfrm ) { float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; int negTrace, ZgtX, ZgtY, YgtX; int largestXorY, largestYorZ, largestZorX; xx = tfrm.getCol0().getX(); yx = tfrm.getCol0().getY(); zx = tfrm.getCol0().getZ(); xy = tfrm.getCol1().getX(); yy = tfrm.getCol1().getY(); zy = tfrm.getCol1().getZ(); xz = tfrm.getCol2().getX(); yz = tfrm.getCol2().getY(); zz = tfrm.getCol2().getZ(); trace = ( ( xx + yy ) + zz ); negTrace = ( trace < 0.0f ); ZgtX = zz > xx; ZgtY = zz > yy; YgtX = yy > xx; largestXorY = ( !ZgtX || !ZgtY ) && negTrace; largestYorZ = ( YgtX || ZgtX ) && negTrace; largestZorX = ( ZgtY || !YgtX ) && negTrace; if ( largestXorY ) { zz = -zz; xy = -xy; } if ( largestYorZ ) { xx = -xx; yz = -yz; } if ( largestZorX ) { yy = -yy; zx = -zx; } radicand = ( ( ( xx + yy ) + zz ) + 1.0f ); scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) ); tmpx = ( ( zy - yz ) * scale ); tmpy = ( ( xz - zx ) * scale ); tmpz = ( ( yx - xy ) * scale ); tmpw = ( radicand * scale ); qx = tmpx; qy = tmpy; qz = tmpz; qw = tmpw; if ( largestXorY ) { qx = tmpw; qy = tmpz; qz = tmpy; qw = tmpx; } if ( largestYorZ ) { tmpx = qx; tmpz = qz; qx = qy; qy = tmpx; qz = qw; qw = tmpz; } mX = qx; mY = qy; mZ = qz; mW = qw; } inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) { return Matrix3( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ) ); } inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) { return Matrix4( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ), ( tfrm0 * tfrm1.getW( ) ) ); } inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) { return Vector3( ( ( ( vec.getX() * mat.getCol0().getX() ) + ( vec.getY() * mat.getCol0().getY() ) ) + ( vec.getZ() * mat.getCol0().getZ() ) ), ( ( ( vec.getX() * mat.getCol1().getX() ) + ( vec.getY() * mat.getCol1().getY() ) ) + ( vec.getZ() * mat.getCol1().getZ() ) ), ( ( ( vec.getX() * mat.getCol2().getX() ) + ( vec.getY() * mat.getCol2().getY() ) ) + ( vec.getZ() * mat.getCol2().getZ() ) ) ); } inline const Matrix3 crossMatrix( const Vector3 & vec ) { return Matrix3( Vector3( 0.0f, vec.getZ(), -vec.getY() ), Vector3( -vec.getZ(), 0.0f, vec.getX() ), Vector3( vec.getY(), -vec.getX(), 0.0f ) ); } inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) { return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); } } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/scalar/cpp/quat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_CPP_H #define _VECTORMATH_QUAT_AOS_CPP_H //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Aos { inline Quat::Quat( const Quat & quat ) { mX = quat.mX; mY = quat.mY; mZ = quat.mZ; mW = quat.mW; } inline Quat::Quat( float _x, float _y, float _z, float _w ) { mX = _x; mY = _y; mZ = _z; mW = _w; } inline Quat::Quat( const Vector3 & xyz, float _w ) { this->setXYZ( xyz ); this->setW( _w ); } inline Quat::Quat( const Vector4 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); mW = vec.getW(); } inline Quat::Quat( float scalar ) { mX = scalar; mY = scalar; mZ = scalar; mW = scalar; } inline const Quat Quat::identity( ) { return Quat( 0.0f, 0.0f, 0.0f, 1.0f ); } inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ) { return ( quat0 + ( ( quat1 - quat0 ) * t ) ); } inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ) { Quat start; float recipSinAngle, scale0, scale1, cosAngle, angle; cosAngle = dot( unitQuat0, unitQuat1 ); if ( cosAngle < 0.0f ) { cosAngle = -cosAngle; start = ( -unitQuat0 ); } else { start = unitQuat0; } if ( cosAngle < _VECTORMATH_SLERP_TOL ) { angle = acosf( cosAngle ); recipSinAngle = ( 1.0f / sinf( angle ) ); scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); } else { scale0 = ( 1.0f - t ); scale1 = t; } return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); } inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) { Quat tmp0, tmp1; tmp0 = slerp( t, unitQuat0, unitQuat3 ); tmp1 = slerp( t, unitQuat1, unitQuat2 ); return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); } inline Quat & Quat::operator =( const Quat & quat ) { mX = quat.mX; mY = quat.mY; mZ = quat.mZ; mW = quat.mW; return *this; } inline Quat & Quat::setXYZ( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); return *this; } inline const Vector3 Quat::getXYZ( ) const { return Vector3( mX, mY, mZ ); } inline Quat & Quat::setX( float _x ) { mX = _x; return *this; } inline float Quat::getX( ) const { return mX; } inline Quat & Quat::setY( float _y ) { mY = _y; return *this; } inline float Quat::getY( ) const { return mY; } inline Quat & Quat::setZ( float _z ) { mZ = _z; return *this; } inline float Quat::getZ( ) const { return mZ; } inline Quat & Quat::setW( float _w ) { mW = _w; return *this; } inline float Quat::getW( ) const { return mW; } inline Quat & Quat::setElem( int idx, float value ) { *(&mX + idx) = value; return *this; } inline float Quat::getElem( int idx ) const { return *(&mX + idx); } inline float & Quat::operator []( int idx ) { return *(&mX + idx); } inline float Quat::operator []( int idx ) const { return *(&mX + idx); } inline const Quat Quat::operator +( const Quat & quat ) const { return Quat( ( mX + quat.mX ), ( mY + quat.mY ), ( mZ + quat.mZ ), ( mW + quat.mW ) ); } inline const Quat Quat::operator -( const Quat & quat ) const { return Quat( ( mX - quat.mX ), ( mY - quat.mY ), ( mZ - quat.mZ ), ( mW - quat.mW ) ); } inline const Quat Quat::operator *( float scalar ) const { return Quat( ( mX * scalar ), ( mY * scalar ), ( mZ * scalar ), ( mW * scalar ) ); } inline Quat & Quat::operator +=( const Quat & quat ) { *this = *this + quat; return *this; } inline Quat & Quat::operator -=( const Quat & quat ) { *this = *this - quat; return *this; } inline Quat & Quat::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Quat Quat::operator /( float scalar ) const { return Quat( ( mX / scalar ), ( mY / scalar ), ( mZ / scalar ), ( mW / scalar ) ); } inline Quat & Quat::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline const Quat Quat::operator -( ) const { return Quat( -mX, -mY, -mZ, -mW ); } inline const Quat operator *( float scalar, const Quat & quat ) { return quat * scalar; } inline float dot( const Quat & quat0, const Quat & quat1 ) { float result; result = ( quat0.getX() * quat1.getX() ); result = ( result + ( quat0.getY() * quat1.getY() ) ); result = ( result + ( quat0.getZ() * quat1.getZ() ) ); result = ( result + ( quat0.getW() * quat1.getW() ) ); return result; } inline float norm( const Quat & quat ) { float result; result = ( quat.getX() * quat.getX() ); result = ( result + ( quat.getY() * quat.getY() ) ); result = ( result + ( quat.getZ() * quat.getZ() ) ); result = ( result + ( quat.getW() * quat.getW() ) ); return result; } inline float length( const Quat & quat ) { return sqrtf( norm( quat ) ); } inline const Quat normalize( const Quat & quat ) { float lenSqr, lenInv; lenSqr = norm( quat ); lenInv = ( 1.0f / sqrtf( lenSqr ) ); return Quat( ( quat.getX() * lenInv ), ( quat.getY() * lenInv ), ( quat.getZ() * lenInv ), ( quat.getW() * lenInv ) ); } inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) { float cosHalfAngleX2, recipCosHalfAngleX2; cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); } inline const Quat Quat::rotation( float radians, const Vector3 & unitVec ) { float s, c, angle; angle = ( radians * 0.5f ); s = sinf( angle ); c = cosf( angle ); return Quat( ( unitVec * s ), c ); } inline const Quat Quat::rotationX( float radians ) { float s, c, angle; angle = ( radians * 0.5f ); s = sinf( angle ); c = cosf( angle ); return Quat( s, 0.0f, 0.0f, c ); } inline const Quat Quat::rotationY( float radians ) { float s, c, angle; angle = ( radians * 0.5f ); s = sinf( angle ); c = cosf( angle ); return Quat( 0.0f, s, 0.0f, c ); } inline const Quat Quat::rotationZ( float radians ) { float s, c, angle; angle = ( radians * 0.5f ); s = sinf( angle ); c = cosf( angle ); return Quat( 0.0f, 0.0f, s, c ); } inline const Quat Quat::operator *( const Quat & quat ) const { return Quat( ( ( ( ( mW * quat.mX ) + ( mX * quat.mW ) ) + ( mY * quat.mZ ) ) - ( mZ * quat.mY ) ), ( ( ( ( mW * quat.mY ) + ( mY * quat.mW ) ) + ( mZ * quat.mX ) ) - ( mX * quat.mZ ) ), ( ( ( ( mW * quat.mZ ) + ( mZ * quat.mW ) ) + ( mX * quat.mY ) ) - ( mY * quat.mX ) ), ( ( ( ( mW * quat.mW ) - ( mX * quat.mX ) ) - ( mY * quat.mY ) ) - ( mZ * quat.mZ ) ) ); } inline Quat & Quat::operator *=( const Quat & quat ) { *this = *this * quat; return *this; } inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) { float tmpX, tmpY, tmpZ, tmpW; tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); return Vector3( ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) ); } inline const Quat conj( const Quat & quat ) { return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); } inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ) { return Quat( ( select1 )? quat1.getX() : quat0.getX(), ( select1 )? quat1.getY() : quat0.getY(), ( select1 )? quat1.getZ() : quat0.getZ(), ( select1 )? quat1.getW() : quat0.getW() ); } #ifdef _VECTORMATH_DEBUG inline void print( const Quat & quat ) { printf( "( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); } inline void print( const Quat & quat, const char * name ) { printf( "%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); } #endif } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/scalar/cpp/vec_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_CPP_H #define _VECTORMATH_VEC_AOS_CPP_H //----------------------------------------------------------------------------- // Constants #define _VECTORMATH_SLERP_TOL 0.999f //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Aos { inline Vector3::Vector3( const Vector3 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; } inline Vector3::Vector3( float _x, float _y, float _z ) { mX = _x; mY = _y; mZ = _z; } inline Vector3::Vector3( const Point3 & pnt ) { mX = pnt.getX(); mY = pnt.getY(); mZ = pnt.getZ(); } inline Vector3::Vector3( float scalar ) { mX = scalar; mY = scalar; mZ = scalar; } inline const Vector3 Vector3::xAxis( ) { return Vector3( 1.0f, 0.0f, 0.0f ); } inline const Vector3 Vector3::yAxis( ) { return Vector3( 0.0f, 1.0f, 0.0f ); } inline const Vector3 Vector3::zAxis( ) { return Vector3( 0.0f, 0.0f, 1.0f ); } inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) { float recipSinAngle, scale0, scale1, cosAngle, angle; cosAngle = dot( unitVec0, unitVec1 ); if ( cosAngle < _VECTORMATH_SLERP_TOL ) { angle = acosf( cosAngle ); recipSinAngle = ( 1.0f / sinf( angle ) ); scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); } else { scale0 = ( 1.0f - t ); scale1 = t; } return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); } inline Vector3 & Vector3::operator =( const Vector3 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; return *this; } inline Vector3 & Vector3::setX( float _x ) { mX = _x; return *this; } inline float Vector3::getX( ) const { return mX; } inline Vector3 & Vector3::setY( float _y ) { mY = _y; return *this; } inline float Vector3::getY( ) const { return mY; } inline Vector3 & Vector3::setZ( float _z ) { mZ = _z; return *this; } inline float Vector3::getZ( ) const { return mZ; } inline Vector3 & Vector3::setElem( int idx, float value ) { *(&mX + idx) = value; return *this; } inline float Vector3::getElem( int idx ) const { return *(&mX + idx); } inline float & Vector3::operator []( int idx ) { return *(&mX + idx); } inline float Vector3::operator []( int idx ) const { return *(&mX + idx); } inline const Vector3 Vector3::operator +( const Vector3 & vec ) const { return Vector3( ( mX + vec.mX ), ( mY + vec.mY ), ( mZ + vec.mZ ) ); } inline const Vector3 Vector3::operator -( const Vector3 & vec ) const { return Vector3( ( mX - vec.mX ), ( mY - vec.mY ), ( mZ - vec.mZ ) ); } inline const Point3 Vector3::operator +( const Point3 & pnt ) const { return Point3( ( mX + pnt.getX() ), ( mY + pnt.getY() ), ( mZ + pnt.getZ() ) ); } inline const Vector3 Vector3::operator *( float scalar ) const { return Vector3( ( mX * scalar ), ( mY * scalar ), ( mZ * scalar ) ); } inline Vector3 & Vector3::operator +=( const Vector3 & vec ) { *this = *this + vec; return *this; } inline Vector3 & Vector3::operator -=( const Vector3 & vec ) { *this = *this - vec; return *this; } inline Vector3 & Vector3::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Vector3 Vector3::operator /( float scalar ) const { return Vector3( ( mX / scalar ), ( mY / scalar ), ( mZ / scalar ) ); } inline Vector3 & Vector3::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline const Vector3 Vector3::operator -( ) const { return Vector3( -mX, -mY, -mZ ); } inline const Vector3 operator *( float scalar, const Vector3 & vec ) { return vec * scalar; } inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( ( vec0.getX() * vec1.getX() ), ( vec0.getY() * vec1.getY() ), ( vec0.getZ() * vec1.getZ() ) ); } inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( ( vec0.getX() / vec1.getX() ), ( vec0.getY() / vec1.getY() ), ( vec0.getZ() / vec1.getZ() ) ); } inline const Vector3 recipPerElem( const Vector3 & vec ) { return Vector3( ( 1.0f / vec.getX() ), ( 1.0f / vec.getY() ), ( 1.0f / vec.getZ() ) ); } inline const Vector3 sqrtPerElem( const Vector3 & vec ) { return Vector3( sqrtf( vec.getX() ), sqrtf( vec.getY() ), sqrtf( vec.getZ() ) ); } inline const Vector3 rsqrtPerElem( const Vector3 & vec ) { return Vector3( ( 1.0f / sqrtf( vec.getX() ) ), ( 1.0f / sqrtf( vec.getY() ) ), ( 1.0f / sqrtf( vec.getZ() ) ) ); } inline const Vector3 absPerElem( const Vector3 & vec ) { return Vector3( fabsf( vec.getX() ), fabsf( vec.getY() ), fabsf( vec.getZ() ) ); } inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ) ); } inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ() ); } inline float maxElem( const Vector3 & vec ) { float result; result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); result = (vec.getZ() > result)? vec.getZ() : result; return result; } inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ() ); } inline float minElem( const Vector3 & vec ) { float result; result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); result = (vec.getZ() < result)? vec.getZ() : result; return result; } inline float sum( const Vector3 & vec ) { float result; result = ( vec.getX() + vec.getY() ); result = ( result + vec.getZ() ); return result; } inline float dot( const Vector3 & vec0, const Vector3 & vec1 ) { float result; result = ( vec0.getX() * vec1.getX() ); result = ( result + ( vec0.getY() * vec1.getY() ) ); result = ( result + ( vec0.getZ() * vec1.getZ() ) ); return result; } inline float lengthSqr( const Vector3 & vec ) { float result; result = ( vec.getX() * vec.getX() ); result = ( result + ( vec.getY() * vec.getY() ) ); result = ( result + ( vec.getZ() * vec.getZ() ) ); return result; } inline float length( const Vector3 & vec ) { return sqrtf( lengthSqr( vec ) ); } inline const Vector3 normalize( const Vector3 & vec ) { float lenSqr, lenInv; lenSqr = lengthSqr( vec ); lenInv = ( 1.0f / sqrtf( lenSqr ) ); return Vector3( ( vec.getX() * lenInv ), ( vec.getY() * lenInv ), ( vec.getZ() * lenInv ) ); } inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( ( ( vec0.getY() * vec1.getZ() ) - ( vec0.getZ() * vec1.getY() ) ), ( ( vec0.getZ() * vec1.getX() ) - ( vec0.getX() * vec1.getZ() ) ), ( ( vec0.getX() * vec1.getY() ) - ( vec0.getY() * vec1.getX() ) ) ); } inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ) { return Vector3( ( select1 )? vec1.getX() : vec0.getX(), ( select1 )? vec1.getY() : vec0.getY(), ( select1 )? vec1.getZ() : vec0.getZ() ); } #ifdef _VECTORMATH_DEBUG inline void print( const Vector3 & vec ) { printf( "( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ() ); } inline void print( const Vector3 & vec, const char * name ) { printf( "%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ() ); } #endif inline Vector4::Vector4( const Vector4 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; mW = vec.mW; } inline Vector4::Vector4( float _x, float _y, float _z, float _w ) { mX = _x; mY = _y; mZ = _z; mW = _w; } inline Vector4::Vector4( const Vector3 & xyz, float _w ) { this->setXYZ( xyz ); this->setW( _w ); } inline Vector4::Vector4( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); mW = 0.0f; } inline Vector4::Vector4( const Point3 & pnt ) { mX = pnt.getX(); mY = pnt.getY(); mZ = pnt.getZ(); mW = 1.0f; } inline Vector4::Vector4( const Quat & quat ) { mX = quat.getX(); mY = quat.getY(); mZ = quat.getZ(); mW = quat.getW(); } inline Vector4::Vector4( float scalar ) { mX = scalar; mY = scalar; mZ = scalar; mW = scalar; } inline const Vector4 Vector4::xAxis( ) { return Vector4( 1.0f, 0.0f, 0.0f, 0.0f ); } inline const Vector4 Vector4::yAxis( ) { return Vector4( 0.0f, 1.0f, 0.0f, 0.0f ); } inline const Vector4 Vector4::zAxis( ) { return Vector4( 0.0f, 0.0f, 1.0f, 0.0f ); } inline const Vector4 Vector4::wAxis( ) { return Vector4( 0.0f, 0.0f, 0.0f, 1.0f ); } inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) { float recipSinAngle, scale0, scale1, cosAngle, angle; cosAngle = dot( unitVec0, unitVec1 ); if ( cosAngle < _VECTORMATH_SLERP_TOL ) { angle = acosf( cosAngle ); recipSinAngle = ( 1.0f / sinf( angle ) ); scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); } else { scale0 = ( 1.0f - t ); scale1 = t; } return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); } inline Vector4 & Vector4::operator =( const Vector4 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; mW = vec.mW; return *this; } inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); return *this; } inline const Vector3 Vector4::getXYZ( ) const { return Vector3( mX, mY, mZ ); } inline Vector4 & Vector4::setX( float _x ) { mX = _x; return *this; } inline float Vector4::getX( ) const { return mX; } inline Vector4 & Vector4::setY( float _y ) { mY = _y; return *this; } inline float Vector4::getY( ) const { return mY; } inline Vector4 & Vector4::setZ( float _z ) { mZ = _z; return *this; } inline float Vector4::getZ( ) const { return mZ; } inline Vector4 & Vector4::setW( float _w ) { mW = _w; return *this; } inline float Vector4::getW( ) const { return mW; } inline Vector4 & Vector4::setElem( int idx, float value ) { *(&mX + idx) = value; return *this; } inline float Vector4::getElem( int idx ) const { return *(&mX + idx); } inline float & Vector4::operator []( int idx ) { return *(&mX + idx); } inline float Vector4::operator []( int idx ) const { return *(&mX + idx); } inline const Vector4 Vector4::operator +( const Vector4 & vec ) const { return Vector4( ( mX + vec.mX ), ( mY + vec.mY ), ( mZ + vec.mZ ), ( mW + vec.mW ) ); } inline const Vector4 Vector4::operator -( const Vector4 & vec ) const { return Vector4( ( mX - vec.mX ), ( mY - vec.mY ), ( mZ - vec.mZ ), ( mW - vec.mW ) ); } inline const Vector4 Vector4::operator *( float scalar ) const { return Vector4( ( mX * scalar ), ( mY * scalar ), ( mZ * scalar ), ( mW * scalar ) ); } inline Vector4 & Vector4::operator +=( const Vector4 & vec ) { *this = *this + vec; return *this; } inline Vector4 & Vector4::operator -=( const Vector4 & vec ) { *this = *this - vec; return *this; } inline Vector4 & Vector4::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Vector4 Vector4::operator /( float scalar ) const { return Vector4( ( mX / scalar ), ( mY / scalar ), ( mZ / scalar ), ( mW / scalar ) ); } inline Vector4 & Vector4::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline const Vector4 Vector4::operator -( ) const { return Vector4( -mX, -mY, -mZ, -mW ); } inline const Vector4 operator *( float scalar, const Vector4 & vec ) { return vec * scalar; } inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( ( vec0.getX() * vec1.getX() ), ( vec0.getY() * vec1.getY() ), ( vec0.getZ() * vec1.getZ() ), ( vec0.getW() * vec1.getW() ) ); } inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( ( vec0.getX() / vec1.getX() ), ( vec0.getY() / vec1.getY() ), ( vec0.getZ() / vec1.getZ() ), ( vec0.getW() / vec1.getW() ) ); } inline const Vector4 recipPerElem( const Vector4 & vec ) { return Vector4( ( 1.0f / vec.getX() ), ( 1.0f / vec.getY() ), ( 1.0f / vec.getZ() ), ( 1.0f / vec.getW() ) ); } inline const Vector4 sqrtPerElem( const Vector4 & vec ) { return Vector4( sqrtf( vec.getX() ), sqrtf( vec.getY() ), sqrtf( vec.getZ() ), sqrtf( vec.getW() ) ); } inline const Vector4 rsqrtPerElem( const Vector4 & vec ) { return Vector4( ( 1.0f / sqrtf( vec.getX() ) ), ( 1.0f / sqrtf( vec.getY() ) ), ( 1.0f / sqrtf( vec.getZ() ) ), ( 1.0f / sqrtf( vec.getW() ) ) ); } inline const Vector4 absPerElem( const Vector4 & vec ) { return Vector4( fabsf( vec.getX() ), fabsf( vec.getY() ), fabsf( vec.getZ() ), fabsf( vec.getW() ) ); } inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ), ( vec1.getW() < 0.0f )? -fabsf( vec0.getW() ) : fabsf( vec0.getW() ) ); } inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ(), (vec0.getW() > vec1.getW())? vec0.getW() : vec1.getW() ); } inline float maxElem( const Vector4 & vec ) { float result; result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); result = (vec.getZ() > result)? vec.getZ() : result; result = (vec.getW() > result)? vec.getW() : result; return result; } inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ(), (vec0.getW() < vec1.getW())? vec0.getW() : vec1.getW() ); } inline float minElem( const Vector4 & vec ) { float result; result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); result = (vec.getZ() < result)? vec.getZ() : result; result = (vec.getW() < result)? vec.getW() : result; return result; } inline float sum( const Vector4 & vec ) { float result; result = ( vec.getX() + vec.getY() ); result = ( result + vec.getZ() ); result = ( result + vec.getW() ); return result; } inline float dot( const Vector4 & vec0, const Vector4 & vec1 ) { float result; result = ( vec0.getX() * vec1.getX() ); result = ( result + ( vec0.getY() * vec1.getY() ) ); result = ( result + ( vec0.getZ() * vec1.getZ() ) ); result = ( result + ( vec0.getW() * vec1.getW() ) ); return result; } inline float lengthSqr( const Vector4 & vec ) { float result; result = ( vec.getX() * vec.getX() ); result = ( result + ( vec.getY() * vec.getY() ) ); result = ( result + ( vec.getZ() * vec.getZ() ) ); result = ( result + ( vec.getW() * vec.getW() ) ); return result; } inline float length( const Vector4 & vec ) { return sqrtf( lengthSqr( vec ) ); } inline const Vector4 normalize( const Vector4 & vec ) { float lenSqr, lenInv; lenSqr = lengthSqr( vec ); lenInv = ( 1.0f / sqrtf( lenSqr ) ); return Vector4( ( vec.getX() * lenInv ), ( vec.getY() * lenInv ), ( vec.getZ() * lenInv ), ( vec.getW() * lenInv ) ); } inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ) { return Vector4( ( select1 )? vec1.getX() : vec0.getX(), ( select1 )? vec1.getY() : vec0.getY(), ( select1 )? vec1.getZ() : vec0.getZ(), ( select1 )? vec1.getW() : vec0.getW() ); } #ifdef _VECTORMATH_DEBUG inline void print( const Vector4 & vec ) { printf( "( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); } inline void print( const Vector4 & vec, const char * name ) { printf( "%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); } #endif inline Point3::Point3( const Point3 & pnt ) { mX = pnt.mX; mY = pnt.mY; mZ = pnt.mZ; } inline Point3::Point3( float _x, float _y, float _z ) { mX = _x; mY = _y; mZ = _z; } inline Point3::Point3( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); } inline Point3::Point3( float scalar ) { mX = scalar; mY = scalar; mZ = scalar; } inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ) { return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); } inline Point3 & Point3::operator =( const Point3 & pnt ) { mX = pnt.mX; mY = pnt.mY; mZ = pnt.mZ; return *this; } inline Point3 & Point3::setX( float _x ) { mX = _x; return *this; } inline float Point3::getX( ) const { return mX; } inline Point3 & Point3::setY( float _y ) { mY = _y; return *this; } inline float Point3::getY( ) const { return mY; } inline Point3 & Point3::setZ( float _z ) { mZ = _z; return *this; } inline float Point3::getZ( ) const { return mZ; } inline Point3 & Point3::setElem( int idx, float value ) { *(&mX + idx) = value; return *this; } inline float Point3::getElem( int idx ) const { return *(&mX + idx); } inline float & Point3::operator []( int idx ) { return *(&mX + idx); } inline float Point3::operator []( int idx ) const { return *(&mX + idx); } inline const Vector3 Point3::operator -( const Point3 & pnt ) const { return Vector3( ( mX - pnt.mX ), ( mY - pnt.mY ), ( mZ - pnt.mZ ) ); } inline const Point3 Point3::operator +( const Vector3 & vec ) const { return Point3( ( mX + vec.getX() ), ( mY + vec.getY() ), ( mZ + vec.getZ() ) ); } inline const Point3 Point3::operator -( const Vector3 & vec ) const { return Point3( ( mX - vec.getX() ), ( mY - vec.getY() ), ( mZ - vec.getZ() ) ); } inline Point3 & Point3::operator +=( const Vector3 & vec ) { *this = *this + vec; return *this; } inline Point3 & Point3::operator -=( const Vector3 & vec ) { *this = *this - vec; return *this; } inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( ( pnt0.getX() * pnt1.getX() ), ( pnt0.getY() * pnt1.getY() ), ( pnt0.getZ() * pnt1.getZ() ) ); } inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( ( pnt0.getX() / pnt1.getX() ), ( pnt0.getY() / pnt1.getY() ), ( pnt0.getZ() / pnt1.getZ() ) ); } inline const Point3 recipPerElem( const Point3 & pnt ) { return Point3( ( 1.0f / pnt.getX() ), ( 1.0f / pnt.getY() ), ( 1.0f / pnt.getZ() ) ); } inline const Point3 sqrtPerElem( const Point3 & pnt ) { return Point3( sqrtf( pnt.getX() ), sqrtf( pnt.getY() ), sqrtf( pnt.getZ() ) ); } inline const Point3 rsqrtPerElem( const Point3 & pnt ) { return Point3( ( 1.0f / sqrtf( pnt.getX() ) ), ( 1.0f / sqrtf( pnt.getY() ) ), ( 1.0f / sqrtf( pnt.getZ() ) ) ); } inline const Point3 absPerElem( const Point3 & pnt ) { return Point3( fabsf( pnt.getX() ), fabsf( pnt.getY() ), fabsf( pnt.getZ() ) ); } inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( ( pnt1.getX() < 0.0f )? -fabsf( pnt0.getX() ) : fabsf( pnt0.getX() ), ( pnt1.getY() < 0.0f )? -fabsf( pnt0.getY() ) : fabsf( pnt0.getY() ), ( pnt1.getZ() < 0.0f )? -fabsf( pnt0.getZ() ) : fabsf( pnt0.getZ() ) ); } inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( (pnt0.getX() > pnt1.getX())? pnt0.getX() : pnt1.getX(), (pnt0.getY() > pnt1.getY())? pnt0.getY() : pnt1.getY(), (pnt0.getZ() > pnt1.getZ())? pnt0.getZ() : pnt1.getZ() ); } inline float maxElem( const Point3 & pnt ) { float result; result = (pnt.getX() > pnt.getY())? pnt.getX() : pnt.getY(); result = (pnt.getZ() > result)? pnt.getZ() : result; return result; } inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( (pnt0.getX() < pnt1.getX())? pnt0.getX() : pnt1.getX(), (pnt0.getY() < pnt1.getY())? pnt0.getY() : pnt1.getY(), (pnt0.getZ() < pnt1.getZ())? pnt0.getZ() : pnt1.getZ() ); } inline float minElem( const Point3 & pnt ) { float result; result = (pnt.getX() < pnt.getY())? pnt.getX() : pnt.getY(); result = (pnt.getZ() < result)? pnt.getZ() : result; return result; } inline float sum( const Point3 & pnt ) { float result; result = ( pnt.getX() + pnt.getY() ); result = ( result + pnt.getZ() ); return result; } inline const Point3 scale( const Point3 & pnt, float scaleVal ) { return mulPerElem( pnt, Point3( scaleVal ) ); } inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) { return mulPerElem( pnt, Point3( scaleVec ) ); } inline float projection( const Point3 & pnt, const Vector3 & unitVec ) { float result; result = ( pnt.getX() * unitVec.getX() ); result = ( result + ( pnt.getY() * unitVec.getY() ) ); result = ( result + ( pnt.getZ() * unitVec.getZ() ) ); return result; } inline float distSqrFromOrigin( const Point3 & pnt ) { return lengthSqr( Vector3( pnt ) ); } inline float distFromOrigin( const Point3 & pnt ) { return length( Vector3( pnt ) ); } inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ) { return lengthSqr( ( pnt1 - pnt0 ) ); } inline float dist( const Point3 & pnt0, const Point3 & pnt1 ) { return length( ( pnt1 - pnt0 ) ); } inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ) { return Point3( ( select1 )? pnt1.getX() : pnt0.getX(), ( select1 )? pnt1.getY() : pnt0.getY(), ( select1 )? pnt1.getZ() : pnt0.getZ() ); } #ifdef _VECTORMATH_DEBUG inline void print( const Point3 & pnt ) { printf( "( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ() ); } inline void print( const Point3 & pnt, const char * name ) { printf( "%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ() ); } #endif } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/scalar/cpp/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_CPP_SCALAR_H #define _VECTORMATH_AOS_CPP_SCALAR_H #include #ifdef _VECTORMATH_DEBUG #include #endif namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // Forward Declarations // class Vector3; class Vector4; class Point3; class Quat; class Matrix3; class Matrix4; class Transform3; // A 3-D vector in array-of-structures format // class Vector3 { float mX; float mY; float mZ; #ifndef __GNUC__ float d; #endif public: // Default constructor; does no initialization // inline Vector3( ) { }; // Copy a 3-D vector // inline Vector3( const Vector3 & vec ); // Construct a 3-D vector from x, y, and z elements // inline Vector3( float x, float y, float z ); // Copy elements from a 3-D point into a 3-D vector // explicit inline Vector3( const Point3 & pnt ); // Set all elements of a 3-D vector to the same scalar value // explicit inline Vector3( float scalar ); // Assign one 3-D vector to another // inline Vector3 & operator =( const Vector3 & vec ); // Set the x element of a 3-D vector // inline Vector3 & setX( float x ); // Set the y element of a 3-D vector // inline Vector3 & setY( float y ); // Set the z element of a 3-D vector // inline Vector3 & setZ( float z ); // Get the x element of a 3-D vector // inline float getX( ) const; // Get the y element of a 3-D vector // inline float getY( ) const; // Get the z element of a 3-D vector // inline float getZ( ) const; // Set an x, y, or z element of a 3-D vector by index // inline Vector3 & setElem( int idx, float value ); // Get an x, y, or z element of a 3-D vector by index // inline float getElem( int idx ) const; // Subscripting operator to set or get an element // inline float & operator []( int idx ); // Subscripting operator to get an element // inline float operator []( int idx ) const; // Add two 3-D vectors // inline const Vector3 operator +( const Vector3 & vec ) const; // Subtract a 3-D vector from another 3-D vector // inline const Vector3 operator -( const Vector3 & vec ) const; // Add a 3-D vector to a 3-D point // inline const Point3 operator +( const Point3 & pnt ) const; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( float scalar ) const; // Divide a 3-D vector by a scalar // inline const Vector3 operator /( float scalar ) const; // Perform compound assignment and addition with a 3-D vector // inline Vector3 & operator +=( const Vector3 & vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Vector3 & operator -=( const Vector3 & vec ); // Perform compound assignment and multiplication by a scalar // inline Vector3 & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Vector3 & operator /=( float scalar ); // Negate all elements of a 3-D vector // inline const Vector3 operator -( ) const; // Construct x axis // static inline const Vector3 xAxis( ); // Construct y axis // static inline const Vector3 yAxis( ); // Construct z axis // static inline const Vector3 zAxis( ); } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif ; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( float scalar, const Vector3 & vec ); // Multiply two 3-D vectors per element // inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Divide two 3-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Compute the reciprocal of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector3 recipPerElem( const Vector3 & vec ); // Compute the square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector3 sqrtPerElem( const Vector3 & vec ); // Compute the reciprocal square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector3 rsqrtPerElem( const Vector3 & vec ); // Compute the absolute value of a 3-D vector per element // inline const Vector3 absPerElem( const Vector3 & vec ); // Copy sign from one 3-D vector to another, per element // inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Maximum of two 3-D vectors per element // inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Minimum of two 3-D vectors per element // inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Maximum element of a 3-D vector // inline float maxElem( const Vector3 & vec ); // Minimum element of a 3-D vector // inline float minElem( const Vector3 & vec ); // Compute the sum of all elements of a 3-D vector // inline float sum( const Vector3 & vec ); // Compute the dot product of two 3-D vectors // inline float dot( const Vector3 & vec0, const Vector3 & vec1 ); // Compute the square of the length of a 3-D vector // inline float lengthSqr( const Vector3 & vec ); // Compute the length of a 3-D vector // inline float length( const Vector3 & vec ); // Normalize a 3-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector3 normalize( const Vector3 & vec ); // Compute cross product of two 3-D vectors // inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); // Outer product of two 3-D vectors // inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); // Pre-multiply a row vector by a 3x3 matrix // inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); // Cross-product matrix of a 3-D vector // inline const Matrix3 crossMatrix( const Vector3 & vec ); // Create cross-product matrix and multiply // NOTE: // Faster than separately creating a cross-product matrix and multiplying. // inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); // Linear interpolation between two 3-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ); // Spherical linear interpolation between two 3-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); // Conditionally select between two 3-D vectors // inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector3 & vec ); // Print a 3-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector3 & vec, const char * name ); #endif // A 4-D vector in array-of-structures format // class Vector4 { float mX; float mY; float mZ; float mW; public: // Default constructor; does no initialization // inline Vector4( ) { }; // Copy a 4-D vector // inline Vector4( const Vector4 & vec ); // Construct a 4-D vector from x, y, z, and w elements // inline Vector4( float x, float y, float z, float w ); // Construct a 4-D vector from a 3-D vector and a scalar // inline Vector4( const Vector3 & xyz, float w ); // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 // explicit inline Vector4( const Vector3 & vec ); // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 // explicit inline Vector4( const Point3 & pnt ); // Copy elements from a quaternion into a 4-D vector // explicit inline Vector4( const Quat & quat ); // Set all elements of a 4-D vector to the same scalar value // explicit inline Vector4( float scalar ); // Assign one 4-D vector to another // inline Vector4 & operator =( const Vector4 & vec ); // Set the x, y, and z elements of a 4-D vector // NOTE: // This function does not change the w element. // inline Vector4 & setXYZ( const Vector3 & vec ); // Get the x, y, and z elements of a 4-D vector // inline const Vector3 getXYZ( ) const; // Set the x element of a 4-D vector // inline Vector4 & setX( float x ); // Set the y element of a 4-D vector // inline Vector4 & setY( float y ); // Set the z element of a 4-D vector // inline Vector4 & setZ( float z ); // Set the w element of a 4-D vector // inline Vector4 & setW( float w ); // Get the x element of a 4-D vector // inline float getX( ) const; // Get the y element of a 4-D vector // inline float getY( ) const; // Get the z element of a 4-D vector // inline float getZ( ) const; // Get the w element of a 4-D vector // inline float getW( ) const; // Set an x, y, z, or w element of a 4-D vector by index // inline Vector4 & setElem( int idx, float value ); // Get an x, y, z, or w element of a 4-D vector by index // inline float getElem( int idx ) const; // Subscripting operator to set or get an element // inline float & operator []( int idx ); // Subscripting operator to get an element // inline float operator []( int idx ) const; // Add two 4-D vectors // inline const Vector4 operator +( const Vector4 & vec ) const; // Subtract a 4-D vector from another 4-D vector // inline const Vector4 operator -( const Vector4 & vec ) const; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( float scalar ) const; // Divide a 4-D vector by a scalar // inline const Vector4 operator /( float scalar ) const; // Perform compound assignment and addition with a 4-D vector // inline Vector4 & operator +=( const Vector4 & vec ); // Perform compound assignment and subtraction by a 4-D vector // inline Vector4 & operator -=( const Vector4 & vec ); // Perform compound assignment and multiplication by a scalar // inline Vector4 & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Vector4 & operator /=( float scalar ); // Negate all elements of a 4-D vector // inline const Vector4 operator -( ) const; // Construct x axis // static inline const Vector4 xAxis( ); // Construct y axis // static inline const Vector4 yAxis( ); // Construct z axis // static inline const Vector4 zAxis( ); // Construct w axis // static inline const Vector4 wAxis( ); } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif ; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( float scalar, const Vector4 & vec ); // Multiply two 4-D vectors per element // inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Divide two 4-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Compute the reciprocal of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector4 recipPerElem( const Vector4 & vec ); // Compute the square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector4 sqrtPerElem( const Vector4 & vec ); // Compute the reciprocal square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector4 rsqrtPerElem( const Vector4 & vec ); // Compute the absolute value of a 4-D vector per element // inline const Vector4 absPerElem( const Vector4 & vec ); // Copy sign from one 4-D vector to another, per element // inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Maximum of two 4-D vectors per element // inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Minimum of two 4-D vectors per element // inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Maximum element of a 4-D vector // inline float maxElem( const Vector4 & vec ); // Minimum element of a 4-D vector // inline float minElem( const Vector4 & vec ); // Compute the sum of all elements of a 4-D vector // inline float sum( const Vector4 & vec ); // Compute the dot product of two 4-D vectors // inline float dot( const Vector4 & vec0, const Vector4 & vec1 ); // Compute the square of the length of a 4-D vector // inline float lengthSqr( const Vector4 & vec ); // Compute the length of a 4-D vector // inline float length( const Vector4 & vec ); // Normalize a 4-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector4 normalize( const Vector4 & vec ); // Outer product of two 4-D vectors // inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); // Linear interpolation between two 4-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ); // Spherical linear interpolation between two 4-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); // Conditionally select between two 4-D vectors // inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector4 & vec ); // Print a 4-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector4 & vec, const char * name ); #endif // A 3-D point in array-of-structures format // class Point3 { float mX; float mY; float mZ; #ifndef __GNUC__ float d; #endif public: // Default constructor; does no initialization // inline Point3( ) { }; // Copy a 3-D point // inline Point3( const Point3 & pnt ); // Construct a 3-D point from x, y, and z elements // inline Point3( float x, float y, float z ); // Copy elements from a 3-D vector into a 3-D point // explicit inline Point3( const Vector3 & vec ); // Set all elements of a 3-D point to the same scalar value // explicit inline Point3( float scalar ); // Assign one 3-D point to another // inline Point3 & operator =( const Point3 & pnt ); // Set the x element of a 3-D point // inline Point3 & setX( float x ); // Set the y element of a 3-D point // inline Point3 & setY( float y ); // Set the z element of a 3-D point // inline Point3 & setZ( float z ); // Get the x element of a 3-D point // inline float getX( ) const; // Get the y element of a 3-D point // inline float getY( ) const; // Get the z element of a 3-D point // inline float getZ( ) const; // Set an x, y, or z element of a 3-D point by index // inline Point3 & setElem( int idx, float value ); // Get an x, y, or z element of a 3-D point by index // inline float getElem( int idx ) const; // Subscripting operator to set or get an element // inline float & operator []( int idx ); // Subscripting operator to get an element // inline float operator []( int idx ) const; // Subtract a 3-D point from another 3-D point // inline const Vector3 operator -( const Point3 & pnt ) const; // Add a 3-D point to a 3-D vector // inline const Point3 operator +( const Vector3 & vec ) const; // Subtract a 3-D vector from a 3-D point // inline const Point3 operator -( const Vector3 & vec ) const; // Perform compound assignment and addition with a 3-D vector // inline Point3 & operator +=( const Vector3 & vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Point3 & operator -=( const Vector3 & vec ); } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif ; // Multiply two 3-D points per element // inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Divide two 3-D points per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Compute the reciprocal of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Point3 recipPerElem( const Point3 & pnt ); // Compute the square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Point3 sqrtPerElem( const Point3 & pnt ); // Compute the reciprocal square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Point3 rsqrtPerElem( const Point3 & pnt ); // Compute the absolute value of a 3-D point per element // inline const Point3 absPerElem( const Point3 & pnt ); // Copy sign from one 3-D point to another, per element // inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Maximum of two 3-D points per element // inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Minimum of two 3-D points per element // inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Maximum element of a 3-D point // inline float maxElem( const Point3 & pnt ); // Minimum element of a 3-D point // inline float minElem( const Point3 & pnt ); // Compute the sum of all elements of a 3-D point // inline float sum( const Point3 & pnt ); // Apply uniform scale to a 3-D point // inline const Point3 scale( const Point3 & pnt, float scaleVal ); // Apply non-uniform scale to a 3-D point // inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); // Scalar projection of a 3-D point on a unit-length 3-D vector // inline float projection( const Point3 & pnt, const Vector3 & unitVec ); // Compute the square of the distance of a 3-D point from the coordinate-system origin // inline float distSqrFromOrigin( const Point3 & pnt ); // Compute the distance of a 3-D point from the coordinate-system origin // inline float distFromOrigin( const Point3 & pnt ); // Compute the square of the distance between two 3-D points // inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ); // Compute the distance between two 3-D points // inline float dist( const Point3 & pnt0, const Point3 & pnt1 ); // Linear interpolation between two 3-D points // NOTE: // Does not clamp t between 0 and 1. // inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ); // Conditionally select between two 3-D points // inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3-D point // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Point3 & pnt ); // Print a 3-D point and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Point3 & pnt, const char * name ); #endif // A quaternion in array-of-structures format // class Quat { float mX; float mY; float mZ; float mW; public: // Default constructor; does no initialization // inline Quat( ) { }; // Copy a quaternion // inline Quat( const Quat & quat ); // Construct a quaternion from x, y, z, and w elements // inline Quat( float x, float y, float z, float w ); // Construct a quaternion from a 3-D vector and a scalar // inline Quat( const Vector3 & xyz, float w ); // Copy elements from a 4-D vector into a quaternion // explicit inline Quat( const Vector4 & vec ); // Convert a rotation matrix to a unit-length quaternion // explicit inline Quat( const Matrix3 & rotMat ); // Set all elements of a quaternion to the same scalar value // explicit inline Quat( float scalar ); // Assign one quaternion to another // inline Quat & operator =( const Quat & quat ); // Set the x, y, and z elements of a quaternion // NOTE: // This function does not change the w element. // inline Quat & setXYZ( const Vector3 & vec ); // Get the x, y, and z elements of a quaternion // inline const Vector3 getXYZ( ) const; // Set the x element of a quaternion // inline Quat & setX( float x ); // Set the y element of a quaternion // inline Quat & setY( float y ); // Set the z element of a quaternion // inline Quat & setZ( float z ); // Set the w element of a quaternion // inline Quat & setW( float w ); // Get the x element of a quaternion // inline float getX( ) const; // Get the y element of a quaternion // inline float getY( ) const; // Get the z element of a quaternion // inline float getZ( ) const; // Get the w element of a quaternion // inline float getW( ) const; // Set an x, y, z, or w element of a quaternion by index // inline Quat & setElem( int idx, float value ); // Get an x, y, z, or w element of a quaternion by index // inline float getElem( int idx ) const; // Subscripting operator to set or get an element // inline float & operator []( int idx ); // Subscripting operator to get an element // inline float operator []( int idx ) const; // Add two quaternions // inline const Quat operator +( const Quat & quat ) const; // Subtract a quaternion from another quaternion // inline const Quat operator -( const Quat & quat ) const; // Multiply two quaternions // inline const Quat operator *( const Quat & quat ) const; // Multiply a quaternion by a scalar // inline const Quat operator *( float scalar ) const; // Divide a quaternion by a scalar // inline const Quat operator /( float scalar ) const; // Perform compound assignment and addition with a quaternion // inline Quat & operator +=( const Quat & quat ); // Perform compound assignment and subtraction by a quaternion // inline Quat & operator -=( const Quat & quat ); // Perform compound assignment and multiplication by a quaternion // inline Quat & operator *=( const Quat & quat ); // Perform compound assignment and multiplication by a scalar // inline Quat & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Quat & operator /=( float scalar ); // Negate all elements of a quaternion // inline const Quat operator -( ) const; // Construct an identity quaternion // static inline const Quat identity( ); // Construct a quaternion to rotate between two unit-length 3-D vectors // NOTE: // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. // static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); // Construct a quaternion to rotate around a unit-length 3-D vector // static inline const Quat rotation( float radians, const Vector3 & unitVec ); // Construct a quaternion to rotate around the x axis // static inline const Quat rotationX( float radians ); // Construct a quaternion to rotate around the y axis // static inline const Quat rotationY( float radians ); // Construct a quaternion to rotate around the z axis // static inline const Quat rotationZ( float radians ); } #ifdef __GNUC__ __attribute__ ((aligned(16))) #endif ; // Multiply a quaternion by a scalar // inline const Quat operator *( float scalar, const Quat & quat ); // Compute the conjugate of a quaternion // inline const Quat conj( const Quat & quat ); // Use a unit-length quaternion to rotate a 3-D vector // inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); // Compute the dot product of two quaternions // inline float dot( const Quat & quat0, const Quat & quat1 ); // Compute the norm of a quaternion // inline float norm( const Quat & quat ); // Compute the length of a quaternion // inline float length( const Quat & quat ); // Normalize a quaternion // NOTE: // The result is unpredictable when all elements of quat are at or near zero. // inline const Quat normalize( const Quat & quat ); // Linear interpolation between two quaternions // NOTE: // Does not clamp t between 0 and 1. // inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ); // Spherical linear interpolation between two quaternions // NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. // inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ); // Spherical quadrangle interpolation // inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); // Conditionally select between two quaternions // inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a quaternion // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Quat & quat ); // Print a quaternion and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Quat & quat, const char * name ); #endif // A 3x3 matrix in array-of-structures format // class Matrix3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; public: // Default constructor; does no initialization // inline Matrix3( ) { }; // Copy a 3x3 matrix // inline Matrix3( const Matrix3 & mat ); // Construct a 3x3 matrix containing the specified columns // inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); // Construct a 3x3 rotation matrix from a unit-length quaternion // explicit inline Matrix3( const Quat & unitQuat ); // Set all elements of a 3x3 matrix to the same scalar value // explicit inline Matrix3( float scalar ); // Assign one 3x3 matrix to another // inline Matrix3 & operator =( const Matrix3 & mat ); // Set column 0 of a 3x3 matrix // inline Matrix3 & setCol0( const Vector3 & col0 ); // Set column 1 of a 3x3 matrix // inline Matrix3 & setCol1( const Vector3 & col1 ); // Set column 2 of a 3x3 matrix // inline Matrix3 & setCol2( const Vector3 & col2 ); // Get column 0 of a 3x3 matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x3 matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x3 matrix // inline const Vector3 getCol2( ) const; // Set the column of a 3x3 matrix referred to by the specified index // inline Matrix3 & setCol( int col, const Vector3 & vec ); // Set the row of a 3x3 matrix referred to by the specified index // inline Matrix3 & setRow( int row, const Vector3 & vec ); // Get the column of a 3x3 matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x3 matrix referred to by the specified index // inline const Vector3 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x3 matrix referred to by column and row indices // inline Matrix3 & setElem( int col, int row, float val ); // Get the element of a 3x3 matrix referred to by column and row indices // inline float getElem( int col, int row ) const; // Add two 3x3 matrices // inline const Matrix3 operator +( const Matrix3 & mat ) const; // Subtract a 3x3 matrix from another 3x3 matrix // inline const Matrix3 operator -( const Matrix3 & mat ) const; // Negate all elements of a 3x3 matrix // inline const Matrix3 operator -( ) const; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( float scalar ) const; // Multiply a 3x3 matrix by a 3-D vector // inline const Vector3 operator *( const Vector3 & vec ) const; // Multiply two 3x3 matrices // inline const Matrix3 operator *( const Matrix3 & mat ) const; // Perform compound assignment and addition with a 3x3 matrix // inline Matrix3 & operator +=( const Matrix3 & mat ); // Perform compound assignment and subtraction by a 3x3 matrix // inline Matrix3 & operator -=( const Matrix3 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix3 & operator *=( float scalar ); // Perform compound assignment and multiplication by a 3x3 matrix // inline Matrix3 & operator *=( const Matrix3 & mat ); // Construct an identity 3x3 matrix // static inline const Matrix3 identity( ); // Construct a 3x3 matrix to rotate around the x axis // static inline const Matrix3 rotationX( float radians ); // Construct a 3x3 matrix to rotate around the y axis // static inline const Matrix3 rotationY( float radians ); // Construct a 3x3 matrix to rotate around the z axis // static inline const Matrix3 rotationZ( float radians ); // Construct a 3x3 matrix to rotate around the x, y, and z axes // static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 3x3 matrix to rotate around a unit-length 3-D vector // static inline const Matrix3 rotation( float radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix3 rotation( const Quat & unitQuat ); // Construct a 3x3 matrix to perform scaling // static inline const Matrix3 scale( const Vector3 & scaleVec ); }; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); // Append (post-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); // Multiply two 3x3 matrices per element // inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); // Compute the absolute value of a 3x3 matrix per element // inline const Matrix3 absPerElem( const Matrix3 & mat ); // Transpose of a 3x3 matrix // inline const Matrix3 transpose( const Matrix3 & mat ); // Compute the inverse of a 3x3 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix3 inverse( const Matrix3 & mat ); // Determinant of a 3x3 matrix // inline float determinant( const Matrix3 & mat ); // Conditionally select between two 3x3 matrices // inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat ); // Print a 3x3 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat, const char * name ); #endif // A 4x4 matrix in array-of-structures format // class Matrix4 { Vector4 mCol0; Vector4 mCol1; Vector4 mCol2; Vector4 mCol3; public: // Default constructor; does no initialization // inline Matrix4( ) { }; // Copy a 4x4 matrix // inline Matrix4( const Matrix4 & mat ); // Construct a 4x4 matrix containing the specified columns // inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); // Construct a 4x4 matrix from a 3x4 transformation matrix // explicit inline Matrix4( const Transform3 & mat ); // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector // inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector // inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); // Set all elements of a 4x4 matrix to the same scalar value // explicit inline Matrix4( float scalar ); // Assign one 4x4 matrix to another // inline Matrix4 & operator =( const Matrix4 & mat ); // Set the upper-left 3x3 submatrix // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 4x4 matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setTranslation( const Vector3 & translateVec ); // Get the translation component of a 4x4 matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 4x4 matrix // inline Matrix4 & setCol0( const Vector4 & col0 ); // Set column 1 of a 4x4 matrix // inline Matrix4 & setCol1( const Vector4 & col1 ); // Set column 2 of a 4x4 matrix // inline Matrix4 & setCol2( const Vector4 & col2 ); // Set column 3 of a 4x4 matrix // inline Matrix4 & setCol3( const Vector4 & col3 ); // Get column 0 of a 4x4 matrix // inline const Vector4 getCol0( ) const; // Get column 1 of a 4x4 matrix // inline const Vector4 getCol1( ) const; // Get column 2 of a 4x4 matrix // inline const Vector4 getCol2( ) const; // Get column 3 of a 4x4 matrix // inline const Vector4 getCol3( ) const; // Set the column of a 4x4 matrix referred to by the specified index // inline Matrix4 & setCol( int col, const Vector4 & vec ); // Set the row of a 4x4 matrix referred to by the specified index // inline Matrix4 & setRow( int row, const Vector4 & vec ); // Get the column of a 4x4 matrix referred to by the specified index // inline const Vector4 getCol( int col ) const; // Get the row of a 4x4 matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector4 & operator []( int col ); // Subscripting operator to get a column // inline const Vector4 operator []( int col ) const; // Set the element of a 4x4 matrix referred to by column and row indices // inline Matrix4 & setElem( int col, int row, float val ); // Get the element of a 4x4 matrix referred to by column and row indices // inline float getElem( int col, int row ) const; // Add two 4x4 matrices // inline const Matrix4 operator +( const Matrix4 & mat ) const; // Subtract a 4x4 matrix from another 4x4 matrix // inline const Matrix4 operator -( const Matrix4 & mat ) const; // Negate all elements of a 4x4 matrix // inline const Matrix4 operator -( ) const; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( float scalar ) const; // Multiply a 4x4 matrix by a 4-D vector // inline const Vector4 operator *( const Vector4 & vec ) const; // Multiply a 4x4 matrix by a 3-D vector // inline const Vector4 operator *( const Vector3 & vec ) const; // Multiply a 4x4 matrix by a 3-D point // inline const Vector4 operator *( const Point3 & pnt ) const; // Multiply two 4x4 matrices // inline const Matrix4 operator *( const Matrix4 & mat ) const; // Multiply a 4x4 matrix by a 3x4 transformation matrix // inline const Matrix4 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and addition with a 4x4 matrix // inline Matrix4 & operator +=( const Matrix4 & mat ); // Perform compound assignment and subtraction by a 4x4 matrix // inline Matrix4 & operator -=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix4 & operator *=( float scalar ); // Perform compound assignment and multiplication by a 4x4 matrix // inline Matrix4 & operator *=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Matrix4 & operator *=( const Transform3 & tfrm ); // Construct an identity 4x4 matrix // static inline const Matrix4 identity( ); // Construct a 4x4 matrix to rotate around the x axis // static inline const Matrix4 rotationX( float radians ); // Construct a 4x4 matrix to rotate around the y axis // static inline const Matrix4 rotationY( float radians ); // Construct a 4x4 matrix to rotate around the z axis // static inline const Matrix4 rotationZ( float radians ); // Construct a 4x4 matrix to rotate around the x, y, and z axes // static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 4x4 matrix to rotate around a unit-length 3-D vector // static inline const Matrix4 rotation( float radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix4 rotation( const Quat & unitQuat ); // Construct a 4x4 matrix to perform scaling // static inline const Matrix4 scale( const Vector3 & scaleVec ); // Construct a 4x4 matrix to perform translation // static inline const Matrix4 translation( const Vector3 & translateVec ); // Construct viewing matrix based on eye position, position looked at, and up direction // static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); // Construct a perspective projection matrix // static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); // Construct a perspective projection matrix based on frustum // static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); // Construct an orthographic projection matrix // static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); }; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); // Append (post-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); // Multiply two 4x4 matrices per element // inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); // Compute the absolute value of a 4x4 matrix per element // inline const Matrix4 absPerElem( const Matrix4 & mat ); // Transpose of a 4x4 matrix // inline const Matrix4 transpose( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix4 inverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix // NOTE: // 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. // inline const Matrix4 affineInverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. // inline const Matrix4 orthoInverse( const Matrix4 & mat ); // Determinant of a 4x4 matrix // inline float determinant( const Matrix4 & mat ); // Conditionally select between two 4x4 matrices // inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat ); // Print a 4x4 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat, const char * name ); #endif // A 3x4 transformation matrix in array-of-structures format // class Transform3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; Vector3 mCol3; public: // Default constructor; does no initialization // inline Transform3( ) { }; // Copy a 3x4 transformation matrix // inline Transform3( const Transform3 & tfrm ); // Construct a 3x4 transformation matrix containing the specified columns // inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector // inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector // inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); // Set all elements of a 3x4 transformation matrix to the same scalar value // explicit inline Transform3( float scalar ); // Assign one 3x4 transformation matrix to another // inline Transform3 & operator =( const Transform3 & tfrm ); // Set the upper-left 3x3 submatrix // inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // inline Transform3 & setTranslation( const Vector3 & translateVec ); // Get the translation component of a 3x4 transformation matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 3x4 transformation matrix // inline Transform3 & setCol0( const Vector3 & col0 ); // Set column 1 of a 3x4 transformation matrix // inline Transform3 & setCol1( const Vector3 & col1 ); // Set column 2 of a 3x4 transformation matrix // inline Transform3 & setCol2( const Vector3 & col2 ); // Set column 3 of a 3x4 transformation matrix // inline Transform3 & setCol3( const Vector3 & col3 ); // Get column 0 of a 3x4 transformation matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x4 transformation matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x4 transformation matrix // inline const Vector3 getCol2( ) const; // Get column 3 of a 3x4 transformation matrix // inline const Vector3 getCol3( ) const; // Set the column of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setCol( int col, const Vector3 & vec ); // Set the row of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setRow( int row, const Vector4 & vec ); // Get the column of a 3x4 transformation matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x4 transformation matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x4 transformation matrix referred to by column and row indices // inline Transform3 & setElem( int col, int row, float val ); // Get the element of a 3x4 transformation matrix referred to by column and row indices // inline float getElem( int col, int row ) const; // Multiply a 3x4 transformation matrix by a 3-D vector // inline const Vector3 operator *( const Vector3 & vec ) const; // Multiply a 3x4 transformation matrix by a 3-D point // inline const Point3 operator *( const Point3 & pnt ) const; // Multiply two 3x4 transformation matrices // inline const Transform3 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Transform3 & operator *=( const Transform3 & tfrm ); // Construct an identity 3x4 transformation matrix // static inline const Transform3 identity( ); // Construct a 3x4 transformation matrix to rotate around the x axis // static inline const Transform3 rotationX( float radians ); // Construct a 3x4 transformation matrix to rotate around the y axis // static inline const Transform3 rotationY( float radians ); // Construct a 3x4 transformation matrix to rotate around the z axis // static inline const Transform3 rotationZ( float radians ); // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes // static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector // static inline const Transform3 rotation( float radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Transform3 rotation( const Quat & unitQuat ); // Construct a 3x4 transformation matrix to perform scaling // static inline const Transform3 scale( const Vector3 & scaleVec ); // Construct a 3x4 transformation matrix to perform translation // static inline const Transform3 translation( const Vector3 & translateVec ); }; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); // Multiply two 3x4 transformation matrices per element // inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); // Compute the absolute value of a 3x4 transformation matrix per element // inline const Transform3 absPerElem( const Transform3 & tfrm ); // Inverse of a 3x4 transformation matrix // NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. // inline const Transform3 inverse( const Transform3 & tfrm ); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. // inline const Transform3 orthoInverse( const Transform3 & tfrm ); // Conditionally select between two 3x4 transformation matrices // inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm ); // Print a 3x4 transformation matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm, const char * name ); #endif } // namespace Aos } // namespace Vectormath #include "vec_aos.h" #include "quat_aos.h" #include "mat_aos.h" #endif ================================================ FILE: samples/vectormath/spu/c/mat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_C_H #define _VECTORMATH_MAT_AOS_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for shuffles, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_0ZB0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_C0X0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_YA00 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_Z }) #define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X }) #define _VECTORMATH_SHUF_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y }) #define _VECTORMATH_SHUF_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZAY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_BZX0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_0ZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A }) #define _VECTORMATH_SHUF_Z0XB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YX0C ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_CZD0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_BBY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( &result->col0, &mat->col0 ); vmathV3Copy( &result->col1, &mat->col1 ); vmathV3Copy( &result->col2, &mat->col2 ); } static inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar ) { vmathV3MakeFromScalar( &result->col0, scalar ); vmathV3MakeFromScalar( &result->col1, scalar ); vmathV3MakeFromScalar( &result->col2, scalar ); } static inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat ) { vec_float4 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); vec_uint4 select_x = (vec_uint4)spu_maskb(0xf000); vec_uint4 select_z = (vec_uint4)spu_maskb(0x00f0); xyzw_2 = spu_add( unitQuat->vec128, unitQuat->vec128 ); wwww = spu_shuffle( unitQuat->vec128, unitQuat->vec128, shuffle_wwww ); yzxw = spu_shuffle( unitQuat->vec128, unitQuat->vec128, _VECTORMATH_SHUF_YZXW ); zxyw = spu_shuffle( unitQuat->vec128, unitQuat->vec128, _VECTORMATH_SHUF_ZXYW ); yzxw_2 = spu_shuffle( xyzw_2, xyzw_2, _VECTORMATH_SHUF_YZXW ); zxyw_2 = spu_shuffle( xyzw_2, xyzw_2, _VECTORMATH_SHUF_ZXYW ); tmp0 = spu_mul( yzxw_2, wwww ); tmp1 = spu_nmsub( yzxw, yzxw_2, spu_splats(1.0f) ); tmp2 = spu_mul( yzxw, xyzw_2 ); tmp0 = spu_madd( zxyw, xyzw_2, tmp0 ); tmp1 = spu_nmsub( zxyw, zxyw_2, tmp1 ); tmp2 = spu_nmsub( zxyw_2, wwww, tmp2 ); tmp3 = spu_sel( tmp0, tmp1, select_x ); tmp4 = spu_sel( tmp1, tmp2, select_x ); tmp5 = spu_sel( tmp2, tmp0, select_x ); result->col0.vec128 = spu_sel( tmp3, tmp2, select_z ); result->col1.vec128 = spu_sel( tmp4, tmp0, select_z ); result->col2.vec128 = spu_sel( tmp5, tmp1, select_z ); } static inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col0, _col0 ); vmathV3Copy( &result->col1, _col1 ); vmathV3Copy( &result->col2, _col2 ); } static inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *_col0 ) { vmathV3Copy( &result->col0, _col0 ); } static inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *_col1 ) { vmathV3Copy( &result->col1, _col1 ); } static inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col2, _col2 ); } static inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec ) { vmathV3Copy( (&result->col0 + col), vec ); } static inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec ) { vmathV3SetElem( &result->col0, row, vmathV3GetElem( vec, 0 ) ); vmathV3SetElem( &result->col1, row, vmathV3GetElem( vec, 1 ) ); vmathV3SetElem( &result->col2, row, vmathV3GetElem( vec, 2 ) ); } static inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val ) { VmathVector3 tmpV3_0; vmathM3GetCol( &tmpV3_0, result, col ); vmathV3SetElem( &tmpV3_0, row, val ); vmathM3SetCol( result, col, &tmpV3_0 ); } static inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row ) { VmathVector3 tmpV3_0; vmathM3GetCol( &tmpV3_0, mat, col ); return vmathV3GetElem( &tmpV3_0, row ); } static inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col0 ); } static inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col1 ); } static inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat ) { vmathV3Copy( result, &mat->col2 ); } static inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col ) { vmathV3Copy( result, (&mat->col0 + col) ); } static inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row ) { vmathV3MakeFromElems( result, vmathV3GetElem( &mat->col0, row ), vmathV3GetElem( &mat->col1, row ), vmathV3GetElem( &mat->col2, row ) ); } static inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vec_float4 tmp0, tmp1, res0, res1, res2; tmp0 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_ZCWD ); res0 = spu_shuffle( tmp0, mat->col1.vec128, _VECTORMATH_SHUF_XAYB ); res1 = spu_shuffle( tmp0, mat->col1.vec128, _VECTORMATH_SHUF_ZBW0 ); res2 = spu_shuffle( tmp1, mat->col1.vec128, _VECTORMATH_SHUF_XCY0 ); result->col0.vec128 = res0; result->col1.vec128 = res1; result->col2.vec128 = res2; } static inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; tmp2 = _vmathVfCross( mat->col0.vec128, mat->col1.vec128 ); tmp0 = _vmathVfCross( mat->col1.vec128, mat->col2.vec128 ); tmp1 = _vmathVfCross( mat->col2.vec128, mat->col0.vec128 ); dot = _vmathVfDot3( tmp2, mat->col2.vec128 ); dot = spu_shuffle( dot, dot, (vec_uchar16)spu_splats(0x00010203) ); invdet = recipf4( dot ); tmp3 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_XAYB ); tmp4 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_ZCWD ); inv0 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_XAYB ); inv1 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_ZBW0 ); inv2 = spu_shuffle( tmp4, tmp1, _VECTORMATH_SHUF_XCY0 ); inv0 = spu_mul( inv0, invdet ); inv1 = spu_mul( inv1, invdet ); inv2 = spu_mul( inv2, invdet ); result->col0.vec128 = inv0; result->col1.vec128 = inv1; result->col2.vec128 = inv2; } static inline float vmathM3Determinant( const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0; vmathV3Cross( &tmpV3_0, &mat->col0, &mat->col1 ); return vmathV3Dot( &mat->col2, &tmpV3_0 ); } static inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3Add( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3Sub( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3Neg( &result->col0, &mat->col0 ); vmathV3Neg( &result->col1, &mat->col1 ); vmathV3Neg( &result->col2, &mat->col2 ); } static inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat ) { vmathV3AbsPerElem( &result->col0, &mat->col0 ); vmathV3AbsPerElem( &result->col1, &mat->col1 ); vmathV3AbsPerElem( &result->col2, &mat->col2 ); } static inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar ) { vmathV3ScalarMul( &result->col0, &mat->col0, scalar ); vmathV3ScalarMul( &result->col1, &mat->col1, scalar ); vmathV3ScalarMul( &result->col2, &mat->col2, scalar ); } static inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec ) { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx ); yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy ); zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz ); res = spu_mul( mat->col0.vec128, xxxx ); res = spu_madd( mat->col1.vec128, yyyy, res ); res = spu_madd( mat->col2.vec128, zzzz, res ); result->vec128 = res; } static inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { VmathMatrix3 tmpResult; vmathM3MulV3( &tmpResult.col0, mat0, &mat1->col0 ); vmathM3MulV3( &tmpResult.col1, mat0, &mat1->col1 ); vmathM3MulV3( &tmpResult.col2, mat0, &mat1->col2 ); vmathM3Copy( result, &tmpResult ); } static inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ) { vmathV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathM3MakeIdentity( VmathMatrix3 *result ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); } static inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = (vec_uint4)spu_maskb(0x0f00); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res1 = spu_sel( zero, c, select_y ); res1 = spu_sel( res1, s, select_z ); res2 = spu_sel( zero, negatef4(s), select_y ); res2 = spu_sel( res2, c, select_z ); vmathV3MakeXAxis( &result->col0 ); result->col1.vec128 = res1; result->col2.vec128 = res2; } static inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, negatef4(s), select_z ); res2 = spu_sel( zero, s, select_x ); res2 = spu_sel( res2, c, select_z ); result->col0.vec128 = res0; vmathV3MakeYAxis( &result->col1 ); result->col2.vec128 = res2; } static inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_y = (vec_uint4)spu_maskb(0x0f00); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, s, select_y ); res1 = spu_sel( zero, negatef4(s), select_x ); res1 = spu_sel( res1, c, select_y ); result->col0.vec128 = res0; result->col1.vec128 = res1; vmathV3MakeZAxis( &result->col2 ); } static inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); angles = radiansXYZ->vec128; angles = spu_insert( 0.0f, angles, 3 ); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 ); Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 ); Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 ); Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 ); X0 = spu_shuffle( s, s, shuffle_xxxx ); X1 = spu_shuffle( c, c, shuffle_xxxx ); tmp = spu_mul( Z0, Y1 ); result->col0.vec128 = spu_mul( Z0, Y0 ); result->col1.vec128 = spu_madd( Z1, X1, spu_mul( tmp, X0 ) ); result->col2.vec128 = spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ); } static inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec ) { vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); axis = unitVec->vec128; sincosf4( spu_splats( radians ), &s, &c ); xxxx = spu_shuffle( axis, axis, shuffle_xxxx ); yyyy = spu_shuffle( axis, axis, shuffle_yyyy ); zzzz = spu_shuffle( axis, axis, shuffle_zzzz ); oneMinusC = spu_sub( spu_splats(1.0f), c ); axisS = spu_mul( axis, s ); negAxisS = negatef4( axisS ); tmp0 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_0ZB0 ); tmp1 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_C0X0 ); tmp2 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_YA00 ); tmp0 = spu_sel( tmp0, c, (vec_uint4)spu_maskb(0xf000) ); tmp1 = spu_sel( tmp1, c, (vec_uint4)spu_maskb(0x0f00) ); tmp2 = spu_sel( tmp2, c, (vec_uint4)spu_maskb(0x00f0) ); result->col0.vec128 = spu_madd( spu_mul( axis, xxxx ), oneMinusC, tmp0 ); result->col1.vec128 = spu_madd( spu_mul( axis, yyyy ), oneMinusC, tmp1 ); result->col2.vec128 = spu_madd( spu_mul( axis, zzzz ), oneMinusC, tmp2 ); } static inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat ) { vmathM3MakeFromQ( result, unitQuat ); } static inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec ) { vec_float4 zero = spu_splats(0.0f); result->col0.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0xf000) ); result->col1.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x0f00) ); result->col2.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x00f0) ); } static inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec ) { vmathV3ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) ); vmathV3ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) ); vmathV3ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) ); } static inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat ) { vmathV3MulPerElem( &result->col0, &mat->col0, scaleVec ); vmathV3MulPerElem( &result->col1, &mat->col1, scaleVec ); vmathV3MulPerElem( &result->col2, &mat->col2, scaleVec ); } static inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 ) { vmathV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathM3Print( const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2; vmathM3GetRow( &tmpV3_0, mat, 0 ); vmathV3Print( &tmpV3_0 ); vmathM3GetRow( &tmpV3_1, mat, 1 ); vmathV3Print( &tmpV3_1 ); vmathM3GetRow( &tmpV3_2, mat, 2 ); vmathV3Print( &tmpV3_2 ); } static inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name ) { printf("%s:\n", name); vmathM3Print( mat ); } #endif static inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( &result->col0, &mat->col0 ); vmathV4Copy( &result->col1, &mat->col1 ); vmathV4Copy( &result->col2, &mat->col2 ); vmathV4Copy( &result->col3, &mat->col3 ); } static inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar ) { vmathV4MakeFromScalar( &result->col0, scalar ); vmathV4MakeFromScalar( &result->col1, scalar ); vmathV4MakeFromScalar( &result->col2, scalar ); vmathV4MakeFromScalar( &result->col3, scalar ); } static inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat ) { vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, &mat->col3, 1.0f ); } static inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *_col0, const VmathVector4 *_col1, const VmathVector4 *_col2, const VmathVector4 *_col3 ) { vmathV4Copy( &result->col0, _col0 ); vmathV4Copy( &result->col1, _col1 ); vmathV4Copy( &result->col2, _col2 ); vmathV4Copy( &result->col3, _col3 ); } static inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec ) { vmathV4MakeFromV3Scalar( &result->col0, &mat->col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat->col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat->col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ) { VmathMatrix3 mat; vmathM3MakeFromQ( &mat, unitQuat ); vmathV4MakeFromV3Scalar( &result->col0, &mat.col0, 0.0f ); vmathV4MakeFromV3Scalar( &result->col1, &mat.col1, 0.0f ); vmathV4MakeFromV3Scalar( &result->col2, &mat.col2, 0.0f ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *_col0 ) { vmathV4Copy( &result->col0, _col0 ); } static inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *_col1 ) { vmathV4Copy( &result->col1, _col1 ); } static inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *_col2 ) { vmathV4Copy( &result->col2, _col2 ); } static inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *_col3 ) { vmathV4Copy( &result->col3, _col3 ); } static inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec ) { vmathV4Copy( (&result->col0 + col), vec ); } static inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec ) { vmathV4SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) ); vmathV4SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) ); vmathV4SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) ); vmathV4SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) ); } static inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val ) { VmathVector4 tmpV3_0; vmathM4GetCol( &tmpV3_0, result, col ); vmathV4SetElem( &tmpV3_0, row, val ); vmathM4SetCol( result, col, &tmpV3_0 ); } static inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row ) { VmathVector4 tmpV4_0; vmathM4GetCol( &tmpV4_0, mat, col ); return vmathV4GetElem( &tmpV4_0, row ); } static inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col0 ); } static inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col1 ); } static inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col2 ); } static inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat ) { vmathV4Copy( result, &mat->col3 ); } static inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col ) { vmathV4Copy( result, (&mat->col0 + col) ); } static inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row ) { vmathV4MakeFromElems( result, vmathV4GetElem( &mat->col0, row ), vmathV4GetElem( &mat->col1, row ), vmathV4GetElem( &mat->col2, row ), vmathV4GetElem( &mat->col3, row ) ); } static inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vec_float4 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; tmp0 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mat->col1.vec128, mat->col3.vec128, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( mat->col1.vec128, mat->col3.vec128, _VECTORMATH_SHUF_ZCWD ); res0 = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); res1 = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); res2 = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); res3 = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ); result->col0.vec128 = res0; result->col1.vec128 = res1; result->col2.vec128 = res2; result->col3.vec128 = res3; } static inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 in0, in1, in2, in3; vec_float4 tmp0, tmp1, tmp2, tmp3; vec_float4 cof0, cof1, cof2, cof3; vec_float4 t0, t1, t2, t3; vec_float4 t01, t02, t03, t12, t23; vec_float4 t1r, t2r; vec_float4 t01r, t02r, t03r, t12r, t23r; vec_float4 t1r3, t1r3r; vec_float4 det, det1, det2, det3, invdet; in0 = mat->col0.vec128; in1 = mat->col1.vec128; in2 = mat->col2.vec128; in3 = mat->col3.vec128; /* Perform transform of the input matrix of the form: * A B C D * E F G H * I J K L * M N O P * * The pseudo transpose of the input matrix is trans: * A E I M * J N B F * C G K O * L P D H */ tmp0 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_XAZC); /* A E C G */ tmp1 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_XAZC); /* I M K O */ tmp2 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_YBWD); /* B F D H */ tmp3 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_YBWD); /* J N L P */ t0 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_XYAB); /* A E I M */ t1 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_XYAB); /* J N B F */ t2 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_ZWCD); /* C G K O */ t3 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_ZWCD); /* L P D H */ /* Generate a cofactor matrix. The computed cofactors reside in * cof0, cof1, cof2, cof3. */ t23 = spu_mul(t2, t3); /* CL GP KD OH */ t23 = spu_shuffle(t23, t23, _VECTORMATH_SHUF_YXWZ); /* GP CL OH KD */ cof0 = spu_mul(t1, t23); /* JGP NCL BOH FKD */ cof1 = spu_mul(t0, t23); /* AGP ECL IOH MKD */ t23r = spu_rlqwbyte(t23, 8); /* OH KD GP CL */ cof0 = spu_msub(t1, t23r, cof0); /* JOH NKD BGP FCL - cof0 */ cof1 = spu_msub(t0, t23r, cof1); /* AOH EKD IGP MCL - cof1 */ cof1 = spu_rlqwbyte(cof1, 8); /* IGP MCL AOH EKD - IOH MKD AGP ECL */ t12 = spu_mul(t1, t2); /* JC NG BK FO */ t12 = spu_shuffle(t12, t12, _VECTORMATH_SHUF_YXWZ); /* NG JC FO BK */ cof0 = spu_madd(t3, t12, cof0); /* LNG PJC DFO HBK + cof0 */ cof3 = spu_mul(t0, t12); /* ANG EJC IFO MBK */ t12r = spu_rlqwbyte(t12, 8); /* FO BK NG JC */ cof0 = spu_nmsub(t3, t12r, cof0); /* cof0 - LFO PBK DNG HJC */ cof3 = spu_msub(t0, t12r, cof3); /* AFO EBK ING MJC - cof3 */ cof3 = spu_rlqwbyte(cof3, 8); /* ING MJC AFO EBK - IFO MBK ANG EJC */ t1r = spu_rlqwbyte(t1, 8); /* B F J N */ t2r = spu_rlqwbyte(t2, 8); /* K O C G */ t1r3 = spu_mul(t1r, t3); /* BL FP JD NH */ t1r3 = spu_shuffle(t1r3, t1r3, _VECTORMATH_SHUF_YXWZ); /* FP BL NH JD */ cof0 = spu_madd(t2r, t1r3, cof0); /* KFP OBL CNH GJD + cof0 */ cof2 = spu_mul(t0, t1r3); /* AFP EBL INH MJD */ t1r3r = spu_rlqwbyte(t1r3, 8); /* NH JD FP BL */ cof0 = spu_nmsub(t2r, t1r3r, cof0); /* cof0 - KNH OJD CFP GBL */ cof2 = spu_msub(t0, t1r3r, cof2); /* ANH EJD IFP MBL - cof2 */ cof2 = spu_rlqwbyte(cof2, 8); /* IFP MBL ANH EJD - INH MJD AFP EBL */ t01 = spu_mul(t0, t1); /* AJ EN IB MF */ t01 = spu_shuffle(t01, t01, _VECTORMATH_SHUF_YXWZ); /* EN AJ MF IB */ cof2 = spu_madd(t3, t01, cof2); /* LEN PAJ DMF HIB + cof2 */ cof3 = spu_msub(t2r, t01, cof3); /* KEN OAJ CMF GIB - cof3 */ t01r = spu_rlqwbyte(t01, 8); /* MF IB EN AJ */ cof2 = spu_msub(t3, t01r, cof2); /* LMF PIB DEN HAJ - cof2 */ cof3 = spu_nmsub(t2r, t01r, cof3); /* cof3 - KMF OIB CEN GAJ */ t03 = spu_mul(t0, t3); /* AL EP ID MH */ t03 = spu_shuffle(t03, t03, _VECTORMATH_SHUF_YXWZ); /* EP AL MH ID */ cof1 = spu_nmsub(t2r, t03, cof1); /* cof1 - KEP OAL CMH GID */ cof2 = spu_madd(t1, t03, cof2); /* JEP NAL BMH FID + cof2 */ t03r = spu_rlqwbyte(t03, 8); /* MH ID EP AL */ cof1 = spu_madd(t2r, t03r, cof1); /* KMH OID CEP GAL + cof1 */ cof2 = spu_nmsub(t1, t03r, cof2); /* cof2 - JMH NID BEP FAL */ t02 = spu_mul(t0, t2r); /* AK EO IC MG */ t02 = spu_shuffle(t02, t02, _VECTORMATH_SHUF_YXWZ); /* E0 AK MG IC */ cof1 = spu_madd(t3, t02, cof1); /* LEO PAK DMG HIC + cof1 */ cof3 = spu_nmsub(t1, t02, cof3); /* cof3 - JEO NAK BMG FIC */ t02r = spu_rlqwbyte(t02, 8); /* MG IC EO AK */ cof1 = spu_nmsub(t3, t02r, cof1); /* cof1 - LMG PIC DEO HAK */ cof3 = spu_madd(t1, t02r, cof3); /* JMG NIC BEO FAK + cof3 */ /* Compute the determinant of the matrix * * det = sum_across(t0 * cof0); * * We perform a sum across the entire vector so that * we don't have to splat the result when multiplying the * cofactors by the inverse of the determinant. */ det = spu_mul(t0, cof0); det1 = spu_rlqwbyte(det, 4); det2 = spu_rlqwbyte(det, 8); det3 = spu_rlqwbyte(det, 12); det = spu_add(det, det1); det2 = spu_add(det2, det3); det = spu_add(det, det2); /* Compute the reciprocal of the determinant. */ invdet = recipf4(det); /* Multiply the cofactors by the reciprocal of the determinant. */ result->col0.vec128 = spu_mul(cof0, invdet); result->col1.vec128 = spu_mul(cof1, invdet); result->col2.vec128 = spu_mul(cof2, invdet); result->col3.vec128 = spu_mul(cof3, invdet); } static inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { VmathTransform3 affineMat, tmpT3_0; VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathT3SetCol0( &affineMat, &tmpV3_0 ); vmathV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathT3SetCol1( &affineMat, &tmpV3_1 ); vmathV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathT3SetCol2( &affineMat, &tmpV3_2 ); vmathV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathT3SetCol3( &affineMat, &tmpV3_3 ); vmathT3Inverse( &tmpT3_0, &affineMat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ) { VmathTransform3 affineMat, tmpT3_0; VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathT3SetCol0( &affineMat, &tmpV3_0 ); vmathV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathT3SetCol1( &affineMat, &tmpV3_1 ); vmathV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathT3SetCol2( &affineMat, &tmpV3_2 ); vmathV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathT3SetCol3( &affineMat, &tmpV3_3 ); vmathT3OrthoInverse( &tmpT3_0, &affineMat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline float vmathM4Determinant( const VmathMatrix4 *mat ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 in0, in1, in2, in3; vec_float4 tmp0, tmp1, tmp2, tmp3; vec_float4 cof0; vec_float4 t0, t1, t2, t3; vec_float4 t12, t23; vec_float4 t1r, t2r; vec_float4 t12r, t23r; vec_float4 t1r3, t1r3r; in0 = mat->col0.vec128; in1 = mat->col1.vec128; in2 = mat->col2.vec128; in3 = mat->col3.vec128; /* Perform transform of the input matrix of the form: * A B C D * E F G H * I J K L * M N O P * * The pseudo transpose of the input matrix is trans: * A E I M * J N B F * C G K O * L P D H */ tmp0 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_XAZC); /* A E C G */ tmp1 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_XAZC); /* I M K O */ tmp2 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_YBWD); /* B F D H */ tmp3 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_YBWD); /* J N L P */ t0 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_XYAB); /* A E I M */ t1 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_XYAB); /* J N B F */ t2 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_ZWCD); /* C G K O */ t3 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_ZWCD); /* L P D H */ /* Generate a cofactor matrix. The computed cofactors reside in * cof0, cof1, cof2, cof3. */ t23 = spu_mul(t2, t3); /* CL GP KD OH */ t23 = spu_shuffle(t23, t23, _VECTORMATH_SHUF_YXWZ); /* GP CL OH KD */ cof0 = spu_mul(t1, t23); /* JGP NCL BOH FKD */ t23r = spu_rlqwbyte(t23, 8); /* OH KD GP CL */ cof0 = spu_msub(t1, t23r, cof0); /* JOH NKD BGP FCL - cof0 */ t12 = spu_mul(t1, t2); /* JC NG BK FO */ t12 = spu_shuffle(t12, t12, _VECTORMATH_SHUF_YXWZ); /* NG JC FO BK */ cof0 = spu_madd(t3, t12, cof0); /* LNG PJC DFO HBK + cof0 */ t12r = spu_rlqwbyte(t12, 8); /* FO BK NG JC */ cof0 = spu_nmsub(t3, t12r, cof0); /* cof0 - LFO PBK DNG HJC */ t1r = spu_rlqwbyte(t1, 8); /* B F J N */ t2r = spu_rlqwbyte(t2, 8); /* K O C G */ t1r3 = spu_mul(t1r, t3); /* BL FP JD NH */ t1r3 = spu_shuffle(t1r3, t1r3, _VECTORMATH_SHUF_YXWZ); /* FP BL NH JD */ cof0 = spu_madd(t2r, t1r3, cof0); /* KFP OBL CNH GJD + cof0 */ t1r3r = spu_rlqwbyte(t1r3, 8); /* NH JD FP BL */ cof0 = spu_nmsub(t2r, t1r3r, cof0); /* cof0 - KNH OJD CFP GBL */ return spu_extract( _vmathVfDot4(t0,cof0), 0 ); } static inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4Add( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4Add( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4Sub( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4Sub( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4Neg( &result->col0, &mat->col0 ); vmathV4Neg( &result->col1, &mat->col1 ); vmathV4Neg( &result->col2, &mat->col2 ); vmathV4Neg( &result->col3, &mat->col3 ); } static inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat ) { vmathV4AbsPerElem( &result->col0, &mat->col0 ); vmathV4AbsPerElem( &result->col1, &mat->col1 ); vmathV4AbsPerElem( &result->col2, &mat->col2 ); vmathV4AbsPerElem( &result->col3, &mat->col3 ); } static inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar ) { vmathV4ScalarMul( &result->col0, &mat->col0, scalar ); vmathV4ScalarMul( &result->col1, &mat->col1, scalar ); vmathV4ScalarMul( &result->col2, &mat->col2, scalar ); vmathV4ScalarMul( &result->col3, &mat->col3, scalar ); } static inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec ) { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz, wwww; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx ); yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy ); zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz ); wwww = spu_shuffle( vec->vec128, vec->vec128, shuffle_wwww ); tmp0 = spu_mul( mat->col0.vec128, xxxx ); tmp1 = spu_mul( mat->col1.vec128, yyyy ); tmp0 = spu_madd( mat->col2.vec128, zzzz, tmp0 ); tmp1 = spu_madd( mat->col3.vec128, wwww, tmp1 ); res = spu_add( tmp0, tmp1 ); result->vec128 = res; } static inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec ) { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx ); yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy ); zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz ); res = spu_mul( mat->col0.vec128, xxxx ); res = spu_madd( mat->col1.vec128, yyyy, res ); res = spu_madd( mat->col2.vec128, zzzz, res ); result->vec128 = res; } static inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt ) { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_xxxx ); yyyy = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_yyyy ); zzzz = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_zzzz ); tmp0 = spu_mul( mat->col0.vec128, xxxx ); tmp1 = spu_mul( mat->col1.vec128, yyyy ); tmp0 = spu_madd( mat->col2.vec128, zzzz, tmp0 ); tmp1 = spu_add( mat->col3.vec128, tmp1 ); res = spu_add( tmp0, tmp1 ); result->vec128 = res; } static inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { VmathMatrix4 tmpResult; vmathM4MulV4( &tmpResult.col0, mat0, &mat1->col0 ); vmathM4MulV4( &tmpResult.col1, mat0, &mat1->col1 ); vmathM4MulV4( &tmpResult.col2, mat0, &mat1->col2 ); vmathM4MulV4( &tmpResult.col3, mat0, &mat1->col3 ); vmathM4Copy( result, &tmpResult ); } static inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm1 ) { VmathMatrix4 tmpResult; VmathPoint3 tmpP3_0; vmathM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 ); vmathM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 ); vmathM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 ); vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathM4MulP3( &tmpResult.col3, mat, &tmpP3_0 ); vmathM4Copy( result, &tmpResult ); } static inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ) { vmathV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); vmathV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathM4MakeIdentity( VmathMatrix4 *result ) { vmathV4MakeXAxis( &result->col0 ); vmathV4MakeYAxis( &result->col1 ); vmathV4MakeZAxis( &result->col2 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 ) { vmathV4SetXYZ( &result->col0, &mat3->col0 ); vmathV4SetXYZ( &result->col1, &mat3->col1 ); vmathV4SetXYZ( &result->col2, &mat3->col2 ); } static inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat ) { vmathV4GetXYZ( &result->col0, &mat->col0 ); vmathV4GetXYZ( &result->col1, &mat->col1 ); vmathV4GetXYZ( &result->col2, &mat->col2 ); } static inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ) { vmathV4SetXYZ( &result->col3, translateVec ); } static inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat ) { vmathV4GetXYZ( result, &mat->col3 ); } static inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = (vec_uint4)spu_maskb(0x0f00); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res1 = spu_sel( zero, c, select_y ); res1 = spu_sel( res1, s, select_z ); res2 = spu_sel( zero, negatef4(s), select_y ); res2 = spu_sel( res2, c, select_z ); vmathV4MakeXAxis( &result->col0 ); result->col1.vec128 = res1; result->col2.vec128 = res2; vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, negatef4(s), select_z ); res2 = spu_sel( zero, s, select_x ); res2 = spu_sel( res2, c, select_z ); result->col0.vec128 = res0; vmathV4MakeYAxis( &result->col1 ); result->col2.vec128 = res2; vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_y = (vec_uint4)spu_maskb(0x0f00); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, s, select_y ); res1 = spu_sel( zero, negatef4(s), select_x ); res1 = spu_sel( res1, c, select_y ); result->col0.vec128 = res0; result->col1.vec128 = res1; vmathV4MakeZAxis( &result->col2 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); angles = radiansXYZ->vec128; angles = spu_insert( 0.0f, angles, 3 ); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 ); Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 ); Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 ); Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 ); X0 = spu_shuffle( s, s, shuffle_xxxx ); X1 = spu_shuffle( c, c, shuffle_xxxx ); tmp = spu_mul( Z0, Y1 ); result->col0.vec128 = spu_mul( Z0, Y0 ); result->col1.vec128 = spu_madd( Z1, X1, spu_mul( tmp, X0 ) ); result->col2.vec128 = spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec ) { vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2, zeroW; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); axis = unitVec->vec128; sincosf4( spu_splats( radians ), &s, &c ); xxxx = spu_shuffle( axis, axis, shuffle_xxxx ); yyyy = spu_shuffle( axis, axis, shuffle_yyyy ); zzzz = spu_shuffle( axis, axis, shuffle_zzzz ); oneMinusC = spu_sub( spu_splats(1.0f), c ); axisS = spu_mul( axis, s ); negAxisS = negatef4( axisS ); tmp0 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_0ZB0 ); tmp1 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_C0X0 ); tmp2 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_YA00 ); tmp0 = spu_sel( tmp0, c, (vec_uint4)spu_maskb(0xf000) ); tmp1 = spu_sel( tmp1, c, (vec_uint4)spu_maskb(0x0f00) ); tmp2 = spu_sel( tmp2, c, (vec_uint4)spu_maskb(0x00f0) ); zeroW = (vec_float4)spu_maskb(0x000f); axis = spu_andc( axis, zeroW ); result->col0.vec128 = spu_madd( spu_mul( axis, xxxx ), oneMinusC, tmp0 ); result->col1.vec128 = spu_madd( spu_mul( axis, yyyy ), oneMinusC, tmp1 ); result->col2.vec128 = spu_madd( spu_mul( axis, zzzz ), oneMinusC, tmp2 ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat ) { VmathTransform3 tmpT3_0; vmathT3MakeRotationQ( &tmpT3_0, unitQuat ); vmathM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec ) { vec_float4 zero = spu_splats(0.0f); result->col0.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0xf000) ); result->col1.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x0f00) ); result->col2.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x00f0) ); vmathV4MakeWAxis( &result->col3 ); } static inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec ) { vmathV4ScalarMul( &result->col0, &mat->col0, vmathV3GetX( scaleVec ) ); vmathV4ScalarMul( &result->col1, &mat->col1, vmathV3GetY( scaleVec ) ); vmathV4ScalarMul( &result->col2, &mat->col2, vmathV3GetZ( scaleVec ) ); vmathV4Copy( &result->col3, &mat->col3 ); } static inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat ) { VmathVector4 scale4; vmathV4MakeFromV3Scalar( &scale4, scaleVec, 1.0f ); vmathV4MulPerElem( &result->col0, &mat->col0, &scale4 ); vmathV4MulPerElem( &result->col1, &mat->col1, &scale4 ); vmathV4MulPerElem( &result->col2, &mat->col2, &scale4 ); vmathV4MulPerElem( &result->col3, &mat->col3, &scale4 ); } static inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ) { vmathV4MakeXAxis( &result->col0 ); vmathV4MakeYAxis( &result->col1 ); vmathV4MakeZAxis( &result->col2 ); vmathV4MakeFromV3Scalar( &result->col3, translateVec, 1.0f ); } static inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec ) { VmathMatrix4 m4EyeFrame; VmathVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1; VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; vmathV3Normalize( &v3Y, upVec ); vmathP3Sub( &tmpV3_0, eyePos, lookAtPos ); vmathV3Normalize( &v3Z, &tmpV3_0 ); vmathV3Cross( &tmpV3_1, &v3Y, &v3Z ); vmathV3Normalize( &v3X, &tmpV3_1 ); vmathV3Cross( &v3Y, &v3Z, &v3X ); vmathV4MakeFromV3( &tmpV4_0, &v3X ); vmathV4MakeFromV3( &tmpV4_1, &v3Y ); vmathV4MakeFromV3( &tmpV4_2, &v3Z ); vmathV4MakeFromP3( &tmpV4_3, eyePos ); vmathM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 ); vmathM4OrthoInverse( result, &m4EyeFrame ); } static inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar ) { float f, rangeInv; vec_float4 zero, col0, col1, col2, col3; f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f ); rangeInv = 1.0f / ( zNear - zFar ); zero = spu_splats(0.0f); col0 = zero; col1 = zero; col2 = zero; col3 = zero; col0 = spu_insert( f / aspect, col0, 0 ); col1 = spu_insert( f, col1, 1 ); col2 = spu_insert( ( zNear + zFar ) * rangeInv, col2, 2 ); col2 = spu_insert( -1.0f, col2, 3 ); col3 = spu_insert( zNear * zFar * rangeInv * 2.0f, col3, 2 ); result->col0.vec128 = col0; result->col1.vec128 = col1; result->col2.vec128 = col2; result->col3.vec128 = col3; } static inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 lbf, rtn; vec_float4 diff, sum, inv_diff; vec_float4 diagonal, column, near2; vec_float4 zero = spu_splats(0.0f); lbf = spu_shuffle( spu_promote(left,0), spu_promote(zFar,0), _VECTORMATH_SHUF_XAYB ); rtn = spu_shuffle( spu_promote(right,0), spu_promote(zNear,0), _VECTORMATH_SHUF_XAYB ); lbf = spu_shuffle( lbf, spu_promote(bottom,0), _VECTORMATH_SHUF_XAYB ); rtn = spu_shuffle( rtn, spu_promote(top,0), _VECTORMATH_SHUF_XAYB ); diff = spu_sub( rtn, lbf ); sum = spu_add( rtn, lbf ); inv_diff = recipf4( diff ); near2 = spu_splats( zNear ); near2 = spu_add( near2, near2 ); diagonal = spu_mul( near2, inv_diff ); column = spu_mul( sum, inv_diff ); result->col0.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0xf000) ); result->col1.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x0f00) ); result->col2.vec128 = spu_sel( column, spu_splats(-1.0f), (vec_uint4)spu_maskb(0x000f) ); result->col3.vec128 = spu_sel( zero, spu_mul( diagonal, spu_splats(zFar) ), (vec_uint4)spu_maskb(0x00f0) ); } static inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 lbf, rtn; vec_float4 diff, sum, inv_diff, neg_inv_diff; vec_float4 diagonal, column; vec_float4 zero = spu_splats(0.0f); lbf = spu_shuffle( spu_promote(left,0), spu_promote(zFar,0), _VECTORMATH_SHUF_XAYB ); rtn = spu_shuffle( spu_promote(right,0), spu_promote(zNear,0), _VECTORMATH_SHUF_XAYB ); lbf = spu_shuffle( lbf, spu_promote(bottom,0), _VECTORMATH_SHUF_XAYB ); rtn = spu_shuffle( rtn, spu_promote(top,0), _VECTORMATH_SHUF_XAYB ); diff = spu_sub( rtn, lbf ); sum = spu_add( rtn, lbf ); inv_diff = recipf4( diff ); neg_inv_diff = negatef4( inv_diff ); diagonal = spu_add( inv_diff, inv_diff ); column = spu_mul( sum, spu_sel( neg_inv_diff, inv_diff, (vec_uint4)spu_maskb(0x00f0) ) ); result->col0.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0xf000) ); result->col1.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x0f00) ); result->col2.vec128 = spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x00f0) ); result->col3.vec128 = spu_sel( column, spu_splats(1.0f), (vec_uint4)spu_maskb(0x000f) ); } static inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 ) { vmathV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); vmathV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathM4Print( const VmathMatrix4 *mat ) { VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; vmathM4GetRow( &tmpV4_0, mat, 0 ); vmathV4Print( &tmpV4_0 ); vmathM4GetRow( &tmpV4_1, mat, 1 ); vmathV4Print( &tmpV4_1 ); vmathM4GetRow( &tmpV4_2, mat, 2 ); vmathV4Print( &tmpV4_2 ); vmathM4GetRow( &tmpV4_3, mat, 3 ); vmathV4Print( &tmpV4_3 ); } static inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name ) { printf("%s:\n", name); vmathM4Print( mat ); } #endif static inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( &result->col0, &tfrm->col0 ); vmathV3Copy( &result->col1, &tfrm->col1 ); vmathV3Copy( &result->col2, &tfrm->col2 ); vmathV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar ) { vmathV3MakeFromScalar( &result->col0, scalar ); vmathV3MakeFromScalar( &result->col1, scalar ); vmathV3MakeFromScalar( &result->col2, scalar ); vmathV3MakeFromScalar( &result->col3, scalar ); } static inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *_col0, const VmathVector3 *_col1, const VmathVector3 *_col2, const VmathVector3 *_col3 ) { vmathV3Copy( &result->col0, _col0 ); vmathV3Copy( &result->col1, _col1 ); vmathV3Copy( &result->col2, _col2 ); vmathV3Copy( &result->col3, _col3 ); } static inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec ) { vmathT3SetUpper3x3( result, tfrm ); vmathT3SetTranslation( result, translateVec ); } static inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ) { VmathMatrix3 tmpM3_0; vmathM3MakeFromQ( &tmpM3_0, unitQuat ); vmathT3SetUpper3x3( result, &tmpM3_0 ); vmathT3SetTranslation( result, translateVec ); } static inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *_col0 ) { vmathV3Copy( &result->col0, _col0 ); } static inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *_col1 ) { vmathV3Copy( &result->col1, _col1 ); } static inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *_col2 ) { vmathV3Copy( &result->col2, _col2 ); } static inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *_col3 ) { vmathV3Copy( &result->col3, _col3 ); } static inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec ) { vmathV3Copy( (&result->col0 + col), vec ); } static inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec ) { vmathV3SetElem( &result->col0, row, vmathV4GetElem( vec, 0 ) ); vmathV3SetElem( &result->col1, row, vmathV4GetElem( vec, 1 ) ); vmathV3SetElem( &result->col2, row, vmathV4GetElem( vec, 2 ) ); vmathV3SetElem( &result->col3, row, vmathV4GetElem( vec, 3 ) ); } static inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val ) { VmathVector3 tmpV3_0; vmathT3GetCol( &tmpV3_0, result, col ); vmathV3SetElem( &tmpV3_0, row, val ); vmathT3SetCol( result, col, &tmpV3_0 ); } static inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row ) { VmathVector3 tmpV3_0; vmathT3GetCol( &tmpV3_0, tfrm, col ); return vmathV3GetElem( &tmpV3_0, row ); } static inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col0 ); } static inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col1 ); } static inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col2 ); } static inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col3 ); } static inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col ) { vmathV3Copy( result, (&tfrm->col0 + col) ); } static inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row ) { vmathV4MakeFromElems( result, vmathV3GetElem( &tfrm->col0, row ), vmathV3GetElem( &tfrm->col1, row ), vmathV3GetElem( &tfrm->col2, row ), vmathV3GetElem( &tfrm->col3, row ) ); } static inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vec_float4 inv0, inv1, inv2, inv3; vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); tmp2 = _vmathVfCross( tfrm->col0.vec128, tfrm->col1.vec128 ); tmp0 = _vmathVfCross( tfrm->col1.vec128, tfrm->col2.vec128 ); tmp1 = _vmathVfCross( tfrm->col2.vec128, tfrm->col0.vec128 ); inv3 = negatef4( tfrm->col3.vec128 ); dot = _vmathVfDot3( tmp2, tfrm->col2.vec128 ); dot = spu_shuffle( dot, dot, shuffle_xxxx ); invdet = recipf4( dot ); tmp3 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_XAYB ); tmp4 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_ZCWD ); inv0 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_XAYB ); xxxx = spu_shuffle( inv3, inv3, shuffle_xxxx ); inv1 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_ZBW0 ); inv2 = spu_shuffle( tmp4, tmp1, _VECTORMATH_SHUF_XCY0 ); yyyy = spu_shuffle( inv3, inv3, shuffle_yyyy ); zzzz = spu_shuffle( inv3, inv3, shuffle_zzzz ); inv3 = spu_mul( inv0, xxxx ); inv3 = spu_madd( inv1, yyyy, inv3 ); inv3 = spu_madd( inv2, zzzz, inv3 ); inv0 = spu_mul( inv0, invdet ); inv1 = spu_mul( inv1, invdet ); inv2 = spu_mul( inv2, invdet ); inv3 = spu_mul( inv3, invdet ); result->col0.vec128 = inv0; result->col1.vec128 = inv1; result->col2.vec128 = inv2; result->col3.vec128 = inv3; } static inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vec_float4 inv0, inv1, inv2, inv3; vec_float4 tmp0, tmp1; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); tmp0 = spu_shuffle( tfrm->col0.vec128, tfrm->col2.vec128, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( tfrm->col0.vec128, tfrm->col2.vec128, _VECTORMATH_SHUF_ZCWD ); inv3 = negatef4( tfrm->col3.vec128 ); inv0 = spu_shuffle( tmp0, tfrm->col1.vec128, _VECTORMATH_SHUF_XAYB ); xxxx = spu_shuffle( inv3, inv3, shuffle_xxxx ); inv1 = spu_shuffle( tmp0, tfrm->col1.vec128, _VECTORMATH_SHUF_ZBW0 ); inv2 = spu_shuffle( tmp1, tfrm->col1.vec128, _VECTORMATH_SHUF_XCY0 ); yyyy = spu_shuffle( inv3, inv3, shuffle_yyyy ); zzzz = spu_shuffle( inv3, inv3, shuffle_zzzz ); inv3 = spu_mul( inv0, xxxx ); inv3 = spu_madd( inv1, yyyy, inv3 ); inv3 = spu_madd( inv2, zzzz, inv3 ); result->col0.vec128 = inv0; result->col1.vec128 = inv1; result->col2.vec128 = inv2; result->col3.vec128 = inv3; } static inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm ) { vmathV3AbsPerElem( &result->col0, &tfrm->col0 ); vmathV3AbsPerElem( &result->col1, &tfrm->col1 ); vmathV3AbsPerElem( &result->col2, &tfrm->col2 ); vmathV3AbsPerElem( &result->col3, &tfrm->col3 ); } static inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec ) { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx ); yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy ); zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz ); res = spu_mul( tfrm->col0.vec128, xxxx ); res = spu_madd( tfrm->col1.vec128, yyyy, res ); res = spu_madd( tfrm->col2.vec128, zzzz, res ); result->vec128 = res; } static inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt ) { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_xxxx ); yyyy = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_yyyy ); zzzz = spu_shuffle( pnt->vec128, pnt->vec128, shuffle_zzzz ); tmp0 = spu_mul( tfrm->col0.vec128, xxxx ); tmp1 = spu_mul( tfrm->col1.vec128, yyyy ); tmp0 = spu_madd( tfrm->col2.vec128, zzzz, tmp0 ); tmp1 = spu_add( tfrm->col3.vec128, tmp1 ); res = spu_add( tmp0, tmp1 ); result->vec128 = res; } static inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ) { VmathTransform3 tmpResult; VmathPoint3 tmpP3_0, tmpP3_1; vmathT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 ); vmathT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 ); vmathT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 ); vmathP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 ); vmathV3MakeFromP3( &tmpResult.col3, &tmpP3_1 ); vmathT3Copy( result, &tmpResult ); } static inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ) { vmathV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 ); vmathV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 ); vmathV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 ); vmathV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 ); } static inline void vmathT3MakeIdentity( VmathTransform3 *result ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *tfrm ) { vmathV3Copy( &result->col0, &tfrm->col0 ); vmathV3Copy( &result->col1, &tfrm->col1 ); vmathV3Copy( &result->col2, &tfrm->col2 ); } static inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm ) { vmathM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 ); } static inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ) { vmathV3Copy( &result->col3, translateVec ); } static inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm ) { vmathV3Copy( result, &tfrm->col3 ); } static inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = (vec_uint4)spu_maskb(0x0f00); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res1 = spu_sel( zero, c, select_y ); res1 = spu_sel( res1, s, select_z ); res2 = spu_sel( zero, negatef4(s), select_y ); res2 = spu_sel( res2, c, select_z ); vmathV3MakeXAxis( &result->col0 ); result->col1.vec128 = res1; result->col2.vec128 = res2; vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, negatef4(s), select_z ); res2 = spu_sel( zero, s, select_x ); res2 = spu_sel( res2, c, select_z ); result->col0.vec128 = res0; vmathV3MakeYAxis( &result->col1 ); result->col2.vec128 = res2; vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_y = (vec_uint4)spu_maskb(0x0f00); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, s, select_y ); res1 = spu_sel( zero, negatef4(s), select_x ); res1 = spu_sel( res1, c, select_y ); result->col0.vec128 = res0; result->col1.vec128 = res1; vmathV3MakeZAxis( &result->col2 ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); angles = radiansXYZ->vec128; angles = spu_insert( 0.0f, angles, 3 ); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 ); Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 ); Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 ); Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 ); X0 = spu_shuffle( s, s, shuffle_xxxx ); X1 = spu_shuffle( c, c, shuffle_xxxx ); tmp = spu_mul( Z0, Y1 ); result->col0.vec128 = spu_mul( Z0, Y0 ); result->col1.vec128 = spu_madd( Z1, X1, spu_mul( tmp, X0 ) ); result->col2.vec128 = spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec ) { VmathMatrix3 tmpM3_0; VmathVector3 tmpV3_0; vmathM3MakeRotationAxis( &tmpM3_0, radians, unitVec ); vmathV3MakeFromScalar( &tmpV3_0, 0.0f ); vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat ) { VmathMatrix3 tmpM3_0; VmathVector3 tmpV3_0; vmathM3MakeFromQ( &tmpM3_0, unitQuat ); vmathV3MakeFromScalar( &tmpV3_0, 0.0f ); vmathT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec ) { vec_float4 zero = spu_splats(0.0f); result->col0.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0xf000) ); result->col1.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x0f00) ); result->col2.vec128 = spu_sel( zero, scaleVec->vec128, (vec_uint4)spu_maskb(0x00f0) ); vmathV3MakeFromScalar( &result->col3, 0.0f ); } static inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec ) { vmathV3ScalarMul( &result->col0, &tfrm->col0, vmathV3GetX( scaleVec ) ); vmathV3ScalarMul( &result->col1, &tfrm->col1, vmathV3GetY( scaleVec ) ); vmathV3ScalarMul( &result->col2, &tfrm->col2, vmathV3GetZ( scaleVec ) ); vmathV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm ) { vmathV3MulPerElem( &result->col0, &tfrm->col0, scaleVec ); vmathV3MulPerElem( &result->col1, &tfrm->col1, scaleVec ); vmathV3MulPerElem( &result->col2, &tfrm->col2, scaleVec ); vmathV3MulPerElem( &result->col3, &tfrm->col3, scaleVec ); } static inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ) { vmathV3MakeXAxis( &result->col0 ); vmathV3MakeYAxis( &result->col1 ); vmathV3MakeZAxis( &result->col2 ); vmathV3Copy( &result->col3, translateVec ); } static inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 ) { vmathV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 ); vmathV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 ); vmathV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 ); vmathV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathT3Print( const VmathTransform3 *tfrm ) { VmathVector4 tmpV4_0, tmpV4_1, tmpV4_2; vmathT3GetRow( &tmpV4_0, tfrm, 0 ); vmathV4Print( &tmpV4_0 ); vmathT3GetRow( &tmpV4_1, tfrm, 1 ); vmathV4Print( &tmpV4_1 ); vmathT3GetRow( &tmpV4_2, tfrm, 2 ); vmathV4Print( &tmpV4_2 ); } static inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name ) { printf("%s:\n", name); vmathT3Print( tfrm ); } #endif static inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *tfrm ) { vec_float4 res; vec_float4 col0, col1, col2; vec_float4 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; vec_float4 zy_xz_yx, yz_zx_xy, sum, diff; vec_float4 radicand, invSqrt, scale; vec_float4 res0, res1, res2, res3; vec_float4 xx, yy, zz; vec_uint4 select_x = (vec_uint4)spu_maskb( 0xf000 ); vec_uint4 select_y = (vec_uint4)spu_maskb( 0x0f00 ); vec_uint4 select_z = (vec_uint4)spu_maskb( 0x00f0 ); vec_uint4 select_w = (vec_uint4)spu_maskb( 0x000f ); vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((unsigned int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((unsigned int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((unsigned int)0x08090a0b); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((unsigned int)0x0c0d0e0f); col0 = tfrm->col0.vec128; col1 = tfrm->col1.vec128; col2 = tfrm->col2.vec128; /* four cases: */ /* trace > 0 */ /* else */ /* xx largest diagonal element */ /* yy largest diagonal element */ /* zz largest diagonal element */ /* compute quaternion for each case */ xx_yy = spu_sel( col0, col1, select_y ); xx_yy_zz_xx = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_XYCX ); yy_zz_xx_yy = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_YCXY ); zz_xx_yy_zz = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_CXYC ); diagSum = spu_add( spu_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); diagDiff = spu_sub( spu_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); radicand = spu_add( spu_sel( diagDiff, diagSum, select_w ), spu_splats(1.0f) ); invSqrt = rsqrtf4( radicand ); zy_xz_yx = spu_sel( col0, col1, select_z ); zy_xz_yx = spu_shuffle( zy_xz_yx, col2, _VECTORMATH_SHUF_ZAY0 ); yz_zx_xy = spu_sel( col0, col1, select_x ); yz_zx_xy = spu_shuffle( yz_zx_xy, col2, _VECTORMATH_SHUF_BZX0 ); sum = spu_add( zy_xz_yx, yz_zx_xy ); diff = spu_sub( zy_xz_yx, yz_zx_xy ); scale = spu_mul( invSqrt, spu_splats(0.5f) ); res0 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_0ZYA ); res1 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_Z0XB ); res2 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_YX0C ); res3 = diff; res0 = spu_sel( res0, radicand, select_x ); res1 = spu_sel( res1, radicand, select_y ); res2 = spu_sel( res2, radicand, select_z ); res3 = spu_sel( res3, radicand, select_w ); res0 = spu_mul( res0, spu_shuffle( scale, scale, shuffle_xxxx ) ); res1 = spu_mul( res1, spu_shuffle( scale, scale, shuffle_yyyy ) ); res2 = spu_mul( res2, spu_shuffle( scale, scale, shuffle_zzzz ) ); res3 = spu_mul( res3, spu_shuffle( scale, scale, shuffle_wwww ) ); /* determine case and select answer */ xx = spu_shuffle( col0, col0, shuffle_xxxx ); yy = spu_shuffle( col1, col1, shuffle_yyyy ); zz = spu_shuffle( col2, col2, shuffle_zzzz ); res = spu_sel( res0, res1, spu_cmpgt( yy, xx ) ); res = spu_sel( res, res2, spu_and( spu_cmpgt( zz, xx ), spu_cmpgt( zz, yy ) ) ); res = spu_sel( res, res3, spu_cmpgt( spu_shuffle( diagSum, diagSum, shuffle_xxxx ), spu_splats(0.0f) ) ); result->vec128 = res; } static inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *tfrm0, const VmathVector3 *tfrm1 ) { vmathV3ScalarMul( &result->col0, tfrm0, vmathV3GetX( tfrm1 ) ); vmathV3ScalarMul( &result->col1, tfrm0, vmathV3GetY( tfrm1 ) ); vmathV3ScalarMul( &result->col2, tfrm0, vmathV3GetZ( tfrm1 ) ); } static inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *tfrm0, const VmathVector4 *tfrm1 ) { vmathV4ScalarMul( &result->col0, tfrm0, vmathV4GetX( tfrm1 ) ); vmathV4ScalarMul( &result->col1, tfrm0, vmathV4GetY( tfrm1 ) ); vmathV4ScalarMul( &result->col2, tfrm0, vmathV4GetZ( tfrm1 ) ); vmathV4ScalarMul( &result->col3, tfrm0, vmathV4GetW( tfrm1 ) ); } static inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ) { vec_float4 tmp0, tmp1, mcol0, mcol1, mcol2, res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); tmp0 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mat->col0.vec128, mat->col2.vec128, _VECTORMATH_SHUF_ZCWD ); xxxx = spu_shuffle( vec->vec128, vec->vec128, shuffle_xxxx ); mcol0 = spu_shuffle( tmp0, mat->col1.vec128, _VECTORMATH_SHUF_XAYB ); mcol1 = spu_shuffle( tmp0, mat->col1.vec128, _VECTORMATH_SHUF_ZBW0 ); mcol2 = spu_shuffle( tmp1, mat->col1.vec128, _VECTORMATH_SHUF_XCY0 ); yyyy = spu_shuffle( vec->vec128, vec->vec128, shuffle_yyyy ); res = spu_mul( mcol0, xxxx ); zzzz = spu_shuffle( vec->vec128, vec->vec128, shuffle_zzzz ); res = spu_madd( mcol1, yyyy, res ); res = spu_madd( mcol2, zzzz, res ); result->vec128 = res; } static inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec ) { vec_float4 neg, res0, res1, res2; neg = negatef4( vec->vec128 ); res0 = spu_shuffle( vec->vec128, neg, _VECTORMATH_SHUF_0ZB0 ); res1 = spu_shuffle( vec->vec128, neg, _VECTORMATH_SHUF_C0X0 ); res2 = spu_shuffle( vec->vec128, neg, _VECTORMATH_SHUF_YA00 ); result->col0.vec128 = res0; result->col1.vec128 = res1; result->col2.vec128 = res2; } static inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ) { VmathVector3 tmpV3_0, tmpV3_1, tmpV3_2; vmathV3Cross( &tmpV3_0, vec, &mat->col0 ); vmathV3Cross( &tmpV3_1, vec, &mat->col1 ); vmathV3Cross( &tmpV3_2, vec, &mat->col2 ); vmathM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 ); } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/mat_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_V_C_H #define _VECTORMATH_MAT_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for shuffles, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_0ZB0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_C0X0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_YA00 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_Z }) #define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X }) #define _VECTORMATH_SHUF_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y }) #define _VECTORMATH_SHUF_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZAY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_BZX0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_0ZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A }) #define _VECTORMATH_SHUF_Z0XB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YX0C ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_CZD0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_BBY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar ) { VmathMatrix3 result; vmathM3MakeFromScalar(&result, scalar); return result; } static inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat ) { VmathMatrix3 result; vmathM3MakeFromQ(&result, &unitQuat); return result; } static inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2 ) { VmathMatrix3 result; vmathM3MakeFromCols(&result, &_col0, &_col1, &_col2); return result; } static inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 _col0 ) { vmathM3SetCol0(result, &_col0); } static inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 _col1 ) { vmathM3SetCol1(result, &_col1); } static inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 _col2 ) { vmathM3SetCol2(result, &_col2); } static inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec ) { vmathM3SetCol(result, col, &vec); } static inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec ) { vmathM3SetRow(result, row, &vec); } static inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val ) { vmathM3SetElem(result, col, row, val); } static inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row ) { return vmathM3GetElem(&mat, col, row); } static inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol0(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol1(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat ) { VmathVector3 result; vmathM3GetCol2(&result, &mat); return result; } static inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col ) { VmathVector3 result; vmathM3GetCol(&result, &mat, col); return result; } static inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row ) { VmathVector3 result; vmathM3GetRow(&result, &mat, row); return result; } static inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Transpose(&result, &mat); return result; } static inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Inverse(&result, &mat); return result; } static inline float vmathM3Determinant_V( VmathMatrix3 mat ) { return vmathM3Determinant(&mat); } static inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Add(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Sub(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3Neg(&result, &mat); return result; } static inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3AbsPerElem(&result, &mat); return result; } static inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar ) { VmathMatrix3 result; vmathM3ScalarMul(&result, &mat, scalar); return result; } static inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec ) { VmathVector3 result; vmathM3MulV3(&result, &mat, &vec); return result; } static inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3Mul(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ) { VmathMatrix3 result; vmathM3MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathMatrix3 vmathM3MakeIdentity_V( ) { VmathMatrix3 result; vmathM3MakeIdentity(&result); return result; } static inline VmathMatrix3 vmathM3MakeRotationX_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationX(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationY_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationY(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians ) { VmathMatrix3 result; vmathM3MakeRotationZ(&result, radians); return result; } static inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathMatrix3 result; vmathM3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathMatrix3 result; vmathM3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat ) { VmathMatrix3 result; vmathM3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec ) { VmathMatrix3 result; vmathM3MakeScale(&result, &scaleVec); return result; } static inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec ) { VmathMatrix3 result; vmathM3AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat ) { VmathMatrix3 result; vmathM3PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 ) { VmathMatrix3 result; vmathM3Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathM3Print_V( VmathMatrix3 mat ) { vmathM3Print(&mat); } static inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name ) { vmathM3Prints(&mat, name); } #endif static inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar ) { VmathMatrix4 result; vmathM4MakeFromScalar(&result, scalar); return result; } static inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat ) { VmathMatrix4 result; vmathM4MakeFromT3(&result, &mat); return result; } static inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 _col0, VmathVector4 _col1, VmathVector4 _col2, VmathVector4 _col3 ) { VmathMatrix4 result; vmathM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeFromM3V3(&result, &mat, &translateVec); return result; } static inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 _col0 ) { vmathM4SetCol0(result, &_col0); } static inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 _col1 ) { vmathM4SetCol1(result, &_col1); } static inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 _col2 ) { vmathM4SetCol2(result, &_col2); } static inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 _col3 ) { vmathM4SetCol3(result, &_col3); } static inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec ) { vmathM4SetCol(result, col, &vec); } static inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec ) { vmathM4SetRow(result, row, &vec); } static inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val ) { vmathM4SetElem(result, col, row, val); } static inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row ) { return vmathM4GetElem(&mat, col, row); } static inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol0(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol1(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol2(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat ) { VmathVector4 result; vmathM4GetCol3(&result, &mat); return result; } static inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col ) { VmathVector4 result; vmathM4GetCol(&result, &mat, col); return result; } static inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row ) { VmathVector4 result; vmathM4GetRow(&result, &mat, row); return result; } static inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Transpose(&result, &mat); return result; } static inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Inverse(&result, &mat); return result; } static inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4AffineInverse(&result, &mat); return result; } static inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4OrthoInverse(&result, &mat); return result; } static inline float vmathM4Determinant_V( VmathMatrix4 mat ) { return vmathM4Determinant(&mat); } static inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Add(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Sub(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4Neg(&result, &mat); return result; } static inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4AbsPerElem(&result, &mat); return result; } static inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar ) { VmathMatrix4 result; vmathM4ScalarMul(&result, &mat, scalar); return result; } static inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec ) { VmathVector4 result; vmathM4MulV4(&result, &mat, &vec); return result; } static inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec ) { VmathVector4 result; vmathM4MulV3(&result, &mat, &vec); return result; } static inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt ) { VmathVector4 result; vmathM4MulP3(&result, &mat, &pnt); return result; } static inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4Mul(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm1 ) { VmathMatrix4 result; vmathM4MulT3(&result, &mat, &tfrm1); return result; } static inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ) { VmathMatrix4 result; vmathM4MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathMatrix4 vmathM4MakeIdentity_V( ) { VmathMatrix4 result; vmathM4MakeIdentity(&result); return result; } static inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 ) { vmathM4SetUpper3x3(result, &mat3); } static inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat ) { VmathMatrix3 result; vmathM4GetUpper3x3(&result, &mat); return result; } static inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec ) { vmathM4SetTranslation(result, &translateVec); } static inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat ) { VmathVector3 result; vmathM4GetTranslation(&result, &mat); return result; } static inline VmathMatrix4 vmathM4MakeRotationX_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationX(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationY_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationY(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians ) { VmathMatrix4 result; vmathM4MakeRotationZ(&result, radians); return result; } static inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathMatrix4 result; vmathM4MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathMatrix4 result; vmathM4MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat ) { VmathMatrix4 result; vmathM4MakeRotationQ(&result, &unitQuat); return result; } static inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec ) { VmathMatrix4 result; vmathM4MakeScale(&result, &scaleVec); return result; } static inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec ) { VmathMatrix4 result; vmathM4AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat ) { VmathMatrix4 result; vmathM4PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec ) { VmathMatrix4 result; vmathM4MakeTranslation(&result, &translateVec); return result; } static inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec ) { VmathMatrix4 result; vmathM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec); return result; } static inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar ) { VmathMatrix4 result; vmathM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 ) { VmathMatrix4 result; vmathM4Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathM4Print_V( VmathMatrix4 mat ) { vmathM4Print(&mat); } static inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name ) { vmathM4Prints(&mat, name); } #endif static inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar ) { VmathTransform3 result; vmathT3MakeFromScalar(&result, scalar); return result; } static inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 _col0, VmathVector3 _col1, VmathVector3 _col2, VmathVector3 _col3 ) { VmathTransform3 result; vmathT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeFromM3V3(&result, &tfrm, &translateVec); return result; } static inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 _col0 ) { vmathT3SetCol0(result, &_col0); } static inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 _col1 ) { vmathT3SetCol1(result, &_col1); } static inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 _col2 ) { vmathT3SetCol2(result, &_col2); } static inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 _col3 ) { vmathT3SetCol3(result, &_col3); } static inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec ) { vmathT3SetCol(result, col, &vec); } static inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec ) { vmathT3SetRow(result, row, &vec); } static inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val ) { vmathT3SetElem(result, col, row, val); } static inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row ) { return vmathT3GetElem(&tfrm, col, row); } static inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol0(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol1(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol2(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetCol3(&result, &tfrm); return result; } static inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col ) { VmathVector3 result; vmathT3GetCol(&result, &tfrm, col); return result; } static inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row ) { VmathVector4 result; vmathT3GetRow(&result, &tfrm, row); return result; } static inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3Inverse(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3OrthoInverse(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3AbsPerElem(&result, &tfrm); return result; } static inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec ) { VmathVector3 result; vmathT3MulV3(&result, &tfrm, &vec); return result; } static inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt ) { VmathPoint3 result; vmathT3MulP3(&result, &tfrm, &pnt); return result; } static inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ) { VmathTransform3 result; vmathT3Mul(&result, &tfrm0, &tfrm1); return result; } static inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ) { VmathTransform3 result; vmathT3MulPerElem(&result, &tfrm0, &tfrm1); return result; } static inline VmathTransform3 vmathT3MakeIdentity_V( ) { VmathTransform3 result; vmathT3MakeIdentity(&result); return result; } static inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 tfrm ) { vmathT3SetUpper3x3(result, &tfrm); } static inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm ) { VmathMatrix3 result; vmathT3GetUpper3x3(&result, &tfrm); return result; } static inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec ) { vmathT3SetTranslation(result, &translateVec); } static inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm ) { VmathVector3 result; vmathT3GetTranslation(&result, &tfrm); return result; } static inline VmathTransform3 vmathT3MakeRotationX_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationX(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationY_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationY(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationZ_V( float radians ) { VmathTransform3 result; vmathT3MakeRotationZ(&result, radians); return result; } static inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ ) { VmathTransform3 result; vmathT3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathTransform3 result; vmathT3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat ) { VmathTransform3 result; vmathT3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec ) { VmathTransform3 result; vmathT3MakeScale(&result, &scaleVec); return result; } static inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec ) { VmathTransform3 result; vmathT3AppendScale(&result, &tfrm, &scaleVec); return result; } static inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm ) { VmathTransform3 result; vmathT3PrependScale(&result, &scaleVec, &tfrm); return result; } static inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec ) { VmathTransform3 result; vmathT3MakeTranslation(&result, &translateVec); return result; } static inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 ) { VmathTransform3 result; vmathT3Select(&result, &tfrm0, &tfrm1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathT3Print_V( VmathTransform3 tfrm ) { vmathT3Print(&tfrm); } static inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name ) { vmathT3Prints(&tfrm, name); } #endif static inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 tfrm ) { VmathQuat result; vmathQMakeFromM3(&result, &tfrm); return result; } static inline VmathMatrix3 vmathV3Outer_V( VmathVector3 tfrm0, VmathVector3 tfrm1 ) { VmathMatrix3 result; vmathV3Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathMatrix4 vmathV4Outer_V( VmathVector4 tfrm0, VmathVector4 tfrm1 ) { VmathMatrix4 result; vmathV4Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat ) { VmathVector3 result; vmathV3RowMul(&result, &vec, &mat); return result; } static inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec ) { VmathMatrix3 result; vmathV3CrossMatrix(&result, &vec); return result; } static inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat ) { VmathMatrix3 result; vmathV3CrossMatrixMul(&result, &vec, &mat); return result; } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/mat_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_SOA_C_H #define _VECTORMATH_MAT_SOA_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants */ #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline void vmathSoaM3Copy( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Copy( &result->col0, &mat->col0 ); vmathSoaV3Copy( &result->col1, &mat->col1 ); vmathSoaV3Copy( &result->col2, &mat->col2 ); } static inline void vmathSoaM3MakeFromScalar( VmathSoaMatrix3 *result, vec_float4 scalar ) { vmathSoaV3MakeFromScalar( &result->col0, scalar ); vmathSoaV3MakeFromScalar( &result->col1, scalar ); vmathSoaV3MakeFromScalar( &result->col2, scalar ); } static inline void vmathSoaM3MakeFromQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat ) { vec_float4 qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; qx = unitQuat->x; qy = unitQuat->y; qz = unitQuat->z; qw = unitQuat->w; qx2 = spu_add( qx, qx ); qy2 = spu_add( qy, qy ); qz2 = spu_add( qz, qz ); qxqx2 = spu_mul( qx, qx2 ); qxqy2 = spu_mul( qx, qy2 ); qxqz2 = spu_mul( qx, qz2 ); qxqw2 = spu_mul( qw, qx2 ); qyqy2 = spu_mul( qy, qy2 ); qyqz2 = spu_mul( qy, qz2 ); qyqw2 = spu_mul( qw, qy2 ); qzqz2 = spu_mul( qz, qz2 ); qzqw2 = spu_mul( qw, qz2 ); vmathSoaV3MakeFromElems( &result->col0, spu_sub( spu_sub( spu_splats(1.0f), qyqy2 ), qzqz2 ), spu_add( qxqy2, qzqw2 ), spu_sub( qxqz2, qyqw2 ) ); vmathSoaV3MakeFromElems( &result->col1, spu_sub( qxqy2, qzqw2 ), spu_sub( spu_sub( spu_splats(1.0f), qxqx2 ), qzqz2 ), spu_add( qyqz2, qxqw2 ) ); vmathSoaV3MakeFromElems( &result->col2, spu_add( qxqz2, qyqw2 ), spu_sub( qyqz2, qxqw2 ), spu_sub( spu_sub( spu_splats(1.0f), qxqx2 ), qyqy2 ) ); } static inline void vmathSoaM3MakeFromCols( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col0, const VmathSoaVector3 *_col1, const VmathSoaVector3 *_col2 ) { vmathSoaV3Copy( &result->col0, _col0 ); vmathSoaV3Copy( &result->col1, _col1 ); vmathSoaV3Copy( &result->col2, _col2 ); } static inline void vmathSoaM3MakeFromAos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat ) { vmathSoaV3MakeFromAos( &result->col0, &mat->col0 ); vmathSoaV3MakeFromAos( &result->col1, &mat->col1 ); vmathSoaV3MakeFromAos( &result->col2, &mat->col2 ); } static inline void vmathSoaM3MakeFrom4Aos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, const VmathMatrix3 *mat2, const VmathMatrix3 *mat3 ) { vmathSoaV3MakeFrom4Aos( &result->col0, &mat0->col0, &mat1->col0, &mat2->col0, &mat3->col0 ); vmathSoaV3MakeFrom4Aos( &result->col1, &mat0->col1, &mat1->col1, &mat2->col1, &mat3->col1 ); vmathSoaV3MakeFrom4Aos( &result->col2, &mat0->col2, &mat1->col2, &mat2->col2, &mat3->col2 ); } static inline void vmathSoaM3Get4Aos( const VmathSoaMatrix3 *mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 ) { vmathSoaV3Get4Aos( &mat->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 ); vmathSoaV3Get4Aos( &mat->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 ); vmathSoaV3Get4Aos( &mat->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 ); } static inline void vmathSoaM3SetCol0( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col0 ) { vmathSoaV3Copy( &result->col0, _col0 ); } static inline void vmathSoaM3SetCol1( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col1 ) { vmathSoaV3Copy( &result->col1, _col1 ); } static inline void vmathSoaM3SetCol2( VmathSoaMatrix3 *result, const VmathSoaVector3 *_col2 ) { vmathSoaV3Copy( &result->col2, _col2 ); } static inline void vmathSoaM3SetCol( VmathSoaMatrix3 *result, int col, const VmathSoaVector3 *vec ) { vmathSoaV3Copy( (&result->col0 + col), vec ); } static inline void vmathSoaM3SetRow( VmathSoaMatrix3 *result, int row, const VmathSoaVector3 *vec ) { vmathSoaV3SetElem( &result->col0, row, vmathSoaV3GetElem( vec, 0 ) ); vmathSoaV3SetElem( &result->col1, row, vmathSoaV3GetElem( vec, 1 ) ); vmathSoaV3SetElem( &result->col2, row, vmathSoaV3GetElem( vec, 2 ) ); } static inline void vmathSoaM3SetElem( VmathSoaMatrix3 *result, int col, int row, vec_float4 val ) { VmathSoaVector3 tmpV3_0; vmathSoaM3GetCol( &tmpV3_0, result, col ); vmathSoaV3SetElem( &tmpV3_0, row, val ); vmathSoaM3SetCol( result, col, &tmpV3_0 ); } static inline vec_float4 vmathSoaM3GetElem( const VmathSoaMatrix3 *mat, int col, int row ) { VmathSoaVector3 tmpV3_0; vmathSoaM3GetCol( &tmpV3_0, mat, col ); return vmathSoaV3GetElem( &tmpV3_0, row ); } static inline void vmathSoaM3GetCol0( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Copy( result, &mat->col0 ); } static inline void vmathSoaM3GetCol1( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Copy( result, &mat->col1 ); } static inline void vmathSoaM3GetCol2( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Copy( result, &mat->col2 ); } static inline void vmathSoaM3GetCol( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int col ) { vmathSoaV3Copy( result, (&mat->col0 + col) ); } static inline void vmathSoaM3GetRow( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int row ) { vmathSoaV3MakeFromElems( result, vmathSoaV3GetElem( &mat->col0, row ), vmathSoaV3GetElem( &mat->col1, row ), vmathSoaV3GetElem( &mat->col2, row ) ); } static inline void vmathSoaM3Transpose( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { VmathSoaMatrix3 tmpResult; vmathSoaV3MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x ); vmathSoaV3MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y ); vmathSoaV3MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z ); vmathSoaM3Copy( result, &tmpResult ); } static inline void vmathSoaM3Inverse( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { VmathSoaVector3 tmp0, tmp1, tmp2; vec_float4 detinv; vmathSoaV3Cross( &tmp0, &mat->col1, &mat->col2 ); vmathSoaV3Cross( &tmp1, &mat->col2, &mat->col0 ); vmathSoaV3Cross( &tmp2, &mat->col0, &mat->col1 ); detinv = recipf4( vmathSoaV3Dot( &mat->col2, &tmp2 ) ); vmathSoaV3MakeFromElems( &result->col0, spu_mul( tmp0.x, detinv ), spu_mul( tmp1.x, detinv ), spu_mul( tmp2.x, detinv ) ); vmathSoaV3MakeFromElems( &result->col1, spu_mul( tmp0.y, detinv ), spu_mul( tmp1.y, detinv ), spu_mul( tmp2.y, detinv ) ); vmathSoaV3MakeFromElems( &result->col2, spu_mul( tmp0.z, detinv ), spu_mul( tmp1.z, detinv ), spu_mul( tmp2.z, detinv ) ); } static inline vec_float4 vmathSoaM3Determinant( const VmathSoaMatrix3 *mat ) { VmathSoaVector3 tmpV3_0; vmathSoaV3Cross( &tmpV3_0, &mat->col0, &mat->col1 ); return vmathSoaV3Dot( &mat->col2, &tmpV3_0 ); } static inline void vmathSoaM3Add( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ) { vmathSoaV3Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV3Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV3Add( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathSoaM3Sub( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ) { vmathSoaV3Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV3Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV3Sub( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathSoaM3Neg( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3Neg( &result->col0, &mat->col0 ); vmathSoaV3Neg( &result->col1, &mat->col1 ); vmathSoaV3Neg( &result->col2, &mat->col2 ); } static inline void vmathSoaM3AbsPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ) { vmathSoaV3AbsPerElem( &result->col0, &mat->col0 ); vmathSoaV3AbsPerElem( &result->col1, &mat->col1 ); vmathSoaV3AbsPerElem( &result->col2, &mat->col2 ); } static inline void vmathSoaM3ScalarMul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, vec_float4 scalar ) { vmathSoaV3ScalarMul( &result->col0, &mat->col0, scalar ); vmathSoaV3ScalarMul( &result->col1, &mat->col1, scalar ); vmathSoaV3ScalarMul( &result->col2, &mat->col2, scalar ); } static inline void vmathSoaM3MulV3( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *vec ) { vec_float4 tmpX, tmpY, tmpZ; 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 ) ); 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 ) ); 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 ) ); vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaM3Mul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ) { VmathSoaMatrix3 tmpResult; vmathSoaM3MulV3( &tmpResult.col0, mat0, &mat1->col0 ); vmathSoaM3MulV3( &tmpResult.col1, mat0, &mat1->col1 ); vmathSoaM3MulV3( &tmpResult.col2, mat0, &mat1->col2 ); vmathSoaM3Copy( result, &tmpResult ); } static inline void vmathSoaM3MulPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ) { vmathSoaV3MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV3MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV3MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); } static inline void vmathSoaM3MakeIdentity( VmathSoaMatrix3 *result ) { vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeZAxis( &result->col2 ); } static inline void vmathSoaM3MakeRotationX( VmathSoaMatrix3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeFromElems( &result->col1, spu_splats(0.0f), c, s ); vmathSoaV3MakeFromElems( &result->col2, spu_splats(0.0f), negatef4( s ), c ); } static inline void vmathSoaM3MakeRotationY( VmathSoaMatrix3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeFromElems( &result->col0, c, spu_splats(0.0f), negatef4( s ) ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeFromElems( &result->col2, s, spu_splats(0.0f), c ); } static inline void vmathSoaM3MakeRotationZ( VmathSoaMatrix3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeFromElems( &result->col0, c, s, spu_splats(0.0f) ); vmathSoaV3MakeFromElems( &result->col1, negatef4( s ), c, spu_splats(0.0f) ); vmathSoaV3MakeZAxis( &result->col2 ); } static inline void vmathSoaM3MakeRotationZYX( VmathSoaMatrix3 *result, const VmathSoaVector3 *radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ->x, &sX, &cX ); sincosf4( radiansXYZ->y, &sY, &cY ); sincosf4( radiansXYZ->z, &sZ, &cZ ); tmp0 = spu_mul( cZ, sY ); tmp1 = spu_mul( sZ, sY ); vmathSoaV3MakeFromElems( &result->col0, spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ) ); 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 ) ); 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 ) ); } static inline void vmathSoaM3MakeRotationAxis( VmathSoaMatrix3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ) { vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx; sincosf4( radians, &s, &c ); x = unitVec->x; y = unitVec->y; z = unitVec->z; xy = spu_mul( x, y ); yz = spu_mul( y, z ); zx = spu_mul( z, x ); oneMinusC = spu_sub( spu_splats(1.0f), c ); 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 ) ) ); 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 ) ) ); 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 ) ); } static inline void vmathSoaM3MakeRotationQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat ) { vmathSoaM3MakeFromQ( result, unitQuat ); } static inline void vmathSoaM3MakeScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec ) { vmathSoaV3MakeFromElems( &result->col0, scaleVec->x, spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV3MakeFromElems( &result->col1, spu_splats(0.0f), scaleVec->y, spu_splats(0.0f) ); vmathSoaV3MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), scaleVec->z ); } static inline void vmathSoaM3AppendScale( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *scaleVec ) { vmathSoaV3ScalarMul( &result->col0, &mat->col0, vmathSoaV3GetX( scaleVec ) ); vmathSoaV3ScalarMul( &result->col1, &mat->col1, vmathSoaV3GetY( scaleVec ) ); vmathSoaV3ScalarMul( &result->col2, &mat->col2, vmathSoaV3GetZ( scaleVec ) ); } static inline void vmathSoaM3PrependScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix3 *mat ) { vmathSoaV3MulPerElem( &result->col0, &mat->col0, scaleVec ); vmathSoaV3MulPerElem( &result->col1, &mat->col1, scaleVec ); vmathSoaV3MulPerElem( &result->col2, &mat->col2, scaleVec ); } static inline void vmathSoaM3Select( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1, vec_uint4 select1 ) { vmathSoaV3Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathSoaV3Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathSoaV3Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaM3Print( const VmathSoaMatrix3 *mat ) { VmathMatrix3 mat0, mat1, mat2, mat3; vmathSoaM3Get4Aos( mat, &mat0, &mat1, &mat2, &mat3 ); printf("slot 0:\n"); vmathM3Print( &mat0 ); printf("slot 1:\n"); vmathM3Print( &mat1 ); printf("slot 2:\n"); vmathM3Print( &mat2 ); printf("slot 3:\n"); vmathM3Print( &mat3 ); } static inline void vmathSoaM3Prints( const VmathSoaMatrix3 *mat, const char *name ) { printf("%s:\n", name); vmathSoaM3Print( mat ); } #endif static inline void vmathSoaM4Copy( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( &result->col0, &mat->col0 ); vmathSoaV4Copy( &result->col1, &mat->col1 ); vmathSoaV4Copy( &result->col2, &mat->col2 ); vmathSoaV4Copy( &result->col3, &mat->col3 ); } static inline void vmathSoaM4MakeFromScalar( VmathSoaMatrix4 *result, vec_float4 scalar ) { vmathSoaV4MakeFromScalar( &result->col0, scalar ); vmathSoaV4MakeFromScalar( &result->col1, scalar ); vmathSoaV4MakeFromScalar( &result->col2, scalar ); vmathSoaV4MakeFromScalar( &result->col3, scalar ); } static inline void vmathSoaM4MakeFromT3( VmathSoaMatrix4 *result, const VmathSoaTransform3 *mat ) { vmathSoaV4MakeFromV3Scalar( &result->col0, &mat->col0, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col1, &mat->col1, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col2, &mat->col2, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col3, &mat->col3, spu_splats(1.0f) ); } static inline void vmathSoaM4MakeFromCols( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col0, const VmathSoaVector4 *_col1, const VmathSoaVector4 *_col2, const VmathSoaVector4 *_col3 ) { vmathSoaV4Copy( &result->col0, _col0 ); vmathSoaV4Copy( &result->col1, _col1 ); vmathSoaV4Copy( &result->col2, _col2 ); vmathSoaV4Copy( &result->col3, _col3 ); } static inline void vmathSoaM4MakeFromM3V3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *translateVec ) { vmathSoaV4MakeFromV3Scalar( &result->col0, &mat->col0, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col1, &mat->col1, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col2, &mat->col2, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, spu_splats(1.0f) ); } static inline void vmathSoaM4MakeFromQV3( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec ) { VmathSoaMatrix3 mat; vmathSoaM3MakeFromQ( &mat, unitQuat ); vmathSoaV4MakeFromV3Scalar( &result->col0, &mat.col0, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col1, &mat.col1, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col2, &mat.col2, spu_splats(0.0f) ); vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, spu_splats(1.0f) ); } static inline void vmathSoaM4MakeFromAos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat ) { vmathSoaV4MakeFromAos( &result->col0, &mat->col0 ); vmathSoaV4MakeFromAos( &result->col1, &mat->col1 ); vmathSoaV4MakeFromAos( &result->col2, &mat->col2 ); vmathSoaV4MakeFromAos( &result->col3, &mat->col3 ); } static inline void vmathSoaM4MakeFrom4Aos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, const VmathMatrix4 *mat2, const VmathMatrix4 *mat3 ) { vmathSoaV4MakeFrom4Aos( &result->col0, &mat0->col0, &mat1->col0, &mat2->col0, &mat3->col0 ); vmathSoaV4MakeFrom4Aos( &result->col1, &mat0->col1, &mat1->col1, &mat2->col1, &mat3->col1 ); vmathSoaV4MakeFrom4Aos( &result->col2, &mat0->col2, &mat1->col2, &mat2->col2, &mat3->col2 ); vmathSoaV4MakeFrom4Aos( &result->col3, &mat0->col3, &mat1->col3, &mat2->col3, &mat3->col3 ); } static inline void vmathSoaM4Get4Aos( const VmathSoaMatrix4 *mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 ) { vmathSoaV4Get4Aos( &mat->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 ); vmathSoaV4Get4Aos( &mat->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 ); vmathSoaV4Get4Aos( &mat->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 ); vmathSoaV4Get4Aos( &mat->col3, &result0->col3, &result1->col3, &result2->col3, &result3->col3 ); } static inline void vmathSoaM4SetCol0( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col0 ) { vmathSoaV4Copy( &result->col0, _col0 ); } static inline void vmathSoaM4SetCol1( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col1 ) { vmathSoaV4Copy( &result->col1, _col1 ); } static inline void vmathSoaM4SetCol2( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col2 ) { vmathSoaV4Copy( &result->col2, _col2 ); } static inline void vmathSoaM4SetCol3( VmathSoaMatrix4 *result, const VmathSoaVector4 *_col3 ) { vmathSoaV4Copy( &result->col3, _col3 ); } static inline void vmathSoaM4SetCol( VmathSoaMatrix4 *result, int col, const VmathSoaVector4 *vec ) { vmathSoaV4Copy( (&result->col0 + col), vec ); } static inline void vmathSoaM4SetRow( VmathSoaMatrix4 *result, int row, const VmathSoaVector4 *vec ) { vmathSoaV4SetElem( &result->col0, row, vmathSoaV4GetElem( vec, 0 ) ); vmathSoaV4SetElem( &result->col1, row, vmathSoaV4GetElem( vec, 1 ) ); vmathSoaV4SetElem( &result->col2, row, vmathSoaV4GetElem( vec, 2 ) ); vmathSoaV4SetElem( &result->col3, row, vmathSoaV4GetElem( vec, 3 ) ); } static inline void vmathSoaM4SetElem( VmathSoaMatrix4 *result, int col, int row, vec_float4 val ) { VmathSoaVector4 tmpV3_0; vmathSoaM4GetCol( &tmpV3_0, result, col ); vmathSoaV4SetElem( &tmpV3_0, row, val ); vmathSoaM4SetCol( result, col, &tmpV3_0 ); } static inline vec_float4 vmathSoaM4GetElem( const VmathSoaMatrix4 *mat, int col, int row ) { VmathSoaVector4 tmpV4_0; vmathSoaM4GetCol( &tmpV4_0, mat, col ); return vmathSoaV4GetElem( &tmpV4_0, row ); } static inline void vmathSoaM4GetCol0( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( result, &mat->col0 ); } static inline void vmathSoaM4GetCol1( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( result, &mat->col1 ); } static inline void vmathSoaM4GetCol2( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( result, &mat->col2 ); } static inline void vmathSoaM4GetCol3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Copy( result, &mat->col3 ); } static inline void vmathSoaM4GetCol( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int col ) { vmathSoaV4Copy( result, (&mat->col0 + col) ); } static inline void vmathSoaM4GetRow( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int row ) { vmathSoaV4MakeFromElems( result, vmathSoaV4GetElem( &mat->col0, row ), vmathSoaV4GetElem( &mat->col1, row ), vmathSoaV4GetElem( &mat->col2, row ), vmathSoaV4GetElem( &mat->col3, row ) ); } static inline void vmathSoaM4Transpose( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { VmathSoaMatrix4 tmpResult; vmathSoaV4MakeFromElems( &tmpResult.col0, mat->col0.x, mat->col1.x, mat->col2.x, mat->col3.x ); vmathSoaV4MakeFromElems( &tmpResult.col1, mat->col0.y, mat->col1.y, mat->col2.y, mat->col3.y ); vmathSoaV4MakeFromElems( &tmpResult.col2, mat->col0.z, mat->col1.z, mat->col2.z, mat->col3.z ); vmathSoaV4MakeFromElems( &tmpResult.col3, mat->col0.w, mat->col1.w, mat->col2.w, mat->col3.w ); vmathSoaM4Copy( result, &tmpResult ); } static inline void vmathSoaM4Inverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { VmathSoaVector4 res0, res1, res2, res3; 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; mA = mat->col0.x; mB = mat->col0.y; mC = mat->col0.z; mD = mat->col0.w; mE = mat->col1.x; mF = mat->col1.y; mG = mat->col1.z; mH = mat->col1.w; mI = mat->col2.x; mJ = mat->col2.y; mK = mat->col2.z; mL = mat->col2.w; mM = mat->col3.x; mN = mat->col3.y; mO = mat->col3.z; mP = mat->col3.w; tmp0 = spu_sub( spu_mul( mK, mD ), spu_mul( mC, mL ) ); tmp1 = spu_sub( spu_mul( mO, mH ), spu_mul( mG, mP ) ); tmp2 = spu_sub( spu_mul( mB, mK ), spu_mul( mJ, mC ) ); tmp3 = spu_sub( spu_mul( mF, mO ), spu_mul( mN, mG ) ); tmp4 = spu_sub( spu_mul( mJ, mD ), spu_mul( mB, mL ) ); tmp5 = spu_sub( spu_mul( mN, mH ), spu_mul( mF, mP ) ); vmathSoaV4SetX( &res0, spu_sub( spu_sub( spu_mul( mJ, tmp1 ), spu_mul( mL, tmp3 ) ), spu_mul( mK, tmp5 ) ) ); vmathSoaV4SetY( &res0, spu_sub( spu_sub( spu_mul( mN, tmp0 ), spu_mul( mP, tmp2 ) ), spu_mul( mO, tmp4 ) ) ); vmathSoaV4SetZ( &res0, spu_sub( spu_add( spu_mul( mD, tmp3 ), spu_mul( mC, tmp5 ) ), spu_mul( mB, tmp1 ) ) ); vmathSoaV4SetW( &res0, spu_sub( spu_add( spu_mul( mH, tmp2 ), spu_mul( mG, tmp4 ) ), spu_mul( mF, tmp0 ) ) ); 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 ) ) ); vmathSoaV4SetX( &res1, spu_mul( mI, tmp1 ) ); vmathSoaV4SetY( &res1, spu_mul( mM, tmp0 ) ); vmathSoaV4SetZ( &res1, spu_mul( mA, tmp1 ) ); vmathSoaV4SetW( &res1, spu_mul( mE, tmp0 ) ); vmathSoaV4SetX( &res3, spu_mul( mI, tmp3 ) ); vmathSoaV4SetY( &res3, spu_mul( mM, tmp2 ) ); vmathSoaV4SetZ( &res3, spu_mul( mA, tmp3 ) ); vmathSoaV4SetW( &res3, spu_mul( mE, tmp2 ) ); vmathSoaV4SetX( &res2, spu_mul( mI, tmp5 ) ); vmathSoaV4SetY( &res2, spu_mul( mM, tmp4 ) ); vmathSoaV4SetZ( &res2, spu_mul( mA, tmp5 ) ); vmathSoaV4SetW( &res2, spu_mul( mE, tmp4 ) ); tmp0 = spu_sub( spu_mul( mI, mB ), spu_mul( mA, mJ ) ); tmp1 = spu_sub( spu_mul( mM, mF ), spu_mul( mE, mN ) ); tmp2 = spu_sub( spu_mul( mI, mD ), spu_mul( mA, mL ) ); tmp3 = spu_sub( spu_mul( mM, mH ), spu_mul( mE, mP ) ); tmp4 = spu_sub( spu_mul( mI, mC ), spu_mul( mA, mK ) ); tmp5 = spu_sub( spu_mul( mM, mG ), spu_mul( mE, mO ) ); vmathSoaV4SetX( &res2, spu_add( spu_sub( spu_mul( mL, tmp1 ), spu_mul( mJ, tmp3 ) ), res2.x ) ); vmathSoaV4SetY( &res2, spu_add( spu_sub( spu_mul( mP, tmp0 ), spu_mul( mN, tmp2 ) ), res2.y ) ); vmathSoaV4SetZ( &res2, spu_sub( spu_sub( spu_mul( mB, tmp3 ), spu_mul( mD, tmp1 ) ), res2.z ) ); vmathSoaV4SetW( &res2, spu_sub( spu_sub( spu_mul( mF, tmp2 ), spu_mul( mH, tmp0 ) ), res2.w ) ); vmathSoaV4SetX( &res3, spu_add( spu_sub( spu_mul( mJ, tmp5 ), spu_mul( mK, tmp1 ) ), res3.x ) ); vmathSoaV4SetY( &res3, spu_add( spu_sub( spu_mul( mN, tmp4 ), spu_mul( mO, tmp0 ) ), res3.y ) ); vmathSoaV4SetZ( &res3, spu_sub( spu_sub( spu_mul( mC, tmp1 ), spu_mul( mB, tmp5 ) ), res3.z ) ); vmathSoaV4SetW( &res3, spu_sub( spu_sub( spu_mul( mG, tmp0 ), spu_mul( mF, tmp4 ) ), res3.w ) ); vmathSoaV4SetX( &res1, spu_sub( spu_sub( spu_mul( mK, tmp3 ), spu_mul( mL, tmp5 ) ), res1.x ) ); vmathSoaV4SetY( &res1, spu_sub( spu_sub( spu_mul( mO, tmp2 ), spu_mul( mP, tmp4 ) ), res1.y ) ); vmathSoaV4SetZ( &res1, spu_add( spu_sub( spu_mul( mD, tmp5 ), spu_mul( mC, tmp3 ) ), res1.z ) ); vmathSoaV4SetW( &res1, spu_add( spu_sub( spu_mul( mH, tmp4 ), spu_mul( mG, tmp2 ) ), res1.w ) ); vmathSoaV4ScalarMul( &result->col0, &res0, detInv ); vmathSoaV4ScalarMul( &result->col1, &res1, detInv ); vmathSoaV4ScalarMul( &result->col2, &res2, detInv ); vmathSoaV4ScalarMul( &result->col3, &res3, detInv ); } static inline void vmathSoaM4AffineInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { VmathSoaTransform3 affineMat, tmpT3_0; VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathSoaV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathSoaT3SetCol0( &affineMat, &tmpV3_0 ); vmathSoaV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathSoaT3SetCol1( &affineMat, &tmpV3_1 ); vmathSoaV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathSoaT3SetCol2( &affineMat, &tmpV3_2 ); vmathSoaV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathSoaT3SetCol3( &affineMat, &tmpV3_3 ); vmathSoaT3Inverse( &tmpT3_0, &affineMat ); vmathSoaM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathSoaM4OrthoInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { VmathSoaTransform3 affineMat, tmpT3_0; VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; vmathSoaV4GetXYZ( &tmpV3_0, &mat->col0 ); vmathSoaT3SetCol0( &affineMat, &tmpV3_0 ); vmathSoaV4GetXYZ( &tmpV3_1, &mat->col1 ); vmathSoaT3SetCol1( &affineMat, &tmpV3_1 ); vmathSoaV4GetXYZ( &tmpV3_2, &mat->col2 ); vmathSoaT3SetCol2( &affineMat, &tmpV3_2 ); vmathSoaV4GetXYZ( &tmpV3_3, &mat->col3 ); vmathSoaT3SetCol3( &affineMat, &tmpV3_3 ); vmathSoaT3OrthoInverse( &tmpT3_0, &affineMat ); vmathSoaM4MakeFromT3( result, &tmpT3_0 ); } static inline vec_float4 vmathSoaM4Determinant( const VmathSoaMatrix4 *mat ) { 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; mA = mat->col0.x; mB = mat->col0.y; mC = mat->col0.z; mD = mat->col0.w; mE = mat->col1.x; mF = mat->col1.y; mG = mat->col1.z; mH = mat->col1.w; mI = mat->col2.x; mJ = mat->col2.y; mK = mat->col2.z; mL = mat->col2.w; mM = mat->col3.x; mN = mat->col3.y; mO = mat->col3.z; mP = mat->col3.w; tmp0 = spu_sub( spu_mul( mK, mD ), spu_mul( mC, mL ) ); tmp1 = spu_sub( spu_mul( mO, mH ), spu_mul( mG, mP ) ); tmp2 = spu_sub( spu_mul( mB, mK ), spu_mul( mJ, mC ) ); tmp3 = spu_sub( spu_mul( mF, mO ), spu_mul( mN, mG ) ); tmp4 = spu_sub( spu_mul( mJ, mD ), spu_mul( mB, mL ) ); tmp5 = spu_sub( spu_mul( mN, mH ), spu_mul( mF, mP ) ); dx = spu_sub( spu_sub( spu_mul( mJ, tmp1 ), spu_mul( mL, tmp3 ) ), spu_mul( mK, tmp5 ) ); dy = spu_sub( spu_sub( spu_mul( mN, tmp0 ), spu_mul( mP, tmp2 ) ), spu_mul( mO, tmp4 ) ); dz = spu_sub( spu_add( spu_mul( mD, tmp3 ), spu_mul( mC, tmp5 ) ), spu_mul( mB, tmp1 ) ); dw = spu_sub( spu_add( spu_mul( mH, tmp2 ), spu_mul( mG, tmp4 ) ), spu_mul( mF, tmp0 ) ); return spu_add( spu_add( spu_add( spu_mul( mA, dx ), spu_mul( mE, dy ) ), spu_mul( mI, dz ) ), spu_mul( mM, dw ) ); } static inline void vmathSoaM4Add( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ) { vmathSoaV4Add( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV4Add( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV4Add( &result->col2, &mat0->col2, &mat1->col2 ); vmathSoaV4Add( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathSoaM4Sub( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ) { vmathSoaV4Sub( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV4Sub( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV4Sub( &result->col2, &mat0->col2, &mat1->col2 ); vmathSoaV4Sub( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathSoaM4Neg( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4Neg( &result->col0, &mat->col0 ); vmathSoaV4Neg( &result->col1, &mat->col1 ); vmathSoaV4Neg( &result->col2, &mat->col2 ); vmathSoaV4Neg( &result->col3, &mat->col3 ); } static inline void vmathSoaM4AbsPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4AbsPerElem( &result->col0, &mat->col0 ); vmathSoaV4AbsPerElem( &result->col1, &mat->col1 ); vmathSoaV4AbsPerElem( &result->col2, &mat->col2 ); vmathSoaV4AbsPerElem( &result->col3, &mat->col3 ); } static inline void vmathSoaM4ScalarMul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, vec_float4 scalar ) { vmathSoaV4ScalarMul( &result->col0, &mat->col0, scalar ); vmathSoaV4ScalarMul( &result->col1, &mat->col1, scalar ); vmathSoaV4ScalarMul( &result->col2, &mat->col2, scalar ); vmathSoaV4ScalarMul( &result->col3, &mat->col3, scalar ); } static inline void vmathSoaM4MulV4( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector4 *vec ) { vec_float4 tmpX, tmpY, tmpZ, tmpW; 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 ) ); 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 ) ); 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 ) ); 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 ) ); vmathSoaV4MakeFromElems( result, tmpX, tmpY, tmpZ, tmpW ); } static inline void vmathSoaM4MulV3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *vec ) { 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 ) ); 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 ) ); 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 ) ); 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 ) ); } static inline void vmathSoaM4MulP3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaPoint3 *pnt ) { 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 ); 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 ); 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 ); 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 ); } static inline void vmathSoaM4Mul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ) { VmathSoaMatrix4 tmpResult; vmathSoaM4MulV4( &tmpResult.col0, mat0, &mat1->col0 ); vmathSoaM4MulV4( &tmpResult.col1, mat0, &mat1->col1 ); vmathSoaM4MulV4( &tmpResult.col2, mat0, &mat1->col2 ); vmathSoaM4MulV4( &tmpResult.col3, mat0, &mat1->col3 ); vmathSoaM4Copy( result, &tmpResult ); } static inline void vmathSoaM4MulT3( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaTransform3 *tfrm1 ) { VmathSoaMatrix4 tmpResult; VmathSoaPoint3 tmpP3_0; vmathSoaM4MulV3( &tmpResult.col0, mat, &tfrm1->col0 ); vmathSoaM4MulV3( &tmpResult.col1, mat, &tfrm1->col1 ); vmathSoaM4MulV3( &tmpResult.col2, mat, &tfrm1->col2 ); vmathSoaP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathSoaM4MulP3( &tmpResult.col3, mat, &tmpP3_0 ); vmathSoaM4Copy( result, &tmpResult ); } static inline void vmathSoaM4MulPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ) { vmathSoaV4MulPerElem( &result->col0, &mat0->col0, &mat1->col0 ); vmathSoaV4MulPerElem( &result->col1, &mat0->col1, &mat1->col1 ); vmathSoaV4MulPerElem( &result->col2, &mat0->col2, &mat1->col2 ); vmathSoaV4MulPerElem( &result->col3, &mat0->col3, &mat1->col3 ); } static inline void vmathSoaM4MakeIdentity( VmathSoaMatrix4 *result ) { vmathSoaV4MakeXAxis( &result->col0 ); vmathSoaV4MakeYAxis( &result->col1 ); vmathSoaV4MakeZAxis( &result->col2 ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4SetUpper3x3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat3 ) { vmathSoaV4SetXYZ( &result->col0, &mat3->col0 ); vmathSoaV4SetXYZ( &result->col1, &mat3->col1 ); vmathSoaV4SetXYZ( &result->col2, &mat3->col2 ); } static inline void vmathSoaM4GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4GetXYZ( &result->col0, &mat->col0 ); vmathSoaV4GetXYZ( &result->col1, &mat->col1 ); vmathSoaV4GetXYZ( &result->col2, &mat->col2 ); } static inline void vmathSoaM4SetTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec ) { vmathSoaV4SetXYZ( &result->col3, translateVec ); } static inline void vmathSoaM4GetTranslation( VmathSoaVector3 *result, const VmathSoaMatrix4 *mat ) { vmathSoaV4GetXYZ( result, &mat->col3 ); } static inline void vmathSoaM4MakeRotationX( VmathSoaMatrix4 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV4MakeXAxis( &result->col0 ); vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), c, s, spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col2, spu_splats(0.0f), negatef4( s ), c, spu_splats(0.0f) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationY( VmathSoaMatrix4 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV4MakeFromElems( &result->col0, c, spu_splats(0.0f), negatef4( s ), spu_splats(0.0f) ); vmathSoaV4MakeYAxis( &result->col1 ); vmathSoaV4MakeFromElems( &result->col2, s, spu_splats(0.0f), c, spu_splats(0.0f) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationZ( VmathSoaMatrix4 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV4MakeFromElems( &result->col0, c, s, spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col1, negatef4( s ), c, spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeZAxis( &result->col2 ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationZYX( VmathSoaMatrix4 *result, const VmathSoaVector3 *radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ->x, &sX, &cX ); sincosf4( radiansXYZ->y, &sY, &cY ); sincosf4( radiansXYZ->z, &sZ, &cZ ); tmp0 = spu_mul( cZ, sY ); tmp1 = spu_mul( sZ, sY ); vmathSoaV4MakeFromElems( &result->col0, spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ), spu_splats(0.0f) ); 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) ); 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) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationAxis( VmathSoaMatrix4 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ) { vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx; sincosf4( radians, &s, &c ); x = unitVec->x; y = unitVec->y; z = unitVec->z; xy = spu_mul( x, y ); yz = spu_mul( y, z ); zx = spu_mul( z, x ); oneMinusC = spu_sub( spu_splats(1.0f), c ); 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) ); 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) ); 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) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4MakeRotationQ( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat ) { VmathSoaTransform3 tmpT3_0; vmathSoaT3MakeRotationQ( &tmpT3_0, unitQuat ); vmathSoaM4MakeFromT3( result, &tmpT3_0 ); } static inline void vmathSoaM4MakeScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec ) { vmathSoaV4MakeFromElems( &result->col0, scaleVec->x, spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), scaleVec->y, spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), scaleVec->z, spu_splats(0.0f) ); vmathSoaV4MakeWAxis( &result->col3 ); } static inline void vmathSoaM4AppendScale( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *scaleVec ) { vmathSoaV4ScalarMul( &result->col0, &mat->col0, vmathSoaV3GetX( scaleVec ) ); vmathSoaV4ScalarMul( &result->col1, &mat->col1, vmathSoaV3GetY( scaleVec ) ); vmathSoaV4ScalarMul( &result->col2, &mat->col2, vmathSoaV3GetZ( scaleVec ) ); vmathSoaV4Copy( &result->col3, &mat->col3 ); } static inline void vmathSoaM4PrependScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix4 *mat ) { VmathSoaVector4 scale4; vmathSoaV4MakeFromV3Scalar( &scale4, scaleVec, spu_splats(1.0f) ); vmathSoaV4MulPerElem( &result->col0, &mat->col0, &scale4 ); vmathSoaV4MulPerElem( &result->col1, &mat->col1, &scale4 ); vmathSoaV4MulPerElem( &result->col2, &mat->col2, &scale4 ); vmathSoaV4MulPerElem( &result->col3, &mat->col3, &scale4 ); } static inline void vmathSoaM4MakeTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec ) { vmathSoaV4MakeXAxis( &result->col0 ); vmathSoaV4MakeYAxis( &result->col1 ); vmathSoaV4MakeZAxis( &result->col2 ); vmathSoaV4MakeFromV3Scalar( &result->col3, translateVec, spu_splats(1.0f) ); } static inline void vmathSoaM4MakeLookAt( VmathSoaMatrix4 *result, const VmathSoaPoint3 *eyePos, const VmathSoaPoint3 *lookAtPos, const VmathSoaVector3 *upVec ) { VmathSoaMatrix4 m4EyeFrame; VmathSoaVector3 v3X, v3Y, v3Z, tmpV3_0, tmpV3_1; VmathSoaVector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; vmathSoaV3Normalize( &v3Y, upVec ); vmathSoaP3Sub( &tmpV3_0, eyePos, lookAtPos ); vmathSoaV3Normalize( &v3Z, &tmpV3_0 ); vmathSoaV3Cross( &tmpV3_1, &v3Y, &v3Z ); vmathSoaV3Normalize( &v3X, &tmpV3_1 ); vmathSoaV3Cross( &v3Y, &v3Z, &v3X ); vmathSoaV4MakeFromV3( &tmpV4_0, &v3X ); vmathSoaV4MakeFromV3( &tmpV4_1, &v3Y ); vmathSoaV4MakeFromV3( &tmpV4_2, &v3Z ); vmathSoaV4MakeFromP3( &tmpV4_3, eyePos ); vmathSoaM4MakeFromCols( &m4EyeFrame, &tmpV4_0, &tmpV4_1, &tmpV4_2, &tmpV4_3 ); vmathSoaM4OrthoInverse( result, &m4EyeFrame ); } static inline void vmathSoaM4MakePerspective( VmathSoaMatrix4 *result, vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ) { vec_float4 f, rangeInv; f = tanf4( spu_sub( spu_splats( _VECTORMATH_PI_OVER_2 ), spu_mul( spu_splats(0.5f), fovyRadians ) ) ); rangeInv = recipf4( spu_sub( zNear, zFar ) ); vmathSoaV4MakeFromElems( &result->col0, divf4( f, aspect ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), f, spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_add( zNear, zFar ), rangeInv ), spu_splats(-1.0f) ); 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) ); } static inline void vmathSoaM4MakeFrustum( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; sum_rl = spu_add( right, left ); sum_tb = spu_add( top, bottom ); sum_nf = spu_add( zNear, zFar ); inv_rl = recipf4( spu_sub( right, left ) ); inv_tb = recipf4( spu_sub( top, bottom ) ); inv_nf = recipf4( spu_sub( zNear, zFar ) ); n2 = spu_add( zNear, zNear ); vmathSoaV4MakeFromElems( &result->col0, spu_mul( n2, inv_rl ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), spu_mul( n2, inv_tb ), spu_splats(0.0f), spu_splats(0.0f) ); 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) ); vmathSoaV4MakeFromElems( &result->col3, spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_mul( n2, inv_nf ), zFar ), spu_splats(0.0f) ); } static inline void vmathSoaM4MakeOrthographic( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; sum_rl = spu_add( right, left ); sum_tb = spu_add( top, bottom ); sum_nf = spu_add( zNear, zFar ); inv_rl = recipf4( spu_sub( right, left ) ); inv_tb = recipf4( spu_sub( top, bottom ) ); inv_nf = recipf4( spu_sub( zNear, zFar ) ); vmathSoaV4MakeFromElems( &result->col0, spu_add( inv_rl, inv_rl ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col1, spu_splats(0.0f), spu_add( inv_tb, inv_tb ), spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV4MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), spu_add( inv_nf, inv_nf ), spu_splats(0.0f) ); 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) ); } static inline void vmathSoaM4Select( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1, vec_uint4 select1 ) { vmathSoaV4Select( &result->col0, &mat0->col0, &mat1->col0, select1 ); vmathSoaV4Select( &result->col1, &mat0->col1, &mat1->col1, select1 ); vmathSoaV4Select( &result->col2, &mat0->col2, &mat1->col2, select1 ); vmathSoaV4Select( &result->col3, &mat0->col3, &mat1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaM4Print( const VmathSoaMatrix4 *mat ) { VmathMatrix4 mat0, mat1, mat2, mat3; vmathSoaM4Get4Aos( mat, &mat0, &mat1, &mat2, &mat3 ); printf("slot 0:\n"); vmathM4Print( &mat0 ); printf("slot 1:\n"); vmathM4Print( &mat1 ); printf("slot 2:\n"); vmathM4Print( &mat2 ); printf("slot 3:\n"); vmathM4Print( &mat3 ); } static inline void vmathSoaM4Prints( const VmathSoaMatrix4 *mat, const char *name ) { printf("%s:\n", name); vmathSoaM4Print( mat ); } #endif static inline void vmathSoaT3Copy( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( &result->col0, &tfrm->col0 ); vmathSoaV3Copy( &result->col1, &tfrm->col1 ); vmathSoaV3Copy( &result->col2, &tfrm->col2 ); vmathSoaV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathSoaT3MakeFromScalar( VmathSoaTransform3 *result, vec_float4 scalar ) { vmathSoaV3MakeFromScalar( &result->col0, scalar ); vmathSoaV3MakeFromScalar( &result->col1, scalar ); vmathSoaV3MakeFromScalar( &result->col2, scalar ); vmathSoaV3MakeFromScalar( &result->col3, scalar ); } static inline void vmathSoaT3MakeFromCols( VmathSoaTransform3 *result, const VmathSoaVector3 *_col0, const VmathSoaVector3 *_col1, const VmathSoaVector3 *_col2, const VmathSoaVector3 *_col3 ) { vmathSoaV3Copy( &result->col0, _col0 ); vmathSoaV3Copy( &result->col1, _col1 ); vmathSoaV3Copy( &result->col2, _col2 ); vmathSoaV3Copy( &result->col3, _col3 ); } static inline void vmathSoaT3MakeFromM3V3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm, const VmathSoaVector3 *translateVec ) { vmathSoaT3SetUpper3x3( result, tfrm ); vmathSoaT3SetTranslation( result, translateVec ); } static inline void vmathSoaT3MakeFromQV3( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec ) { VmathSoaMatrix3 tmpM3_0; vmathSoaM3MakeFromQ( &tmpM3_0, unitQuat ); vmathSoaT3SetUpper3x3( result, &tmpM3_0 ); vmathSoaT3SetTranslation( result, translateVec ); } static inline void vmathSoaT3MakeFromAos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm ) { vmathSoaV3MakeFromAos( &result->col0, &tfrm->col0 ); vmathSoaV3MakeFromAos( &result->col1, &tfrm->col1 ); vmathSoaV3MakeFromAos( &result->col2, &tfrm->col2 ); vmathSoaV3MakeFromAos( &result->col3, &tfrm->col3 ); } static inline void vmathSoaT3MakeFrom4Aos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, const VmathTransform3 *tfrm2, const VmathTransform3 *tfrm3 ) { vmathSoaV3MakeFrom4Aos( &result->col0, &tfrm0->col0, &tfrm1->col0, &tfrm2->col0, &tfrm3->col0 ); vmathSoaV3MakeFrom4Aos( &result->col1, &tfrm0->col1, &tfrm1->col1, &tfrm2->col1, &tfrm3->col1 ); vmathSoaV3MakeFrom4Aos( &result->col2, &tfrm0->col2, &tfrm1->col2, &tfrm2->col2, &tfrm3->col2 ); vmathSoaV3MakeFrom4Aos( &result->col3, &tfrm0->col3, &tfrm1->col3, &tfrm2->col3, &tfrm3->col3 ); } static inline void vmathSoaT3Get4Aos( const VmathSoaTransform3 *tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 ) { vmathSoaV3Get4Aos( &tfrm->col0, &result0->col0, &result1->col0, &result2->col0, &result3->col0 ); vmathSoaV3Get4Aos( &tfrm->col1, &result0->col1, &result1->col1, &result2->col1, &result3->col1 ); vmathSoaV3Get4Aos( &tfrm->col2, &result0->col2, &result1->col2, &result2->col2, &result3->col2 ); vmathSoaV3Get4Aos( &tfrm->col3, &result0->col3, &result1->col3, &result2->col3, &result3->col3 ); } static inline void vmathSoaT3SetCol0( VmathSoaTransform3 *result, const VmathSoaVector3 *_col0 ) { vmathSoaV3Copy( &result->col0, _col0 ); } static inline void vmathSoaT3SetCol1( VmathSoaTransform3 *result, const VmathSoaVector3 *_col1 ) { vmathSoaV3Copy( &result->col1, _col1 ); } static inline void vmathSoaT3SetCol2( VmathSoaTransform3 *result, const VmathSoaVector3 *_col2 ) { vmathSoaV3Copy( &result->col2, _col2 ); } static inline void vmathSoaT3SetCol3( VmathSoaTransform3 *result, const VmathSoaVector3 *_col3 ) { vmathSoaV3Copy( &result->col3, _col3 ); } static inline void vmathSoaT3SetCol( VmathSoaTransform3 *result, int col, const VmathSoaVector3 *vec ) { vmathSoaV3Copy( (&result->col0 + col), vec ); } static inline void vmathSoaT3SetRow( VmathSoaTransform3 *result, int row, const VmathSoaVector4 *vec ) { vmathSoaV3SetElem( &result->col0, row, vmathSoaV4GetElem( vec, 0 ) ); vmathSoaV3SetElem( &result->col1, row, vmathSoaV4GetElem( vec, 1 ) ); vmathSoaV3SetElem( &result->col2, row, vmathSoaV4GetElem( vec, 2 ) ); vmathSoaV3SetElem( &result->col3, row, vmathSoaV4GetElem( vec, 3 ) ); } static inline void vmathSoaT3SetElem( VmathSoaTransform3 *result, int col, int row, vec_float4 val ) { VmathSoaVector3 tmpV3_0; vmathSoaT3GetCol( &tmpV3_0, result, col ); vmathSoaV3SetElem( &tmpV3_0, row, val ); vmathSoaT3SetCol( result, col, &tmpV3_0 ); } static inline vec_float4 vmathSoaT3GetElem( const VmathSoaTransform3 *tfrm, int col, int row ) { VmathSoaVector3 tmpV3_0; vmathSoaT3GetCol( &tmpV3_0, tfrm, col ); return vmathSoaV3GetElem( &tmpV3_0, row ); } static inline void vmathSoaT3GetCol0( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col0 ); } static inline void vmathSoaT3GetCol1( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col1 ); } static inline void vmathSoaT3GetCol2( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col2 ); } static inline void vmathSoaT3GetCol3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col3 ); } static inline void vmathSoaT3GetCol( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, int col ) { vmathSoaV3Copy( result, (&tfrm->col0 + col) ); } static inline void vmathSoaT3GetRow( VmathSoaVector4 *result, const VmathSoaTransform3 *tfrm, int row ) { vmathSoaV4MakeFromElems( result, vmathSoaV3GetElem( &tfrm->col0, row ), vmathSoaV3GetElem( &tfrm->col1, row ), vmathSoaV3GetElem( &tfrm->col2, row ), vmathSoaV3GetElem( &tfrm->col3, row ) ); } static inline void vmathSoaT3Inverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ) { VmathSoaVector3 tmp0, tmp1, tmp2, inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5; vec_float4 detinv; vmathSoaV3Cross( &tmp0, &tfrm->col1, &tfrm->col2 ); vmathSoaV3Cross( &tmp1, &tfrm->col2, &tfrm->col0 ); vmathSoaV3Cross( &tmp2, &tfrm->col0, &tfrm->col1 ); detinv = recipf4( vmathSoaV3Dot( &tfrm->col2, &tmp2 ) ); vmathSoaV3MakeFromElems( &inv0, spu_mul( tmp0.x, detinv ), spu_mul( tmp1.x, detinv ), spu_mul( tmp2.x, detinv ) ); vmathSoaV3MakeFromElems( &inv1, spu_mul( tmp0.y, detinv ), spu_mul( tmp1.y, detinv ), spu_mul( tmp2.y, detinv ) ); vmathSoaV3MakeFromElems( &inv2, spu_mul( tmp0.z, detinv ), spu_mul( tmp1.z, detinv ), spu_mul( tmp2.z, detinv ) ); vmathSoaV3Copy( &result->col0, &inv0 ); vmathSoaV3Copy( &result->col1, &inv1 ); vmathSoaV3Copy( &result->col2, &inv2 ); vmathSoaV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x ); vmathSoaV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y ); vmathSoaV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z ); vmathSoaV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 ); vmathSoaV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 ); vmathSoaV3Neg( &tmpV3_5, &tmpV3_4 ); vmathSoaV3Copy( &result->col3, &tmpV3_5 ); } static inline void vmathSoaT3OrthoInverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ) { VmathSoaVector3 inv0, inv1, inv2, tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3, tmpV3_4, tmpV3_5; vmathSoaV3MakeFromElems( &inv0, tfrm->col0.x, tfrm->col1.x, tfrm->col2.x ); vmathSoaV3MakeFromElems( &inv1, tfrm->col0.y, tfrm->col1.y, tfrm->col2.y ); vmathSoaV3MakeFromElems( &inv2, tfrm->col0.z, tfrm->col1.z, tfrm->col2.z ); vmathSoaV3Copy( &result->col0, &inv0 ); vmathSoaV3Copy( &result->col1, &inv1 ); vmathSoaV3Copy( &result->col2, &inv2 ); vmathSoaV3ScalarMul( &tmpV3_0, &inv0, tfrm->col3.x ); vmathSoaV3ScalarMul( &tmpV3_1, &inv1, tfrm->col3.y ); vmathSoaV3ScalarMul( &tmpV3_2, &inv2, tfrm->col3.z ); vmathSoaV3Add( &tmpV3_3, &tmpV3_1, &tmpV3_2 ); vmathSoaV3Add( &tmpV3_4, &tmpV3_0, &tmpV3_3 ); vmathSoaV3Neg( &tmpV3_5, &tmpV3_4 ); vmathSoaV3Copy( &result->col3, &tmpV3_5 ); } static inline void vmathSoaT3AbsPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3AbsPerElem( &result->col0, &tfrm->col0 ); vmathSoaV3AbsPerElem( &result->col1, &tfrm->col1 ); vmathSoaV3AbsPerElem( &result->col2, &tfrm->col2 ); vmathSoaV3AbsPerElem( &result->col3, &tfrm->col3 ); } static inline void vmathSoaT3MulV3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *vec ) { vec_float4 tmpX, tmpY, tmpZ; 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 ) ); 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 ) ); 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 ) ); vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaT3MulP3( VmathSoaPoint3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaPoint3 *pnt ) { vec_float4 tmpX, tmpY, tmpZ; 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 ); 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 ); 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 ); vmathSoaP3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaT3Mul( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 ) { VmathSoaTransform3 tmpResult; VmathSoaPoint3 tmpP3_0, tmpP3_1; vmathSoaT3MulV3( &tmpResult.col0, tfrm0, &tfrm1->col0 ); vmathSoaT3MulV3( &tmpResult.col1, tfrm0, &tfrm1->col1 ); vmathSoaT3MulV3( &tmpResult.col2, tfrm0, &tfrm1->col2 ); vmathSoaP3MakeFromV3( &tmpP3_0, &tfrm1->col3 ); vmathSoaT3MulP3( &tmpP3_1, tfrm0, &tmpP3_0 ); vmathSoaV3MakeFromP3( &tmpResult.col3, &tmpP3_1 ); vmathSoaT3Copy( result, &tmpResult ); } static inline void vmathSoaT3MulPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 ) { vmathSoaV3MulPerElem( &result->col0, &tfrm0->col0, &tfrm1->col0 ); vmathSoaV3MulPerElem( &result->col1, &tfrm0->col1, &tfrm1->col1 ); vmathSoaV3MulPerElem( &result->col2, &tfrm0->col2, &tfrm1->col2 ); vmathSoaV3MulPerElem( &result->col3, &tfrm0->col3, &tfrm1->col3 ); } static inline void vmathSoaT3MakeIdentity( VmathSoaTransform3 *result ) { vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeZAxis( &result->col2 ); vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) ); } static inline void vmathSoaT3SetUpper3x3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm ) { vmathSoaV3Copy( &result->col0, &tfrm->col0 ); vmathSoaV3Copy( &result->col1, &tfrm->col1 ); vmathSoaV3Copy( &result->col2, &tfrm->col2 ); } static inline void vmathSoaT3GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaM3MakeFromCols( result, &tfrm->col0, &tfrm->col1, &tfrm->col2 ); } static inline void vmathSoaT3SetTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec ) { vmathSoaV3Copy( &result->col3, translateVec ); } static inline void vmathSoaT3GetTranslation( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ) { vmathSoaV3Copy( result, &tfrm->col3 ); } static inline void vmathSoaT3MakeRotationX( VmathSoaTransform3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeFromElems( &result->col1, spu_splats(0.0f), c, s ); vmathSoaV3MakeFromElems( &result->col2, spu_splats(0.0f), negatef4( s ), c ); vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) ); } static inline void vmathSoaT3MakeRotationY( VmathSoaTransform3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeFromElems( &result->col0, c, spu_splats(0.0f), negatef4( s ) ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeFromElems( &result->col2, s, spu_splats(0.0f), c ); vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) ); } static inline void vmathSoaT3MakeRotationZ( VmathSoaTransform3 *result, vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); vmathSoaV3MakeFromElems( &result->col0, c, s, spu_splats(0.0f) ); vmathSoaV3MakeFromElems( &result->col1, negatef4( s ), c, spu_splats(0.0f) ); vmathSoaV3MakeZAxis( &result->col2 ); vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) ); } static inline void vmathSoaT3MakeRotationZYX( VmathSoaTransform3 *result, const VmathSoaVector3 *radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ->x, &sX, &cX ); sincosf4( radiansXYZ->y, &sY, &cY ); sincosf4( radiansXYZ->z, &sZ, &cZ ); tmp0 = spu_mul( cZ, sY ); tmp1 = spu_mul( sZ, sY ); vmathSoaV3MakeFromElems( &result->col0, spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ) ); 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 ) ); 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 ) ); vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) ); } static inline void vmathSoaT3MakeRotationAxis( VmathSoaTransform3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ) { VmathSoaMatrix3 tmpM3_0; VmathSoaVector3 tmpV3_0; vmathSoaM3MakeRotationAxis( &tmpM3_0, radians, unitVec ); vmathSoaV3MakeFromScalar( &tmpV3_0, spu_splats(0.0f) ); vmathSoaT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathSoaT3MakeRotationQ( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat ) { VmathSoaMatrix3 tmpM3_0; VmathSoaVector3 tmpV3_0; vmathSoaM3MakeFromQ( &tmpM3_0, unitQuat ); vmathSoaV3MakeFromScalar( &tmpV3_0, spu_splats(0.0f) ); vmathSoaT3MakeFromM3V3( result, &tmpM3_0, &tmpV3_0 ); } static inline void vmathSoaT3MakeScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec ) { vmathSoaV3MakeFromElems( &result->col0, scaleVec->x, spu_splats(0.0f), spu_splats(0.0f) ); vmathSoaV3MakeFromElems( &result->col1, spu_splats(0.0f), scaleVec->y, spu_splats(0.0f) ); vmathSoaV3MakeFromElems( &result->col2, spu_splats(0.0f), spu_splats(0.0f), scaleVec->z ); vmathSoaV3MakeFromScalar( &result->col3, spu_splats(0.0f) ); } static inline void vmathSoaT3AppendScale( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *scaleVec ) { vmathSoaV3ScalarMul( &result->col0, &tfrm->col0, vmathSoaV3GetX( scaleVec ) ); vmathSoaV3ScalarMul( &result->col1, &tfrm->col1, vmathSoaV3GetY( scaleVec ) ); vmathSoaV3ScalarMul( &result->col2, &tfrm->col2, vmathSoaV3GetZ( scaleVec ) ); vmathSoaV3Copy( &result->col3, &tfrm->col3 ); } static inline void vmathSoaT3PrependScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaTransform3 *tfrm ) { vmathSoaV3MulPerElem( &result->col0, &tfrm->col0, scaleVec ); vmathSoaV3MulPerElem( &result->col1, &tfrm->col1, scaleVec ); vmathSoaV3MulPerElem( &result->col2, &tfrm->col2, scaleVec ); vmathSoaV3MulPerElem( &result->col3, &tfrm->col3, scaleVec ); } static inline void vmathSoaT3MakeTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec ) { vmathSoaV3MakeXAxis( &result->col0 ); vmathSoaV3MakeYAxis( &result->col1 ); vmathSoaV3MakeZAxis( &result->col2 ); vmathSoaV3Copy( &result->col3, translateVec ); } static inline void vmathSoaT3Select( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1, vec_uint4 select1 ) { vmathSoaV3Select( &result->col0, &tfrm0->col0, &tfrm1->col0, select1 ); vmathSoaV3Select( &result->col1, &tfrm0->col1, &tfrm1->col1, select1 ); vmathSoaV3Select( &result->col2, &tfrm0->col2, &tfrm1->col2, select1 ); vmathSoaV3Select( &result->col3, &tfrm0->col3, &tfrm1->col3, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaT3Print( const VmathSoaTransform3 *tfrm ) { VmathTransform3 mat0, mat1, mat2, mat3; vmathSoaT3Get4Aos( tfrm, &mat0, &mat1, &mat2, &mat3 ); printf("slot 0:\n"); vmathT3Print( &mat0 ); printf("slot 1:\n"); vmathT3Print( &mat1 ); printf("slot 2:\n"); vmathT3Print( &mat2 ); printf("slot 3:\n"); vmathT3Print( &mat3 ); } static inline void vmathSoaT3Prints( const VmathSoaTransform3 *tfrm, const char *name ) { printf("%s:\n", name); vmathSoaT3Print( tfrm ); } #endif static inline void vmathSoaQMakeFromM3( VmathSoaQuat *result, const VmathSoaMatrix3 *tfrm ) { vec_float4 trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; vec_uint4 negTrace, ZgtX, ZgtY, YgtX; vec_uint4 largestXorY, largestYorZ, largestZorX; xx = tfrm->col0.x; yx = tfrm->col0.y; zx = tfrm->col0.z; xy = tfrm->col1.x; yy = tfrm->col1.y; zy = tfrm->col1.z; xz = tfrm->col2.x; yz = tfrm->col2.y; zz = tfrm->col2.z; trace = spu_add( spu_add( xx, yy ), zz ); negTrace = spu_cmpgt( spu_splats(0.0f), trace ); ZgtX = spu_cmpgt( zz, xx ); ZgtY = spu_cmpgt( zz, yy ); YgtX = spu_cmpgt( yy, xx ); largestXorY = spu_and( negTrace, spu_nand( ZgtX, ZgtY ) ); largestYorZ = spu_and( negTrace, spu_or( YgtX, ZgtX ) ); largestZorX = spu_and( negTrace, spu_orc( ZgtY, YgtX ) ); zz = spu_sel( zz, negatef4(zz), largestXorY ); xy = spu_sel( xy, negatef4(xy), largestXorY ); xx = spu_sel( xx, negatef4(xx), largestYorZ ); yz = spu_sel( yz, negatef4(yz), largestYorZ ); yy = spu_sel( yy, negatef4(yy), largestZorX ); zx = spu_sel( zx, negatef4(zx), largestZorX ); radicand = spu_add( spu_add( spu_add( xx, yy ), zz ), spu_splats(1.0f) ); scale = spu_mul( spu_splats(0.5f), rsqrtf4( radicand ) ); tmpx = spu_mul( spu_sub( zy, yz ), scale ); tmpy = spu_mul( spu_sub( xz, zx ), scale ); tmpz = spu_mul( spu_sub( yx, xy ), scale ); tmpw = spu_mul( radicand, scale ); qx = tmpx; qy = tmpy; qz = tmpz; qw = tmpw; qx = spu_sel( qx, tmpw, largestXorY ); qy = spu_sel( qy, tmpz, largestXorY ); qz = spu_sel( qz, tmpy, largestXorY ); qw = spu_sel( qw, tmpx, largestXorY ); tmpx = qx; tmpz = qz; qx = spu_sel( qx, qy, largestYorZ ); qy = spu_sel( qy, tmpx, largestYorZ ); qz = spu_sel( qz, qw, largestYorZ ); qw = spu_sel( qw, tmpz, largestYorZ ); result->x = qx; result->y = qy; result->z = qz; result->w = qw; } static inline void vmathSoaV3Outer( VmathSoaMatrix3 *result, const VmathSoaVector3 *tfrm0, const VmathSoaVector3 *tfrm1 ) { vmathSoaV3ScalarMul( &result->col0, tfrm0, vmathSoaV3GetX( tfrm1 ) ); vmathSoaV3ScalarMul( &result->col1, tfrm0, vmathSoaV3GetY( tfrm1 ) ); vmathSoaV3ScalarMul( &result->col2, tfrm0, vmathSoaV3GetZ( tfrm1 ) ); } static inline void vmathSoaV4Outer( VmathSoaMatrix4 *result, const VmathSoaVector4 *tfrm0, const VmathSoaVector4 *tfrm1 ) { vmathSoaV4ScalarMul( &result->col0, tfrm0, vmathSoaV4GetX( tfrm1 ) ); vmathSoaV4ScalarMul( &result->col1, tfrm0, vmathSoaV4GetY( tfrm1 ) ); vmathSoaV4ScalarMul( &result->col2, tfrm0, vmathSoaV4GetZ( tfrm1 ) ); vmathSoaV4ScalarMul( &result->col3, tfrm0, vmathSoaV4GetW( tfrm1 ) ); } static inline void vmathSoaV3RowMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat ) { vec_float4 tmpX, tmpY, tmpZ; 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 ) ); 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 ) ); 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 ) ); vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaV3CrossMatrix( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec ) { vmathSoaV3MakeFromElems( &result->col0, spu_splats(0.0f), vec->z, negatef4( vec->y ) ); vmathSoaV3MakeFromElems( &result->col1, negatef4( vec->z ), spu_splats(0.0f), vec->x ); vmathSoaV3MakeFromElems( &result->col2, vec->y, negatef4( vec->x ), spu_splats(0.0f) ); } static inline void vmathSoaV3CrossMatrixMul( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat ) { VmathSoaVector3 tmpV3_0, tmpV3_1, tmpV3_2; vmathSoaV3Cross( &tmpV3_0, vec, &mat->col0 ); vmathSoaV3Cross( &tmpV3_1, vec, &mat->col1 ); vmathSoaV3Cross( &tmpV3_2, vec, &mat->col2 ); vmathSoaM3MakeFromCols( result, &tmpV3_0, &tmpV3_1, &tmpV3_2 ); } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/mat_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_SOA_V_C_H #define _VECTORMATH_MAT_SOA_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants */ #define _VECTORMATH_PI_OVER_2 1.570796327f /*----------------------------------------------------------------------------- * Definitions */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromScalar_V( vec_float4 scalar ) { VmathSoaMatrix3 result; vmathSoaM3MakeFromScalar(&result, scalar); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeFromQ_V( VmathSoaQuat unitQuat ) { VmathSoaMatrix3 result; vmathSoaM3MakeFromQ(&result, &unitQuat); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeFromCols_V( VmathSoaVector3 _col0, VmathSoaVector3 _col1, VmathSoaVector3 _col2 ) { VmathSoaMatrix3 result; vmathSoaM3MakeFromCols(&result, &_col0, &_col1, &_col2); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeFromAos_V( VmathMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3MakeFromAos(&result, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeFrom4Aos_V( VmathMatrix3 mat0, VmathMatrix3 mat1, VmathMatrix3 mat2, VmathMatrix3 mat3 ) { VmathSoaMatrix3 result; vmathSoaM3MakeFrom4Aos(&result, &mat0, &mat1, &mat2, &mat3); return result; } static inline void vmathSoaM3Get4Aos_V( VmathSoaMatrix3 mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 ) { vmathSoaM3Get4Aos(&mat, result0, result1, result2, result3); } static inline void vmathSoaM3SetCol0_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col0 ) { vmathSoaM3SetCol0(result, &_col0); } static inline void vmathSoaM3SetCol1_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col1 ) { vmathSoaM3SetCol1(result, &_col1); } static inline void vmathSoaM3SetCol2_V( VmathSoaMatrix3 *result, VmathSoaVector3 _col2 ) { vmathSoaM3SetCol2(result, &_col2); } static inline void vmathSoaM3SetCol_V( VmathSoaMatrix3 *result, int col, VmathSoaVector3 vec ) { vmathSoaM3SetCol(result, col, &vec); } static inline void vmathSoaM3SetRow_V( VmathSoaMatrix3 *result, int row, VmathSoaVector3 vec ) { vmathSoaM3SetRow(result, row, &vec); } static inline void vmathSoaM3SetElem_V( VmathSoaMatrix3 *result, int col, int row, vec_float4 val ) { vmathSoaM3SetElem(result, col, row, val); } static inline vec_float4 vmathSoaM3GetElem_V( VmathSoaMatrix3 mat, int col, int row ) { return vmathSoaM3GetElem(&mat, col, row); } static inline VmathSoaVector3 vmathSoaM3GetCol0_V( VmathSoaMatrix3 mat ) { VmathSoaVector3 result; vmathSoaM3GetCol0(&result, &mat); return result; } static inline VmathSoaVector3 vmathSoaM3GetCol1_V( VmathSoaMatrix3 mat ) { VmathSoaVector3 result; vmathSoaM3GetCol1(&result, &mat); return result; } static inline VmathSoaVector3 vmathSoaM3GetCol2_V( VmathSoaMatrix3 mat ) { VmathSoaVector3 result; vmathSoaM3GetCol2(&result, &mat); return result; } static inline VmathSoaVector3 vmathSoaM3GetCol_V( VmathSoaMatrix3 mat, int col ) { VmathSoaVector3 result; vmathSoaM3GetCol(&result, &mat, col); return result; } static inline VmathSoaVector3 vmathSoaM3GetRow_V( VmathSoaMatrix3 mat, int row ) { VmathSoaVector3 result; vmathSoaM3GetRow(&result, &mat, row); return result; } static inline VmathSoaMatrix3 vmathSoaM3Transpose_V( VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3Transpose(&result, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3Inverse_V( VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3Inverse(&result, &mat); return result; } static inline vec_float4 vmathSoaM3Determinant_V( VmathSoaMatrix3 mat ) { return vmathSoaM3Determinant(&mat); } static inline VmathSoaMatrix3 vmathSoaM3Add_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ) { VmathSoaMatrix3 result; vmathSoaM3Add(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix3 vmathSoaM3Sub_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ) { VmathSoaMatrix3 result; vmathSoaM3Sub(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix3 vmathSoaM3Neg_V( VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3Neg(&result, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3AbsPerElem_V( VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3AbsPerElem(&result, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3ScalarMul_V( VmathSoaMatrix3 mat, vec_float4 scalar ) { VmathSoaMatrix3 result; vmathSoaM3ScalarMul(&result, &mat, scalar); return result; } static inline VmathSoaVector3 vmathSoaM3MulV3_V( VmathSoaMatrix3 mat, VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaM3MulV3(&result, &mat, &vec); return result; } static inline VmathSoaMatrix3 vmathSoaM3Mul_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ) { VmathSoaMatrix3 result; vmathSoaM3Mul(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix3 vmathSoaM3MulPerElem_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ) { VmathSoaMatrix3 result; vmathSoaM3MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeIdentity_V( ) { VmathSoaMatrix3 result; vmathSoaM3MakeIdentity(&result); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationX_V( vec_float4 radians ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationX(&result, radians); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationY_V( vec_float4 radians ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationY(&result, radians); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationZ_V( vec_float4 radians ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationZ(&result, radians); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeRotationQ_V( VmathSoaQuat unitQuat ) { VmathSoaMatrix3 result; vmathSoaM3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathSoaMatrix3 vmathSoaM3MakeScale_V( VmathSoaVector3 scaleVec ) { VmathSoaMatrix3 result; vmathSoaM3MakeScale(&result, &scaleVec); return result; } static inline VmathSoaMatrix3 vmathSoaM3AppendScale_V( VmathSoaMatrix3 mat, VmathSoaVector3 scaleVec ) { VmathSoaMatrix3 result; vmathSoaM3AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathSoaMatrix3 vmathSoaM3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaM3PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaM3Select_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1, vec_uint4 select1 ) { VmathSoaMatrix3 result; vmathSoaM3Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaM3Print_V( VmathSoaMatrix3 mat ) { vmathSoaM3Print(&mat); } static inline void vmathSoaM3Prints_V( VmathSoaMatrix3 mat, const char *name ) { vmathSoaM3Prints(&mat, name); } #endif static inline VmathSoaMatrix4 vmathSoaM4MakeFromScalar_V( vec_float4 scalar ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromScalar(&result, scalar); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromT3_V( VmathSoaTransform3 mat ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromT3(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromCols_V( VmathSoaVector4 _col0, VmathSoaVector4 _col1, VmathSoaVector4 _col2, VmathSoaVector4 _col3 ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromM3V3_V( VmathSoaMatrix3 mat, VmathSoaVector3 translateVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromM3V3(&result, &mat, &translateVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFromAos_V( VmathMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4MakeFromAos(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFrom4Aos_V( VmathMatrix4 mat0, VmathMatrix4 mat1, VmathMatrix4 mat2, VmathMatrix4 mat3 ) { VmathSoaMatrix4 result; vmathSoaM4MakeFrom4Aos(&result, &mat0, &mat1, &mat2, &mat3); return result; } static inline void vmathSoaM4Get4Aos_V( VmathSoaMatrix4 mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 ) { vmathSoaM4Get4Aos(&mat, result0, result1, result2, result3); } static inline void vmathSoaM4SetCol0_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col0 ) { vmathSoaM4SetCol0(result, &_col0); } static inline void vmathSoaM4SetCol1_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col1 ) { vmathSoaM4SetCol1(result, &_col1); } static inline void vmathSoaM4SetCol2_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col2 ) { vmathSoaM4SetCol2(result, &_col2); } static inline void vmathSoaM4SetCol3_V( VmathSoaMatrix4 *result, VmathSoaVector4 _col3 ) { vmathSoaM4SetCol3(result, &_col3); } static inline void vmathSoaM4SetCol_V( VmathSoaMatrix4 *result, int col, VmathSoaVector4 vec ) { vmathSoaM4SetCol(result, col, &vec); } static inline void vmathSoaM4SetRow_V( VmathSoaMatrix4 *result, int row, VmathSoaVector4 vec ) { vmathSoaM4SetRow(result, row, &vec); } static inline void vmathSoaM4SetElem_V( VmathSoaMatrix4 *result, int col, int row, vec_float4 val ) { vmathSoaM4SetElem(result, col, row, val); } static inline vec_float4 vmathSoaM4GetElem_V( VmathSoaMatrix4 mat, int col, int row ) { return vmathSoaM4GetElem(&mat, col, row); } static inline VmathSoaVector4 vmathSoaM4GetCol0_V( VmathSoaMatrix4 mat ) { VmathSoaVector4 result; vmathSoaM4GetCol0(&result, &mat); return result; } static inline VmathSoaVector4 vmathSoaM4GetCol1_V( VmathSoaMatrix4 mat ) { VmathSoaVector4 result; vmathSoaM4GetCol1(&result, &mat); return result; } static inline VmathSoaVector4 vmathSoaM4GetCol2_V( VmathSoaMatrix4 mat ) { VmathSoaVector4 result; vmathSoaM4GetCol2(&result, &mat); return result; } static inline VmathSoaVector4 vmathSoaM4GetCol3_V( VmathSoaMatrix4 mat ) { VmathSoaVector4 result; vmathSoaM4GetCol3(&result, &mat); return result; } static inline VmathSoaVector4 vmathSoaM4GetCol_V( VmathSoaMatrix4 mat, int col ) { VmathSoaVector4 result; vmathSoaM4GetCol(&result, &mat, col); return result; } static inline VmathSoaVector4 vmathSoaM4GetRow_V( VmathSoaMatrix4 mat, int row ) { VmathSoaVector4 result; vmathSoaM4GetRow(&result, &mat, row); return result; } static inline VmathSoaMatrix4 vmathSoaM4Transpose_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4Transpose(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4Inverse_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4Inverse(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4AffineInverse_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4AffineInverse(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4OrthoInverse_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4OrthoInverse(&result, &mat); return result; } static inline vec_float4 vmathSoaM4Determinant_V( VmathSoaMatrix4 mat ) { return vmathSoaM4Determinant(&mat); } static inline VmathSoaMatrix4 vmathSoaM4Add_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ) { VmathSoaMatrix4 result; vmathSoaM4Add(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix4 vmathSoaM4Sub_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ) { VmathSoaMatrix4 result; vmathSoaM4Sub(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix4 vmathSoaM4Neg_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4Neg(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4AbsPerElem_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4AbsPerElem(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4ScalarMul_V( VmathSoaMatrix4 mat, vec_float4 scalar ) { VmathSoaMatrix4 result; vmathSoaM4ScalarMul(&result, &mat, scalar); return result; } static inline VmathSoaVector4 vmathSoaM4MulV4_V( VmathSoaMatrix4 mat, VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaM4MulV4(&result, &mat, &vec); return result; } static inline VmathSoaVector4 vmathSoaM4MulV3_V( VmathSoaMatrix4 mat, VmathSoaVector3 vec ) { VmathSoaVector4 result; vmathSoaM4MulV3(&result, &mat, &vec); return result; } static inline VmathSoaVector4 vmathSoaM4MulP3_V( VmathSoaMatrix4 mat, VmathSoaPoint3 pnt ) { VmathSoaVector4 result; vmathSoaM4MulP3(&result, &mat, &pnt); return result; } static inline VmathSoaMatrix4 vmathSoaM4Mul_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ) { VmathSoaMatrix4 result; vmathSoaM4Mul(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix4 vmathSoaM4MulT3_V( VmathSoaMatrix4 mat, VmathSoaTransform3 tfrm1 ) { VmathSoaMatrix4 result; vmathSoaM4MulT3(&result, &mat, &tfrm1); return result; } static inline VmathSoaMatrix4 vmathSoaM4MulPerElem_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ) { VmathSoaMatrix4 result; vmathSoaM4MulPerElem(&result, &mat0, &mat1); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeIdentity_V( ) { VmathSoaMatrix4 result; vmathSoaM4MakeIdentity(&result); return result; } static inline void vmathSoaM4SetUpper3x3_V( VmathSoaMatrix4 *result, VmathSoaMatrix3 mat3 ) { vmathSoaM4SetUpper3x3(result, &mat3); } static inline VmathSoaMatrix3 vmathSoaM4GetUpper3x3_V( VmathSoaMatrix4 mat ) { VmathSoaMatrix3 result; vmathSoaM4GetUpper3x3(&result, &mat); return result; } static inline void vmathSoaM4SetTranslation_V( VmathSoaMatrix4 *result, VmathSoaVector3 translateVec ) { vmathSoaM4SetTranslation(result, &translateVec); } static inline VmathSoaVector3 vmathSoaM4GetTranslation_V( VmathSoaMatrix4 mat ) { VmathSoaVector3 result; vmathSoaM4GetTranslation(&result, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationX_V( vec_float4 radians ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationX(&result, radians); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationY_V( vec_float4 radians ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationY(&result, radians); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationZ_V( vec_float4 radians ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationZ(&result, radians); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeRotationQ_V( VmathSoaQuat unitQuat ) { VmathSoaMatrix4 result; vmathSoaM4MakeRotationQ(&result, &unitQuat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeScale_V( VmathSoaVector3 scaleVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeScale(&result, &scaleVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4AppendScale_V( VmathSoaMatrix4 mat, VmathSoaVector3 scaleVec ) { VmathSoaMatrix4 result; vmathSoaM4AppendScale(&result, &mat, &scaleVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix4 mat ) { VmathSoaMatrix4 result; vmathSoaM4PrependScale(&result, &scaleVec, &mat); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeTranslation_V( VmathSoaVector3 translateVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeTranslation(&result, &translateVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeLookAt_V( VmathSoaPoint3 eyePos, VmathSoaPoint3 lookAtPos, VmathSoaVector3 upVec ) { VmathSoaMatrix4 result; vmathSoaM4MakeLookAt(&result, &eyePos, &lookAtPos, &upVec); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakePerspective_V( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ) { VmathSoaMatrix4 result; vmathSoaM4MakePerspective(&result, fovyRadians, aspect, zNear, zFar); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeFrustum_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { VmathSoaMatrix4 result; vmathSoaM4MakeFrustum(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathSoaMatrix4 vmathSoaM4MakeOrthographic_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { VmathSoaMatrix4 result; vmathSoaM4MakeOrthographic(&result, left, right, bottom, top, zNear, zFar); return result; } static inline VmathSoaMatrix4 vmathSoaM4Select_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1, vec_uint4 select1 ) { VmathSoaMatrix4 result; vmathSoaM4Select(&result, &mat0, &mat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaM4Print_V( VmathSoaMatrix4 mat ) { vmathSoaM4Print(&mat); } static inline void vmathSoaM4Prints_V( VmathSoaMatrix4 mat, const char *name ) { vmathSoaM4Prints(&mat, name); } #endif static inline VmathSoaTransform3 vmathSoaT3MakeFromScalar_V( vec_float4 scalar ) { VmathSoaTransform3 result; vmathSoaT3MakeFromScalar(&result, scalar); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFromCols_V( VmathSoaVector3 _col0, VmathSoaVector3 _col1, VmathSoaVector3 _col2, VmathSoaVector3 _col3 ) { VmathSoaTransform3 result; vmathSoaT3MakeFromCols(&result, &_col0, &_col1, &_col2, &_col3); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFromM3V3_V( VmathSoaMatrix3 tfrm, VmathSoaVector3 translateVec ) { VmathSoaTransform3 result; vmathSoaT3MakeFromM3V3(&result, &tfrm, &translateVec); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec ) { VmathSoaTransform3 result; vmathSoaT3MakeFromQV3(&result, &unitQuat, &translateVec); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFromAos_V( VmathTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3MakeFromAos(&result, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeFrom4Aos_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, VmathTransform3 tfrm2, VmathTransform3 tfrm3 ) { VmathSoaTransform3 result; vmathSoaT3MakeFrom4Aos(&result, &tfrm0, &tfrm1, &tfrm2, &tfrm3); return result; } static inline void vmathSoaT3Get4Aos_V( VmathSoaTransform3 tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 ) { vmathSoaT3Get4Aos(&tfrm, result0, result1, result2, result3); } static inline void vmathSoaT3SetCol0_V( VmathSoaTransform3 *result, VmathSoaVector3 _col0 ) { vmathSoaT3SetCol0(result, &_col0); } static inline void vmathSoaT3SetCol1_V( VmathSoaTransform3 *result, VmathSoaVector3 _col1 ) { vmathSoaT3SetCol1(result, &_col1); } static inline void vmathSoaT3SetCol2_V( VmathSoaTransform3 *result, VmathSoaVector3 _col2 ) { vmathSoaT3SetCol2(result, &_col2); } static inline void vmathSoaT3SetCol3_V( VmathSoaTransform3 *result, VmathSoaVector3 _col3 ) { vmathSoaT3SetCol3(result, &_col3); } static inline void vmathSoaT3SetCol_V( VmathSoaTransform3 *result, int col, VmathSoaVector3 vec ) { vmathSoaT3SetCol(result, col, &vec); } static inline void vmathSoaT3SetRow_V( VmathSoaTransform3 *result, int row, VmathSoaVector4 vec ) { vmathSoaT3SetRow(result, row, &vec); } static inline void vmathSoaT3SetElem_V( VmathSoaTransform3 *result, int col, int row, vec_float4 val ) { vmathSoaT3SetElem(result, col, row, val); } static inline vec_float4 vmathSoaT3GetElem_V( VmathSoaTransform3 tfrm, int col, int row ) { return vmathSoaT3GetElem(&tfrm, col, row); } static inline VmathSoaVector3 vmathSoaT3GetCol0_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetCol0(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3GetCol1_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetCol1(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3GetCol2_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetCol2(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3GetCol3_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetCol3(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3GetCol_V( VmathSoaTransform3 tfrm, int col ) { VmathSoaVector3 result; vmathSoaT3GetCol(&result, &tfrm, col); return result; } static inline VmathSoaVector4 vmathSoaT3GetRow_V( VmathSoaTransform3 tfrm, int row ) { VmathSoaVector4 result; vmathSoaT3GetRow(&result, &tfrm, row); return result; } static inline VmathSoaTransform3 vmathSoaT3Inverse_V( VmathSoaTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3Inverse(&result, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3OrthoInverse_V( VmathSoaTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3OrthoInverse(&result, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3AbsPerElem_V( VmathSoaTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3AbsPerElem(&result, &tfrm); return result; } static inline VmathSoaVector3 vmathSoaT3MulV3_V( VmathSoaTransform3 tfrm, VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaT3MulV3(&result, &tfrm, &vec); return result; } static inline VmathSoaPoint3 vmathSoaT3MulP3_V( VmathSoaTransform3 tfrm, VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaT3MulP3(&result, &tfrm, &pnt); return result; } static inline VmathSoaTransform3 vmathSoaT3Mul_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 ) { VmathSoaTransform3 result; vmathSoaT3Mul(&result, &tfrm0, &tfrm1); return result; } static inline VmathSoaTransform3 vmathSoaT3MulPerElem_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 ) { VmathSoaTransform3 result; vmathSoaT3MulPerElem(&result, &tfrm0, &tfrm1); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeIdentity_V( ) { VmathSoaTransform3 result; vmathSoaT3MakeIdentity(&result); return result; } static inline void vmathSoaT3SetUpper3x3_V( VmathSoaTransform3 *result, VmathSoaMatrix3 tfrm ) { vmathSoaT3SetUpper3x3(result, &tfrm); } static inline VmathSoaMatrix3 vmathSoaT3GetUpper3x3_V( VmathSoaTransform3 tfrm ) { VmathSoaMatrix3 result; vmathSoaT3GetUpper3x3(&result, &tfrm); return result; } static inline void vmathSoaT3SetTranslation_V( VmathSoaTransform3 *result, VmathSoaVector3 translateVec ) { vmathSoaT3SetTranslation(result, &translateVec); } static inline VmathSoaVector3 vmathSoaT3GetTranslation_V( VmathSoaTransform3 tfrm ) { VmathSoaVector3 result; vmathSoaT3GetTranslation(&result, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationX_V( vec_float4 radians ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationX(&result, radians); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationY_V( vec_float4 radians ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationY(&result, radians); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationZ_V( vec_float4 radians ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationZ(&result, radians); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationZYX(&result, &radiansXYZ); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeRotationQ_V( VmathSoaQuat unitQuat ) { VmathSoaTransform3 result; vmathSoaT3MakeRotationQ(&result, &unitQuat); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeScale_V( VmathSoaVector3 scaleVec ) { VmathSoaTransform3 result; vmathSoaT3MakeScale(&result, &scaleVec); return result; } static inline VmathSoaTransform3 vmathSoaT3AppendScale_V( VmathSoaTransform3 tfrm, VmathSoaVector3 scaleVec ) { VmathSoaTransform3 result; vmathSoaT3AppendScale(&result, &tfrm, &scaleVec); return result; } static inline VmathSoaTransform3 vmathSoaT3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaTransform3 tfrm ) { VmathSoaTransform3 result; vmathSoaT3PrependScale(&result, &scaleVec, &tfrm); return result; } static inline VmathSoaTransform3 vmathSoaT3MakeTranslation_V( VmathSoaVector3 translateVec ) { VmathSoaTransform3 result; vmathSoaT3MakeTranslation(&result, &translateVec); return result; } static inline VmathSoaTransform3 vmathSoaT3Select_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1, vec_uint4 select1 ) { VmathSoaTransform3 result; vmathSoaT3Select(&result, &tfrm0, &tfrm1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaT3Print_V( VmathSoaTransform3 tfrm ) { vmathSoaT3Print(&tfrm); } static inline void vmathSoaT3Prints_V( VmathSoaTransform3 tfrm, const char *name ) { vmathSoaT3Prints(&tfrm, name); } #endif static inline VmathSoaQuat vmathSoaQMakeFromM3_V( VmathSoaMatrix3 tfrm ) { VmathSoaQuat result; vmathSoaQMakeFromM3(&result, &tfrm); return result; } static inline VmathSoaMatrix3 vmathSoaV3Outer_V( VmathSoaVector3 tfrm0, VmathSoaVector3 tfrm1 ) { VmathSoaMatrix3 result; vmathSoaV3Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathSoaMatrix4 vmathSoaV4Outer_V( VmathSoaVector4 tfrm0, VmathSoaVector4 tfrm1 ) { VmathSoaMatrix4 result; vmathSoaV4Outer(&result, &tfrm0, &tfrm1); return result; } static inline VmathSoaVector3 vmathSoaV3RowMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat ) { VmathSoaVector3 result; vmathSoaV3RowMul(&result, &vec, &mat); return result; } static inline VmathSoaMatrix3 vmathSoaV3CrossMatrix_V( VmathSoaVector3 vec ) { VmathSoaMatrix3 result; vmathSoaV3CrossMatrix(&result, &vec); return result; } static inline VmathSoaMatrix3 vmathSoaV3CrossMatrixMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat ) { VmathSoaMatrix3 result; vmathSoaV3CrossMatrixMul(&result, &vec, &mat); return result; } #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/quat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_C_H #define _VECTORMATH_QUAT_AOS_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat ) { result->vec128 = quat->vec128; } static inline void vmathQMakeFromElems( VmathQuat *result, float _x, float _y, float _z, float _w ) { result->vec128 = (vec_float4){ _x, _y, _z, _w }; } static inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float _w ) { result->vec128 = spu_shuffle( xyz->vec128, spu_promote( _w, 0 ), _VECTORMATH_SHUF_XYZA ); } static inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec ) { result->vec128 = vec->vec128; } static inline void vmathQMakeFromScalar( VmathQuat *result, float scalar ) { result->vec128 = spu_splats( scalar ); } static inline void vmathQMakeFrom128( VmathQuat *result, vec_float4 vf4 ) { result->vec128 = vf4; } static inline void vmathQMakeIdentity( VmathQuat *result ) { result->vec128 = _VECTORMATH_UNIT_0001; } static inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 ) { VmathQuat tmpQ_0, tmpQ_1; vmathQSub( &tmpQ_0, quat1, quat0 ); vmathQScalarMul( &tmpQ_1, &tmpQ_0, t ); vmathQAdd( result, quat0, &tmpQ_1 ); } static inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 ) { VmathQuat start; vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); cosAngle = _vmathVfDot4( unitQuat0->vec128, unitQuat1->vec128 ); cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(0.0f), cosAngle ); cosAngle = spu_sel( cosAngle, negatef4( cosAngle ), selectMask ); start.vec128 = spu_sel( unitQuat0->vec128, negatef4( unitQuat0->vec128 ), selectMask ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = spu_splats(t); oneMinusT = spu_sub( spu_splats(1.0f), tttt ); angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) ); angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) ); angles = spu_mul( angles, angle ); sines = sinf4( angles ); scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) ); scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask ); scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask ); result->vec128 = spu_madd( start.vec128, scale0, spu_mul( unitQuat1->vec128, scale1 ) ); } static inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 ) { VmathQuat tmp0, tmp1; vmathQSlerp( &tmp0, t, unitQuat0, unitQuat3 ); vmathQSlerp( &tmp1, t, unitQuat1, unitQuat2 ); vmathQSlerp( result, ( ( 2.0f * t ) * ( 1.0f - t ) ), &tmp0, &tmp1 ); } static inline vec_float4 vmathQGet128( const VmathQuat *quat ) { return quat->vec128; } static inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec ) { result->vec128 = spu_sel( vec->vec128, result->vec128, (vec_uint4)spu_maskb(0x000f) ); } static inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat ) { result->vec128 = quat->vec128; } static inline void vmathQSetX( VmathQuat *result, float _x ) { result->vec128 = spu_insert( _x, result->vec128, 0 ); } static inline float vmathQGetX( const VmathQuat *quat ) { return spu_extract( quat->vec128, 0 ); } static inline void vmathQSetY( VmathQuat *result, float _y ) { result->vec128 = spu_insert( _y, result->vec128, 1 ); } static inline float vmathQGetY( const VmathQuat *quat ) { return spu_extract( quat->vec128, 1 ); } static inline void vmathQSetZ( VmathQuat *result, float _z ) { result->vec128 = spu_insert( _z, result->vec128, 2 ); } static inline float vmathQGetZ( const VmathQuat *quat ) { return spu_extract( quat->vec128, 2 ); } static inline void vmathQSetW( VmathQuat *result, float _w ) { result->vec128 = spu_insert( _w, result->vec128, 3 ); } static inline float vmathQGetW( const VmathQuat *quat ) { return spu_extract( quat->vec128, 3 ); } static inline void vmathQSetElem( VmathQuat *result, int idx, float value ) { result->vec128 = spu_insert( value, result->vec128, idx ); } static inline float vmathQGetElem( const VmathQuat *quat, int idx ) { return spu_extract( quat->vec128, idx ); } static inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { result->vec128 = spu_add( quat0->vec128, quat1->vec128 ); } static inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { result->vec128 = spu_sub( quat0->vec128, quat1->vec128 ); } static inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar ) { result->vec128 = spu_mul( quat->vec128, spu_splats(scalar) ); } static inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar ) { result->vec128 = divf4( quat->vec128, spu_splats(scalar) ); } static inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat ) { result->vec128 = negatef4( quat->vec128 ); } static inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 ) { return spu_extract( _vmathVfDot4( quat0->vec128, quat1->vec128 ), 0 ); } static inline float vmathQNorm( const VmathQuat *quat ) { return spu_extract( _vmathVfDot4( quat->vec128, quat->vec128 ), 0 ); } static inline float vmathQLength( const VmathQuat *quat ) { return sqrtf( vmathQNorm( quat ) ); } static inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat ) { vec_float4 dot = _vmathVfDot4( quat->vec128, quat->vec128 ); result->vec128 = spu_mul( quat->vec128, rsqrtf4( dot ) ); } static inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ) { VmathVector3 crossVec, tmpV3_0; vec_float4 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; cosAngle = _vmathVfDot3( unitVec0->vec128, unitVec1->vec128 ); cosAngle = spu_shuffle( cosAngle, cosAngle, (vec_uchar16)spu_splats(0x00010203) ); cosAngleX2Plus2 = spu_madd( cosAngle, spu_splats(2.0f), spu_splats(2.0f) ); recipCosHalfAngleX2 = rsqrtf4( cosAngleX2Plus2 ); cosHalfAngleX2 = spu_mul( recipCosHalfAngleX2, cosAngleX2Plus2 ); vmathV3Cross( &tmpV3_0, unitVec0, unitVec1 ); crossVec = tmpV3_0; res = spu_mul( crossVec.vec128, recipCosHalfAngleX2 ); res = spu_sel( res, spu_mul( cosHalfAngleX2, spu_splats(0.5f) ), (vec_uint4)spu_maskb(0x000f) ); result->vec128 = res; } static inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec ) { vec_float4 s, c, angle, res; angle = spu_mul( spu_splats(radians), spu_splats(0.5f) ); sincosf4( angle, &s, &c ); res = spu_sel( spu_mul( unitVec->vec128, s ), c, (vec_uint4)spu_maskb(0x000f) ); result->vec128 = res; } static inline void vmathQMakeRotationX( VmathQuat *result, float radians ) { vec_float4 s, c, angle, res; angle = spu_mul( spu_splats(radians), spu_splats(0.5f) ); sincosf4( angle, &s, &c ); res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0xf000) ); res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) ); result->vec128 = res; } static inline void vmathQMakeRotationY( VmathQuat *result, float radians ) { vec_float4 s, c, angle, res; angle = spu_mul( spu_splats(radians), spu_splats(0.5f) ); sincosf4( angle, &s, &c ); res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0x0f00) ); res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) ); result->vec128 = res; } static inline void vmathQMakeRotationZ( VmathQuat *result, float radians ) { vec_float4 s, c, angle, res; angle = spu_mul( spu_splats(radians), spu_splats(0.5f) ); sincosf4( angle, &s, &c ); res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0x00f0) ); res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) ); result->vec128 = res; } static inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ) { vec_float4 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; vec_float4 product, l_wxyz, r_wxyz, xy, qw; ldata = quat0->vec128; rdata = quat1->vec128; vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); tmp0 = spu_shuffle( ldata, ldata, _VECTORMATH_SHUF_YZXW ); tmp1 = spu_shuffle( rdata, rdata, _VECTORMATH_SHUF_ZXYW ); tmp2 = spu_shuffle( ldata, ldata, _VECTORMATH_SHUF_ZXYW ); tmp3 = spu_shuffle( rdata, rdata, _VECTORMATH_SHUF_YZXW ); qv = spu_mul( spu_shuffle( ldata, ldata, shuffle_wwww ), rdata ); qv = spu_madd( spu_shuffle( rdata, rdata, shuffle_wwww ), ldata, qv ); qv = spu_madd( tmp0, tmp1, qv ); qv = spu_nmsub( tmp2, tmp3, qv ); product = spu_mul( ldata, rdata ); l_wxyz = spu_rlqwbyte( ldata, 12 ); r_wxyz = spu_rlqwbyte( rdata, 12 ); qw = spu_nmsub( l_wxyz, r_wxyz, product ); xy = spu_madd( l_wxyz, r_wxyz, product ); qw = spu_sub( qw, spu_rlqwbyte( xy, 8 ) ); result->vec128 = spu_sel( qv, qw, (vec_uint4)spu_maskb( 0x000f ) ); } static inline void vmathQRotate( VmathVector3 *result, const VmathQuat *quat, const VmathVector3 *vec ) { vec_float4 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; qdata = quat->vec128; vdata = vec->vec128; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); tmp0 = spu_shuffle( qdata, qdata, _VECTORMATH_SHUF_YZXW ); tmp1 = spu_shuffle( vdata, vdata, _VECTORMATH_SHUF_ZXYW ); tmp2 = spu_shuffle( qdata, qdata, _VECTORMATH_SHUF_ZXYW ); tmp3 = spu_shuffle( vdata, vdata, _VECTORMATH_SHUF_YZXW ); wwww = spu_shuffle( qdata, qdata, shuffle_wwww ); qv = spu_mul( wwww, vdata ); qv = spu_madd( tmp0, tmp1, qv ); qv = spu_nmsub( tmp2, tmp3, qv ); product = spu_mul( qdata, vdata ); qw = spu_madd( spu_rlqwbyte( qdata, 4 ), spu_rlqwbyte( vdata, 4 ), product ); qw = spu_add( spu_rlqwbyte( product, 8 ), qw ); tmp1 = spu_shuffle( qv, qv, _VECTORMATH_SHUF_ZXYW ); tmp3 = spu_shuffle( qv, qv, _VECTORMATH_SHUF_YZXW ); res = spu_mul( spu_shuffle( qw, qw, shuffle_xxxx ), qdata ); res = spu_madd( wwww, qv, res ); res = spu_madd( tmp0, tmp1, res ); res = spu_nmsub( tmp2, tmp3, res ); result->vec128 = res; } static inline void vmathQConj( VmathQuat *result, const VmathQuat *quat ) { result->vec128 = spu_xor( quat->vec128, ((vec_float4)(vec_int4){0x80000000,0x80000000,0x80000000,0}) ); } static inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 ) { result->vec128 = spu_sel( quat0->vec128, quat1->vec128, spu_splats( (unsigned int)-(select1 > 0) ) ); } #ifdef _VECTORMATH_DEBUG static inline void vmathQPrint( const VmathQuat *quat ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = quat->vec128; printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } static inline void vmathQPrints( const VmathQuat *quat, const char *name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = quat->vec128; printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/quat_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_V_C_H #define _VECTORMATH_QUAT_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathQuat vmathQMakeFromElems_V( float _x, float _y, float _z, float _w ) { VmathQuat result; vmathQMakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float _w ) { VmathQuat result; vmathQMakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec ) { VmathQuat result; vmathQMakeFromV4(&result, &vec); return result; } static inline VmathQuat vmathQMakeFromScalar_V( float scalar ) { VmathQuat result; vmathQMakeFromScalar(&result, scalar); return result; } static inline VmathQuat vmathQMakeFrom128_V( vec_float4 vf4 ) { VmathQuat result; vmathQMakeFrom128(&result, vf4); return result; } static inline VmathQuat vmathQMakeIdentity_V( ) { VmathQuat result; vmathQMakeIdentity(&result); return result; } static inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQLerp(&result, t, &quat0, &quat1); return result; } static inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 ) { VmathQuat result; vmathQSlerp(&result, t, &unitQuat0, &unitQuat1); return result; } static inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 ) { VmathQuat result; vmathQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3); return result; } static inline vec_float4 vmathQGet128_V( VmathQuat quat ) { return vmathQGet128(&quat); } static inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec ) { vmathQSetXYZ(result, &vec); } static inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat ) { VmathVector3 result; vmathQGetXYZ(&result, &quat); return result; } static inline void vmathQSetX_V( VmathQuat *result, float _x ) { vmathQSetX(result, _x); } static inline float vmathQGetX_V( VmathQuat quat ) { return vmathQGetX(&quat); } static inline void vmathQSetY_V( VmathQuat *result, float _y ) { vmathQSetY(result, _y); } static inline float vmathQGetY_V( VmathQuat quat ) { return vmathQGetY(&quat); } static inline void vmathQSetZ_V( VmathQuat *result, float _z ) { vmathQSetZ(result, _z); } static inline float vmathQGetZ_V( VmathQuat quat ) { return vmathQGetZ(&quat); } static inline void vmathQSetW_V( VmathQuat *result, float _w ) { vmathQSetW(result, _w); } static inline float vmathQGetW_V( VmathQuat quat ) { return vmathQGetW(&quat); } static inline void vmathQSetElem_V( VmathQuat *result, int idx, float value ) { vmathQSetElem(result, idx, value); } static inline float vmathQGetElem_V( VmathQuat quat, int idx ) { return vmathQGetElem(&quat, idx); } static inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQAdd(&result, &quat0, &quat1); return result; } static inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQSub(&result, &quat0, &quat1); return result; } static inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar ) { VmathQuat result; vmathQScalarMul(&result, &quat, scalar); return result; } static inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar ) { VmathQuat result; vmathQScalarDiv(&result, &quat, scalar); return result; } static inline VmathQuat vmathQNeg_V( VmathQuat quat ) { VmathQuat result; vmathQNeg(&result, &quat); return result; } static inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 ) { return vmathQDot(&quat0, &quat1); } static inline float vmathQNorm_V( VmathQuat quat ) { return vmathQNorm(&quat); } static inline float vmathQLength_V( VmathQuat quat ) { return vmathQLength(&quat); } static inline VmathQuat vmathQNormalize_V( VmathQuat quat ) { VmathQuat result; vmathQNormalize(&result, &quat); return result; } static inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 ) { VmathQuat result; vmathQMakeRotationArc(&result, &unitVec0, &unitVec1); return result; } static inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec ) { VmathQuat result; vmathQMakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathQuat vmathQMakeRotationX_V( float radians ) { VmathQuat result; vmathQMakeRotationX(&result, radians); return result; } static inline VmathQuat vmathQMakeRotationY_V( float radians ) { VmathQuat result; vmathQMakeRotationY(&result, radians); return result; } static inline VmathQuat vmathQMakeRotationZ_V( float radians ) { VmathQuat result; vmathQMakeRotationZ(&result, radians); return result; } static inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 ) { VmathQuat result; vmathQMul(&result, &quat0, &quat1); return result; } static inline VmathVector3 vmathQRotate_V( VmathQuat quat, VmathVector3 vec ) { VmathVector3 result; vmathQRotate(&result, &quat, &vec); return result; } static inline VmathQuat vmathQConj_V( VmathQuat quat ) { VmathQuat result; vmathQConj(&result, &quat); return result; } static inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 ) { VmathQuat result; vmathQSelect(&result, &quat0, &quat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathQPrint_V( VmathQuat quat ) { vmathQPrint(&quat); } static inline void vmathQPrints_V( VmathQuat quat, const char *name ) { vmathQPrints(&quat, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/quat_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_SOA_C_H #define _VECTORMATH_QUAT_SOA_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat ) { result->x = quat->x; result->y = quat->y; result->z = quat->z; result->w = quat->w; } static inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { result->x = _x; result->y = _y; result->z = _z; result->w = _w; } static inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 _w ) { vmathSoaQSetXYZ( result, xyz ); vmathSoaQSetW( result, _w ); } static inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = vec->w; } static inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; result->w = scalar; } static inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat ) { vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); vec_float4 vec128 = quat->vec128; result->x = spu_shuffle( vec128, vec128, shuffle_xxxx ); result->y = spu_shuffle( vec128, vec128, shuffle_yyyy ); result->z = spu_shuffle( vec128, vec128, shuffle_zzzz ); result->w = spu_shuffle( vec128, vec128, shuffle_wwww ); } static inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( quat0->vec128, quat2->vec128, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( quat1->vec128, quat3->vec128, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( quat0->vec128, quat2->vec128, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( quat1->vec128, quat3->vec128, _VECTORMATH_SHUF_ZCWD ); result->x = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); result->y = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); result->z = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); result->w = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ); } static inline void vmathSoaQMakeIdentity( VmathSoaQuat *result ) { vmathSoaQMakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) ); } static inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { VmathSoaQuat tmpQ_0, tmpQ_1; vmathSoaQSub( &tmpQ_0, quat1, quat0 ); vmathSoaQScalarMul( &tmpQ_1, &tmpQ_0, t ); vmathSoaQAdd( result, quat0, &tmpQ_1 ); } static inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 ) { VmathSoaQuat start, tmpQ_0, tmpQ_1; vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = vmathSoaQDot( unitQuat0, unitQuat1 ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(0.0f), cosAngle ); cosAngle = spu_sel( cosAngle, negatef4( cosAngle ), selectMask ); vmathSoaQSetX( &start, spu_sel( unitQuat0->x, negatef4( unitQuat0->x ), selectMask ) ); vmathSoaQSetY( &start, spu_sel( unitQuat0->y, negatef4( unitQuat0->y ), selectMask ) ); vmathSoaQSetZ( &start, spu_sel( unitQuat0->z, negatef4( unitQuat0->z ), selectMask ) ); vmathSoaQSetW( &start, spu_sel( unitQuat0->w, negatef4( unitQuat0->w ), selectMask ) ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = recipf4( sinf4( angle ) ); 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 ); scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask ); vmathSoaQScalarMul( &tmpQ_0, &start, scale0 ); vmathSoaQScalarMul( &tmpQ_1, unitQuat1, scale1 ); vmathSoaQAdd( result, &tmpQ_0, &tmpQ_1 ); } static inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 ) { VmathSoaQuat tmp0, tmp1; vmathSoaQSlerp( &tmp0, t, unitQuat0, unitQuat3 ); vmathSoaQSlerp( &tmp1, t, unitQuat1, unitQuat2 ); vmathSoaQSlerp( result, spu_mul( spu_mul( spu_splats(2.0f), t ), spu_sub( spu_splats(1.0f), t ) ), &tmp0, &tmp1 ); } static inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( quat->x, quat->z, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( quat->y, quat->w, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( quat->x, quat->z, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( quat->y, quat->w, _VECTORMATH_SHUF_ZCWD ); vmathQMakeFrom128( result0, spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ) ); vmathQMakeFrom128( result1, spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ) ); vmathQMakeFrom128( result2, spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ) ); vmathQMakeFrom128( result3, spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ) ); } static inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat ) { vmathSoaV3MakeFromElems( result, quat->x, quat->y, quat->z ); } static inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 _x ) { result->x = _x; } static inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat ) { return quat->x; } static inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 _y ) { result->y = _y; } static inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat ) { return quat->y; } static inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 _z ) { result->z = _z; } static inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat ) { return quat->z; } static inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 _w ) { result->w = _w; } static inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat ) { return quat->w; } static inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value ) { *(&result->x + idx) = value; } static inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx ) { return *(&quat->x + idx); } static inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { result->x = spu_add( quat0->x, quat1->x ); result->y = spu_add( quat0->y, quat1->y ); result->z = spu_add( quat0->z, quat1->z ); result->w = spu_add( quat0->w, quat1->w ); } static inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { result->x = spu_sub( quat0->x, quat1->x ); result->y = spu_sub( quat0->y, quat1->y ); result->z = spu_sub( quat0->z, quat1->z ); result->w = spu_sub( quat0->w, quat1->w ); } static inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar ) { result->x = spu_mul( quat->x, scalar ); result->y = spu_mul( quat->y, scalar ); result->z = spu_mul( quat->z, scalar ); result->w = spu_mul( quat->w, scalar ); } static inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar ) { result->x = divf4( quat->x, scalar ); result->y = divf4( quat->y, scalar ); result->z = divf4( quat->z, scalar ); result->w = divf4( quat->w, scalar ); } static inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat ) { result->x = negatef4( quat->x ); result->y = negatef4( quat->y ); result->z = negatef4( quat->z ); result->w = negatef4( quat->w ); } static inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { vec_float4 result; result = spu_mul( quat0->x, quat1->x ); result = spu_add( result, spu_mul( quat0->y, quat1->y ) ); result = spu_add( result, spu_mul( quat0->z, quat1->z ) ); result = spu_add( result, spu_mul( quat0->w, quat1->w ) ); return result; } static inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat ) { vec_float4 result; result = spu_mul( quat->x, quat->x ); result = spu_add( result, spu_mul( quat->y, quat->y ) ); result = spu_add( result, spu_mul( quat->z, quat->z ) ); result = spu_add( result, spu_mul( quat->w, quat->w ) ); return result; } static inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat ) { return sqrtf4( vmathSoaQNorm( quat ) ); } static inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat ) { vec_float4 lenSqr, lenInv; lenSqr = vmathSoaQNorm( quat ); lenInv = rsqrtf4( lenSqr ); result->x = spu_mul( quat->x, lenInv ); result->y = spu_mul( quat->y, lenInv ); result->z = spu_mul( quat->z, lenInv ); result->w = spu_mul( quat->w, lenInv ); } static inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 ) { VmathSoaVector3 tmpV3_0, tmpV3_1; vec_float4 cosHalfAngleX2, recipCosHalfAngleX2; cosHalfAngleX2 = sqrtf4( spu_mul( spu_splats(2.0f), spu_add( spu_splats(1.0f), vmathSoaV3Dot( unitVec0, unitVec1 ) ) ) ); recipCosHalfAngleX2 = recipf4( cosHalfAngleX2 ); vmathSoaV3Cross( &tmpV3_0, unitVec0, unitVec1 ); vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, recipCosHalfAngleX2 ); vmathSoaQMakeFromV3Scalar( result, &tmpV3_1, spu_mul( cosHalfAngleX2, spu_splats(0.5f) ) ); } static inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec ) { VmathSoaVector3 tmpV3_0; vec_float4 s, c, angle; angle = spu_mul( radians, spu_splats(0.5f) ); sincosf4( angle, &s, &c ); vmathSoaV3ScalarMul( &tmpV3_0, unitVec, s ); vmathSoaQMakeFromV3Scalar( result, &tmpV3_0, c ); } static inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians ) { vec_float4 s, c, angle; angle = spu_mul( radians, spu_splats(0.5f) ); sincosf4( angle, &s, &c ); vmathSoaQMakeFromElems( result, s, spu_splats(0.0f), spu_splats(0.0f), c ); } static inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians ) { vec_float4 s, c, angle; angle = spu_mul( radians, spu_splats(0.5f) ); sincosf4( angle, &s, &c ); vmathSoaQMakeFromElems( result, spu_splats(0.0f), s, spu_splats(0.0f), c ); } static inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians ) { vec_float4 s, c, angle; angle = spu_mul( radians, spu_splats(0.5f) ); sincosf4( angle, &s, &c ); vmathSoaQMakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), s, c ); } static inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ) { vec_float4 tmpX, tmpY, tmpZ, tmpW; 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 ) ); 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 ) ); 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 ) ); 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 ) ); vmathSoaQMakeFromElems( result, tmpX, tmpY, tmpZ, tmpW ); } static inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *quat, const VmathSoaVector3 *vec ) { vec_float4 tmpX, tmpY, tmpZ, tmpW; tmpX = spu_sub( spu_add( spu_mul( quat->w, vec->x ), spu_mul( quat->y, vec->z ) ), spu_mul( quat->z, vec->y ) ); tmpY = spu_sub( spu_add( spu_mul( quat->w, vec->y ), spu_mul( quat->z, vec->x ) ), spu_mul( quat->x, vec->z ) ); tmpZ = spu_sub( spu_add( spu_mul( quat->w, vec->z ), spu_mul( quat->x, vec->y ) ), spu_mul( quat->y, vec->x ) ); tmpW = spu_add( spu_add( spu_mul( quat->x, vec->x ), spu_mul( quat->y, vec->y ) ), spu_mul( quat->z, vec->z ) ); 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 ) ); 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 ) ); 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 ) ); } static inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat ) { vmathSoaQMakeFromElems( result, negatef4( quat->x ), negatef4( quat->y ), negatef4( quat->z ), quat->w ); } static inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 ) { result->x = spu_sel( quat0->x, quat1->x, select1 ); result->y = spu_sel( quat0->y, quat1->y, select1 ); result->z = spu_sel( quat0->z, quat1->z, select1 ); result->w = spu_sel( quat0->w, quat1->w, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaQPrint( const VmathSoaQuat *quat ) { VmathQuat vec0, vec1, vec2, vec3; vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathQPrint( &vec0 ); printf("slot 1:\n"); vmathQPrint( &vec1 ); printf("slot 2:\n"); vmathQPrint( &vec2 ); printf("slot 3:\n"); vmathQPrint( &vec3 ); } static inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name ) { VmathQuat vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathQPrint( &vec0 ); printf("slot 1:\n"); vmathQPrint( &vec1 ); printf("slot 2:\n"); vmathQPrint( &vec2 ); printf("slot 3:\n"); vmathQPrint( &vec3 ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/quat_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_SOA_V_C_H #define _VECTORMATH_QUAT_SOA_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathSoaQuat vmathSoaQMakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { VmathSoaQuat result; vmathSoaQMakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathSoaQuat vmathSoaQMakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 _w ) { VmathSoaQuat result; vmathSoaQMakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathSoaQuat vmathSoaQMakeFromV4_V( VmathSoaVector4 vec ) { VmathSoaQuat result; vmathSoaQMakeFromV4(&result, &vec); return result; } static inline VmathSoaQuat vmathSoaQMakeFromScalar_V( vec_float4 scalar ) { VmathSoaQuat result; vmathSoaQMakeFromScalar(&result, scalar); return result; } static inline VmathSoaQuat vmathSoaQMakeFromAos_V( VmathQuat quat ) { VmathSoaQuat result; vmathSoaQMakeFromAos(&result, &quat); return result; } static inline VmathSoaQuat vmathSoaQMakeFrom4Aos_V( VmathQuat quat0, VmathQuat quat1, VmathQuat quat2, VmathQuat quat3 ) { VmathSoaQuat result; vmathSoaQMakeFrom4Aos(&result, &quat0, &quat1, &quat2, &quat3); return result; } static inline VmathSoaQuat vmathSoaQMakeIdentity_V( ) { VmathSoaQuat result; vmathSoaQMakeIdentity(&result); return result; } static inline VmathSoaQuat vmathSoaQLerp_V( vec_float4 t, VmathSoaQuat quat0, VmathSoaQuat quat1 ) { VmathSoaQuat result; vmathSoaQLerp(&result, t, &quat0, &quat1); return result; } static inline VmathSoaQuat vmathSoaQSlerp_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1 ) { VmathSoaQuat result; vmathSoaQSlerp(&result, t, &unitQuat0, &unitQuat1); return result; } static inline VmathSoaQuat vmathSoaQSquad_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1, VmathSoaQuat unitQuat2, VmathSoaQuat unitQuat3 ) { VmathSoaQuat result; vmathSoaQSquad(&result, t, &unitQuat0, &unitQuat1, &unitQuat2, &unitQuat3); return result; } static inline void vmathSoaQGet4Aos_V( VmathSoaQuat quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 ) { vmathSoaQGet4Aos(&quat, result0, result1, result2, result3); } static inline void vmathSoaQSetXYZ_V( VmathSoaQuat *result, VmathSoaVector3 vec ) { vmathSoaQSetXYZ(result, &vec); } static inline VmathSoaVector3 vmathSoaQGetXYZ_V( VmathSoaQuat quat ) { VmathSoaVector3 result; vmathSoaQGetXYZ(&result, &quat); return result; } static inline void vmathSoaQSetX_V( VmathSoaQuat *result, vec_float4 _x ) { vmathSoaQSetX(result, _x); } static inline vec_float4 vmathSoaQGetX_V( VmathSoaQuat quat ) { return vmathSoaQGetX(&quat); } static inline void vmathSoaQSetY_V( VmathSoaQuat *result, vec_float4 _y ) { vmathSoaQSetY(result, _y); } static inline vec_float4 vmathSoaQGetY_V( VmathSoaQuat quat ) { return vmathSoaQGetY(&quat); } static inline void vmathSoaQSetZ_V( VmathSoaQuat *result, vec_float4 _z ) { vmathSoaQSetZ(result, _z); } static inline vec_float4 vmathSoaQGetZ_V( VmathSoaQuat quat ) { return vmathSoaQGetZ(&quat); } static inline void vmathSoaQSetW_V( VmathSoaQuat *result, vec_float4 _w ) { vmathSoaQSetW(result, _w); } static inline vec_float4 vmathSoaQGetW_V( VmathSoaQuat quat ) { return vmathSoaQGetW(&quat); } static inline void vmathSoaQSetElem_V( VmathSoaQuat *result, int idx, vec_float4 value ) { vmathSoaQSetElem(result, idx, value); } static inline vec_float4 vmathSoaQGetElem_V( VmathSoaQuat quat, int idx ) { return vmathSoaQGetElem(&quat, idx); } static inline VmathSoaQuat vmathSoaQAdd_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ) { VmathSoaQuat result; vmathSoaQAdd(&result, &quat0, &quat1); return result; } static inline VmathSoaQuat vmathSoaQSub_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ) { VmathSoaQuat result; vmathSoaQSub(&result, &quat0, &quat1); return result; } static inline VmathSoaQuat vmathSoaQScalarMul_V( VmathSoaQuat quat, vec_float4 scalar ) { VmathSoaQuat result; vmathSoaQScalarMul(&result, &quat, scalar); return result; } static inline VmathSoaQuat vmathSoaQScalarDiv_V( VmathSoaQuat quat, vec_float4 scalar ) { VmathSoaQuat result; vmathSoaQScalarDiv(&result, &quat, scalar); return result; } static inline VmathSoaQuat vmathSoaQNeg_V( VmathSoaQuat quat ) { VmathSoaQuat result; vmathSoaQNeg(&result, &quat); return result; } static inline vec_float4 vmathSoaQDot_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ) { return vmathSoaQDot(&quat0, &quat1); } static inline vec_float4 vmathSoaQNorm_V( VmathSoaQuat quat ) { return vmathSoaQNorm(&quat); } static inline vec_float4 vmathSoaQLength_V( VmathSoaQuat quat ) { return vmathSoaQLength(&quat); } static inline VmathSoaQuat vmathSoaQNormalize_V( VmathSoaQuat quat ) { VmathSoaQuat result; vmathSoaQNormalize(&result, &quat); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationArc_V( VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 ) { VmathSoaQuat result; vmathSoaQMakeRotationArc(&result, &unitVec0, &unitVec1); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ) { VmathSoaQuat result; vmathSoaQMakeRotationAxis(&result, radians, &unitVec); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationX_V( vec_float4 radians ) { VmathSoaQuat result; vmathSoaQMakeRotationX(&result, radians); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationY_V( vec_float4 radians ) { VmathSoaQuat result; vmathSoaQMakeRotationY(&result, radians); return result; } static inline VmathSoaQuat vmathSoaQMakeRotationZ_V( vec_float4 radians ) { VmathSoaQuat result; vmathSoaQMakeRotationZ(&result, radians); return result; } static inline VmathSoaQuat vmathSoaQMul_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ) { VmathSoaQuat result; vmathSoaQMul(&result, &quat0, &quat1); return result; } static inline VmathSoaVector3 vmathSoaQRotate_V( VmathSoaQuat quat, VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaQRotate(&result, &quat, &vec); return result; } static inline VmathSoaQuat vmathSoaQConj_V( VmathSoaQuat quat ) { VmathSoaQuat result; vmathSoaQConj(&result, &quat); return result; } static inline VmathSoaQuat vmathSoaQSelect_V( VmathSoaQuat quat0, VmathSoaQuat quat1, vec_uint4 select1 ) { VmathSoaQuat result; vmathSoaQSelect(&result, &quat0, &quat1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaQPrint_V( VmathSoaQuat quat ) { vmathSoaQPrint(&quat); } static inline void vmathSoaQPrints_V( VmathSoaQuat quat, const char *name ) { vmathSoaQPrints(&quat, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/vec_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_C_H #define _VECTORMATH_VEC_AOS_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for shuffles, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_SHUF_X 0x00010203 #define _VECTORMATH_SHUF_Y 0x04050607 #define _VECTORMATH_SHUF_Z 0x08090a0b #define _VECTORMATH_SHUF_W 0x0c0d0e0f #define _VECTORMATH_SHUF_A 0x10111213 #define _VECTORMATH_SHUF_B 0x14151617 #define _VECTORMATH_SHUF_C 0x18191a1b #define _VECTORMATH_SHUF_D 0x1c1d1e1f #define _VECTORMATH_SHUF_0 0x80808080 #define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A } #define _VECTORMATH_SHUF_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_W } #define _VECTORMATH_SHUF_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W } #define _VECTORMATH_SHUF_WABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C } #define _VECTORMATH_SHUF_ZWAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B } #define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A } #define _VECTORMATH_SHUF_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B } #define _VECTORMATH_SHUF_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C } #define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f } #define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f } #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS static inline vec_float4 _vmathVfDot3( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 result; result = spu_mul( vec0, vec1 ); result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result ); return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result ); } static inline vec_float4 _vmathVfDot4( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 result; result = spu_mul( vec0, vec1 ); result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result ); return spu_add( spu_rlqwbyte( result, 8 ), result ); } static inline vec_float4 _vmathVfCross( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 tmp0, tmp1, tmp2, tmp3, result; tmp0 = spu_shuffle( vec0, vec0, _VECTORMATH_SHUF_YZXW ); tmp1 = spu_shuffle( vec1, vec1, _VECTORMATH_SHUF_ZXYW ); tmp2 = spu_shuffle( vec0, vec0, _VECTORMATH_SHUF_ZXYW ); tmp3 = spu_shuffle( vec1, vec1, _VECTORMATH_SHUF_YZXW ); result = spu_mul( tmp0, tmp1 ); result = spu_nmsub( tmp2, tmp3, result ); return result; } static inline vec_uint4 _vmathVfToHalfFloatsUnpacked(vec_float4 v) { vec_int4 bexp; vec_uint4 mant, sign, hfloat; vec_uint4 notZero, isInf; const vec_uint4 hfloatInf = spu_splats(0x00007c00u); const vec_uint4 mergeMant = spu_splats(0x000003ffu); const vec_uint4 mergeSign = spu_splats(0x00008000u); sign = spu_rlmask((vec_uint4)v, -16); mant = spu_rlmask((vec_uint4)v, -13); bexp = spu_and(spu_rlmask((vec_int4)v, -23), 0xff); notZero = spu_cmpgt(bexp, 112); isInf = spu_cmpgt(bexp, 142); bexp = spu_add(bexp, -112); bexp = spu_sl(bexp, 10); hfloat = spu_sel((vec_uint4)bexp, mant, mergeMant); hfloat = spu_sel(spu_splats(0u), hfloat, notZero); hfloat = spu_sel(hfloat, hfloatInf, isInf); hfloat = spu_sel(hfloat, sign, mergeSign); return hfloat; } static inline vec_ushort8 _vmath2VfToHalfFloats(vec_float4 u, vec_float4 v) { vec_uint4 hfloat_u, hfloat_v; const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31}; hfloat_u = _vmathVfToHalfFloatsUnpacked(u); hfloat_v = _vmathVfToHalfFloatsUnpacked(v); return (vec_ushort8)spu_shuffle(hfloat_u, hfloat_v, pack); } #endif static inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = vec->vec128; } static inline void vmathV3MakeFromElems( VmathVector3 *result, float _x, float _y, float _z ) { result->vec128 = (vec_float4){ _x, _y, _z, 0.0f }; } static inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt ) { result->vec128 = pnt->vec128; } static inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar ) { result->vec128 = spu_splats( scalar ); } static inline void vmathV3MakeFrom128( VmathVector3 *result, vec_float4 vf4 ) { result->vec128 = vf4; } static inline void vmathV3MakeXAxis( VmathVector3 *result ) { result->vec128 = _VECTORMATH_UNIT_1000; } static inline void vmathV3MakeYAxis( VmathVector3 *result ) { result->vec128 = _VECTORMATH_UNIT_0100; } static inline void vmathV3MakeZAxis( VmathVector3 *result ) { result->vec128 = _VECTORMATH_UNIT_0010; } static inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { VmathVector3 tmpV3_0, tmpV3_1; vmathV3Sub( &tmpV3_0, vec1, vec0 ); vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathV3Add( result, vec0, &tmpV3_1 ); } static inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ) { vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); cosAngle = _vmathVfDot3( unitVec0->vec128, unitVec1->vec128 ); cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = spu_splats(t); oneMinusT = spu_sub( spu_splats(1.0f), tttt ); angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) ); angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) ); angles = spu_mul( angles, angle ); sines = sinf4( angles ); scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) ); scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask ); scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask ); result->vec128 = spu_madd( unitVec0->vec128, scale0, spu_mul( unitVec1->vec128, scale1 ) ); } static inline vec_float4 vmathV3Get128( const VmathVector3 *vec ) { return vec->vec128; } static inline void vmathV3StoreXYZ( const VmathVector3 *vec, vec_float4 *quad ) { vec_float4 dstVec = *quad; vec_uint4 mask = (vec_uint4)spu_maskb(0x000f); dstVec = spu_sel(vec->vec128, dstVec, mask); *quad = dstVec; } static inline void vmathV3LoadXYZArray( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyz1 = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_WABC ); xyz2 = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_ZWAB ); xyz3 = spu_rlqwbyte( zxyz, 4 ); vec0->vec128 = xyzx; vec1->vec128 = xyz1; vec2->vec128 = xyz2; vec3->vec128 = xyz3; } static inline void vmathV3StoreXYZArray( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz; xyzx = spu_shuffle( vec0->vec128, vec1->vec128, _VECTORMATH_SHUF_XYZA ); yzxy = spu_shuffle( vec1->vec128, vec2->vec128, _VECTORMATH_SHUF_YZAB ); zxyz = spu_shuffle( vec2->vec128, vec3->vec128, _VECTORMATH_SHUF_ZABC ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } static 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 ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; vmathV3StoreXYZArray( vec0, vec1, vec2, vec3, xyz0 ); vmathV3StoreXYZArray( vec4, vec5, vec6, vec7, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } static inline void vmathV3SetX( VmathVector3 *result, float _x ) { result->vec128 = spu_insert( _x, result->vec128, 0 ); } static inline float vmathV3GetX( const VmathVector3 *vec ) { return spu_extract( vec->vec128, 0 ); } static inline void vmathV3SetY( VmathVector3 *result, float _y ) { result->vec128 = spu_insert( _y, result->vec128, 1 ); } static inline float vmathV3GetY( const VmathVector3 *vec ) { return spu_extract( vec->vec128, 1 ); } static inline void vmathV3SetZ( VmathVector3 *result, float _z ) { result->vec128 = spu_insert( _z, result->vec128, 2 ); } static inline float vmathV3GetZ( const VmathVector3 *vec ) { return spu_extract( vec->vec128, 2 ); } static inline void vmathV3SetElem( VmathVector3 *result, int idx, float value ) { result->vec128 = spu_insert( value, result->vec128, idx ); } static inline float vmathV3GetElem( const VmathVector3 *vec, int idx ) { return spu_extract( vec->vec128, idx ); } static inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = spu_add( vec0->vec128, vec1->vec128 ); } static inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = spu_sub( vec0->vec128, vec1->vec128 ); } static inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt1 ) { result->vec128 = spu_add( vec->vec128, pnt1->vec128 ); } static inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar ) { result->vec128 = spu_mul( vec->vec128, spu_splats(scalar) ); } static inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar ) { result->vec128 = divf4( vec->vec128, spu_splats(scalar) ); } static inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = negatef4( vec->vec128 ); } static inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = spu_mul( vec0->vec128, vec1->vec128 ); } static inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = divf4( vec0->vec128, vec1->vec128 ); } static inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = recipf4( vec->vec128 ); } static inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = sqrtf4( vec->vec128 ); } static inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = rsqrtf4( vec->vec128 ); } static inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec ) { result->vec128 = fabsf4( vec->vec128 ); } static inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = copysignf4( vec0->vec128, vec1->vec128 ); } static inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = fmaxf4( vec0->vec128, vec1->vec128 ); } static inline float vmathV3MaxElem( const VmathVector3 *vec ) { vec_float4 result; result = fmaxf4( spu_promote( spu_extract( vec->vec128, 1 ), 0 ), vec->vec128 ); result = fmaxf4( spu_promote( spu_extract( vec->vec128, 2 ), 0 ), result ); return spu_extract( result, 0 ); } static inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = fminf4( vec0->vec128, vec1->vec128 ); } static inline float vmathV3MinElem( const VmathVector3 *vec ) { vec_float4 result; result = fminf4( spu_promote( spu_extract( vec->vec128, 1 ), 0 ), vec->vec128 ); result = fminf4( spu_promote( spu_extract( vec->vec128, 2 ), 0 ), result ); return spu_extract( result, 0 ); } static inline float vmathV3Sum( const VmathVector3 *vec ) { return spu_extract( vec->vec128, 0 ) + spu_extract( vec->vec128, 1 ) + spu_extract( vec->vec128, 2 ); } static inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 ) { return spu_extract( _vmathVfDot3( vec0->vec128, vec1->vec128 ), 0 ); } static inline float vmathV3LengthSqr( const VmathVector3 *vec ) { return spu_extract( _vmathVfDot3( vec->vec128, vec->vec128 ), 0 ); } static inline float vmathV3Length( const VmathVector3 *vec ) { return sqrtf( vmathV3LengthSqr( vec ) ); } static inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec ) { vec_float4 dot = _vmathVfDot3( vec->vec128, vec->vec128 ); dot = spu_shuffle( dot, dot, (vec_uchar16)spu_splats(0x00010203) ); result->vec128 = spu_mul( vec->vec128, rsqrtf4( dot ) ); } static inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ) { result->vec128 = _vmathVfCross( vec0->vec128, vec1->vec128 ); } static inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 ) { result->vec128 = spu_sel( vec0->vec128, vec1->vec128, spu_splats( (unsigned int)-(select1 > 0) ) ); } #ifdef _VECTORMATH_DEBUG static inline void vmathV3Print( const VmathVector3 *vec ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec->vec128; printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } static inline void vmathV3Prints( const VmathVector3 *vec, const char *name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec->vec128; printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif static inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = vec->vec128; } static inline void vmathV4MakeFromElems( VmathVector4 *result, float _x, float _y, float _z, float _w ) { result->vec128 = (vec_float4){ _x, _y, _z, _w }; } static inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float _w ) { result->vec128 = spu_shuffle( xyz->vec128, spu_promote( _w, 0 ), _VECTORMATH_SHUF_XYZA ); } static inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec ) { result->vec128 = spu_sel( vec->vec128, spu_splats(0.0f), (vec_uint4)spu_maskb(0x000f) ); } static inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt ) { result->vec128 = spu_sel( pnt->vec128, spu_splats(1.0f), (vec_uint4)spu_maskb(0x000f) ); } static inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat ) { result->vec128 = quat->vec128; } static inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar ) { result->vec128 = spu_splats( scalar ); } static inline void vmathV4MakeFrom128( VmathVector4 *result, vec_float4 vf4 ) { result->vec128 = vf4; } static inline void vmathV4MakeXAxis( VmathVector4 *result ) { result->vec128 = _VECTORMATH_UNIT_1000; } static inline void vmathV4MakeYAxis( VmathVector4 *result ) { result->vec128 = _VECTORMATH_UNIT_0100; } static inline void vmathV4MakeZAxis( VmathVector4 *result ) { result->vec128 = _VECTORMATH_UNIT_0010; } static inline void vmathV4MakeWAxis( VmathVector4 *result ) { result->vec128 = _VECTORMATH_UNIT_0001; } static inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { VmathVector4 tmpV4_0, tmpV4_1; vmathV4Sub( &tmpV4_0, vec1, vec0 ); vmathV4ScalarMul( &tmpV4_1, &tmpV4_0, t ); vmathV4Add( result, vec0, &tmpV4_1 ); } static inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 ) { vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); cosAngle = _vmathVfDot4( unitVec0->vec128, unitVec1->vec128 ); cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = spu_splats(t); oneMinusT = spu_sub( spu_splats(1.0f), tttt ); angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) ); angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) ); angles = spu_mul( angles, angle ); sines = sinf4( angles ); scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) ); scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask ); scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask ); result->vec128 = spu_madd( unitVec0->vec128, scale0, spu_mul( unitVec1->vec128, scale1 ) ); } static inline vec_float4 vmathV4Get128( const VmathVector4 *vec ) { return vec->vec128; } static inline void vmathV4StoreHalfFloats( const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3, vec_ushort8 *twoQuads ) { twoQuads[0] = _vmath2VfToHalfFloats(vec0->vec128, vec1->vec128); twoQuads[1] = _vmath2VfToHalfFloats(vec2->vec128, vec3->vec128); } static inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec ) { result->vec128 = spu_sel( vec->vec128, result->vec128, (vec_uint4)spu_maskb(0x000f) ); } static inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec ) { result->vec128 = vec->vec128; } static inline void vmathV4SetX( VmathVector4 *result, float _x ) { result->vec128 = spu_insert( _x, result->vec128, 0 ); } static inline float vmathV4GetX( const VmathVector4 *vec ) { return spu_extract( vec->vec128, 0 ); } static inline void vmathV4SetY( VmathVector4 *result, float _y ) { result->vec128 = spu_insert( _y, result->vec128, 1 ); } static inline float vmathV4GetY( const VmathVector4 *vec ) { return spu_extract( vec->vec128, 1 ); } static inline void vmathV4SetZ( VmathVector4 *result, float _z ) { result->vec128 = spu_insert( _z, result->vec128, 2 ); } static inline float vmathV4GetZ( const VmathVector4 *vec ) { return spu_extract( vec->vec128, 2 ); } static inline void vmathV4SetW( VmathVector4 *result, float _w ) { result->vec128 = spu_insert( _w, result->vec128, 3 ); } static inline float vmathV4GetW( const VmathVector4 *vec ) { return spu_extract( vec->vec128, 3 ); } static inline void vmathV4SetElem( VmathVector4 *result, int idx, float value ) { result->vec128 = spu_insert( value, result->vec128, idx ); } static inline float vmathV4GetElem( const VmathVector4 *vec, int idx ) { return spu_extract( vec->vec128, idx ); } static inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = spu_add( vec0->vec128, vec1->vec128 ); } static inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = spu_sub( vec0->vec128, vec1->vec128 ); } static inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar ) { result->vec128 = spu_mul( vec->vec128, spu_splats(scalar) ); } static inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar ) { result->vec128 = divf4( vec->vec128, spu_splats(scalar) ); } static inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = negatef4( vec->vec128 ); } static inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = spu_mul( vec0->vec128, vec1->vec128 ); } static inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = divf4( vec0->vec128, vec1->vec128 ); } static inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = recipf4( vec->vec128 ); } static inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = sqrtf4( vec->vec128 ); } static inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = rsqrtf4( vec->vec128 ); } static inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec ) { result->vec128 = fabsf4( vec->vec128 ); } static inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = copysignf4( vec0->vec128, vec1->vec128 ); } static inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = fmaxf4( vec0->vec128, vec1->vec128 ); } static inline float vmathV4MaxElem( const VmathVector4 *vec ) { vec_float4 result; result = fmaxf4( spu_promote( spu_extract( vec->vec128, 1 ), 0 ), vec->vec128 ); result = fmaxf4( spu_promote( spu_extract( vec->vec128, 2 ), 0 ), result ); result = fmaxf4( spu_promote( spu_extract( vec->vec128, 3 ), 0 ), result ); return spu_extract( result, 0 ); } static inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ) { result->vec128 = fminf4( vec0->vec128, vec1->vec128 ); } static inline float vmathV4MinElem( const VmathVector4 *vec ) { vec_float4 result; result = fminf4( spu_promote( spu_extract( vec->vec128, 1 ), 0 ), vec->vec128 ); result = fminf4( spu_promote( spu_extract( vec->vec128, 2 ), 0 ), result ); result = fminf4( spu_promote( spu_extract( vec->vec128, 3 ), 0 ), result ); return spu_extract( result, 0 ); } static inline float vmathV4Sum( const VmathVector4 *vec ) { return spu_extract( vec->vec128, 0 ) + spu_extract( vec->vec128, 1 ) + spu_extract( vec->vec128, 2 ) + spu_extract( vec->vec128, 3 ); } static inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 ) { return spu_extract( _vmathVfDot4( vec0->vec128, vec1->vec128 ), 0 ); } static inline float vmathV4LengthSqr( const VmathVector4 *vec ) { return spu_extract( _vmathVfDot4( vec->vec128, vec->vec128 ), 0 ); } static inline float vmathV4Length( const VmathVector4 *vec ) { return sqrtf( vmathV4LengthSqr( vec ) ); } static inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec ) { vec_float4 dot = _vmathVfDot4( vec->vec128, vec->vec128 ); result->vec128 = spu_mul( vec->vec128, rsqrtf4( dot ) ); } static inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 ) { result->vec128 = spu_sel( vec0->vec128, vec1->vec128, spu_splats( (unsigned int)-(select1 > 0) ) ); } #ifdef _VECTORMATH_DEBUG static inline void vmathV4Print( const VmathVector4 *vec ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec->vec128; printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } static inline void vmathV4Prints( const VmathVector4 *vec, const char *name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec->vec128; printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif static inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = pnt->vec128; } static inline void vmathP3MakeFromElems( VmathPoint3 *result, float _x, float _y, float _z ) { result->vec128 = (vec_float4){ _x, _y, _z, 0.0f }; } static inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec ) { result->vec128 = vec->vec128; } static inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar ) { result->vec128 = spu_splats( scalar ); } static inline void vmathP3MakeFrom128( VmathPoint3 *result, vec_float4 vf4 ) { result->vec128 = vf4; } static inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0, tmpV3_1; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); vmathV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathP3AddV3( result, pnt0, &tmpV3_1 ); } static inline vec_float4 vmathP3Get128( const VmathPoint3 *pnt ) { return pnt->vec128; } static inline void vmathP3StoreXYZ( const VmathPoint3 *pnt, vec_float4 *quad ) { vec_float4 dstVec = *quad; vec_uint4 mask = (vec_uint4)spu_maskb(0x000f); dstVec = spu_sel(pnt->vec128, dstVec, mask); *quad = dstVec; } static inline void vmathP3LoadXYZArray( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyz1 = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_WABC ); xyz2 = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_ZWAB ); xyz3 = spu_rlqwbyte( zxyz, 4 ); pnt0->vec128 = xyzx; pnt1->vec128 = xyz1; pnt2->vec128 = xyz2; pnt3->vec128 = xyz3; } static inline void vmathP3StoreXYZArray( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz; xyzx = spu_shuffle( pnt0->vec128, pnt1->vec128, _VECTORMATH_SHUF_XYZA ); yzxy = spu_shuffle( pnt1->vec128, pnt2->vec128, _VECTORMATH_SHUF_YZAB ); zxyz = spu_shuffle( pnt2->vec128, pnt3->vec128, _VECTORMATH_SHUF_ZABC ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } static 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 ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; vmathP3StoreXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 ); vmathP3StoreXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } static inline void vmathP3SetX( VmathPoint3 *result, float _x ) { result->vec128 = spu_insert( _x, result->vec128, 0 ); } static inline float vmathP3GetX( const VmathPoint3 *pnt ) { return spu_extract( pnt->vec128, 0 ); } static inline void vmathP3SetY( VmathPoint3 *result, float _y ) { result->vec128 = spu_insert( _y, result->vec128, 1 ); } static inline float vmathP3GetY( const VmathPoint3 *pnt ) { return spu_extract( pnt->vec128, 1 ); } static inline void vmathP3SetZ( VmathPoint3 *result, float _z ) { result->vec128 = spu_insert( _z, result->vec128, 2 ); } static inline float vmathP3GetZ( const VmathPoint3 *pnt ) { return spu_extract( pnt->vec128, 2 ); } static inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value ) { result->vec128 = spu_insert( value, result->vec128, idx ); } static inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx ) { return spu_extract( pnt->vec128, idx ); } static inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = spu_sub( pnt0->vec128, pnt1->vec128 ); } static inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 ) { result->vec128 = spu_add( pnt->vec128, vec1->vec128 ); } static inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec1 ) { result->vec128 = spu_sub( pnt->vec128, vec1->vec128 ); } static inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = spu_mul( pnt0->vec128, pnt1->vec128 ); } static inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = divf4( pnt0->vec128, pnt1->vec128 ); } static inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = recipf4( pnt->vec128 ); } static inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = sqrtf4( pnt->vec128 ); } static inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = rsqrtf4( pnt->vec128 ); } static inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ) { result->vec128 = fabsf4( pnt->vec128 ); } static inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = copysignf4( pnt0->vec128, pnt1->vec128 ); } static inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = fmaxf4( pnt0->vec128, pnt1->vec128 ); } static inline float vmathP3MaxElem( const VmathPoint3 *pnt ) { vec_float4 result; result = fmaxf4( spu_promote( spu_extract( pnt->vec128, 1 ), 0 ), pnt->vec128 ); result = fmaxf4( spu_promote( spu_extract( pnt->vec128, 2 ), 0 ), result ); return spu_extract( result, 0 ); } static inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { result->vec128 = fminf4( pnt0->vec128, pnt1->vec128 ); } static inline float vmathP3MinElem( const VmathPoint3 *pnt ) { vec_float4 result; result = fminf4( spu_promote( spu_extract( pnt->vec128, 1 ), 0 ), pnt->vec128 ); result = fminf4( spu_promote( spu_extract( pnt->vec128, 2 ), 0 ), result ); return spu_extract( result, 0 ); } static inline float vmathP3Sum( const VmathPoint3 *pnt ) { return spu_extract( pnt->vec128, 0 ) + spu_extract( pnt->vec128, 1 ) + spu_extract( pnt->vec128, 2 ); } static inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal ) { VmathPoint3 tmpP3_0; vmathP3MakeFromScalar( &tmpP3_0, scaleVal ); vmathP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec ) { VmathPoint3 tmpP3_0; vmathP3MakeFromV3( &tmpP3_0, scaleVec ); vmathP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec ) { return spu_extract( _vmathVfDot3( pnt->vec128, unitVec->vec128 ), 0 ); } static inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt ) { VmathVector3 tmpV3_0; vmathV3MakeFromP3( &tmpV3_0, pnt ); return vmathV3LengthSqr( &tmpV3_0 ); } static inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt ) { VmathVector3 tmpV3_0; vmathV3MakeFromP3( &tmpV3_0, pnt ); return vmathV3Length( &tmpV3_0 ); } static inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathV3LengthSqr( &tmpV3_0 ); } static inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ) { VmathVector3 tmpV3_0; vmathP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathV3Length( &tmpV3_0 ); } static inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 ) { result->vec128 = spu_sel( pnt0->vec128, pnt1->vec128, spu_splats( (unsigned int)-(select1 > 0) ) ); } #ifdef _VECTORMATH_DEBUG static inline void vmathP3Print( const VmathPoint3 *pnt ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = pnt->vec128; printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } static inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = pnt->vec128; printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/vec_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_V_C_H #define _VECTORMATH_VEC_AOS_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for shuffles, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_SHUF_X 0x00010203 #define _VECTORMATH_SHUF_Y 0x04050607 #define _VECTORMATH_SHUF_Z 0x08090a0b #define _VECTORMATH_SHUF_W 0x0c0d0e0f #define _VECTORMATH_SHUF_A 0x10111213 #define _VECTORMATH_SHUF_B 0x14151617 #define _VECTORMATH_SHUF_C 0x18191a1b #define _VECTORMATH_SHUF_D 0x1c1d1e1f #define _VECTORMATH_SHUF_0 0x80808080 #define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A } #define _VECTORMATH_SHUF_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_W } #define _VECTORMATH_SHUF_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W } #define _VECTORMATH_SHUF_WABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C } #define _VECTORMATH_SHUF_ZWAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B } #define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A } #define _VECTORMATH_SHUF_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B } #define _VECTORMATH_SHUF_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C } #define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f } #define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f } #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathVector3 vmathV3MakeFromElems_V( float _x, float _y, float _z ) { VmathVector3 result; vmathV3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt ) { VmathVector3 result; vmathV3MakeFromP3(&result, &pnt); return result; } static inline VmathVector3 vmathV3MakeFromScalar_V( float scalar ) { VmathVector3 result; vmathV3MakeFromScalar(&result, scalar); return result; } static inline VmathVector3 vmathV3MakeFrom128_V( vec_float4 vf4 ) { VmathVector3 result; vmathV3MakeFrom128(&result, vf4); return result; } static inline VmathVector3 vmathV3MakeXAxis_V( ) { VmathVector3 result; vmathV3MakeXAxis(&result); return result; } static inline VmathVector3 vmathV3MakeYAxis_V( ) { VmathVector3 result; vmathV3MakeYAxis(&result); return result; } static inline VmathVector3 vmathV3MakeZAxis_V( ) { VmathVector3 result; vmathV3MakeZAxis(&result); return result; } static inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 ) { VmathVector3 result; vmathV3Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline vec_float4 vmathV3Get128_V( VmathVector3 vec ) { return vmathV3Get128(&vec); } static inline void vmathV3StoreXYZ_V( VmathVector3 vec, vec_float4 *quad ) { vmathV3StoreXYZ(&vec, quad); } static inline void vmathV3LoadXYZArray_V( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads ) { vmathV3LoadXYZArray(vec0, vec1, vec2, vec3, threeQuads); } static inline void vmathV3StoreXYZArray_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, vec_float4 *threeQuads ) { vmathV3StoreXYZArray(&vec0, &vec1, &vec2, &vec3, threeQuads); } static inline void vmathV3StoreHalfFloats_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, VmathVector3 vec4, VmathVector3 vec5, VmathVector3 vec6, VmathVector3 vec7, vec_ushort8 *threeQuads ) { vmathV3StoreHalfFloats(&vec0, &vec1, &vec2, &vec3, &vec4, &vec5, &vec6, &vec7, threeQuads); } static inline void vmathV3SetX_V( VmathVector3 *result, float _x ) { vmathV3SetX(result, _x); } static inline float vmathV3GetX_V( VmathVector3 vec ) { return vmathV3GetX(&vec); } static inline void vmathV3SetY_V( VmathVector3 *result, float _y ) { vmathV3SetY(result, _y); } static inline float vmathV3GetY_V( VmathVector3 vec ) { return vmathV3GetY(&vec); } static inline void vmathV3SetZ_V( VmathVector3 *result, float _z ) { vmathV3SetZ(result, _z); } static inline float vmathV3GetZ_V( VmathVector3 vec ) { return vmathV3GetZ(&vec); } static inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value ) { vmathV3SetElem(result, idx, value); } static inline float vmathV3GetElem_V( VmathVector3 vec, int idx ) { return vmathV3GetElem(&vec, idx); } static inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Add(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Sub(&result, &vec0, &vec1); return result; } static inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathV3AddP3(&result, &vec, &pnt1); return result; } static inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar ) { VmathVector3 result; vmathV3ScalarMul(&result, &vec, scalar); return result; } static inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar ) { VmathVector3 result; vmathV3ScalarDiv(&result, &vec, scalar); return result; } static inline VmathVector3 vmathV3Neg_V( VmathVector3 vec ) { VmathVector3 result; vmathV3Neg(&result, &vec); return result; } static inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3RecipPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3SqrtPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3RsqrtPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec ) { VmathVector3 result; vmathV3AbsPerElem(&result, &vec); return result; } static inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MaxPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV3MaxElem_V( VmathVector3 vec ) { return vmathV3MaxElem(&vec); } static inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3MinPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV3MinElem_V( VmathVector3 vec ) { return vmathV3MinElem(&vec); } static inline float vmathV3Sum_V( VmathVector3 vec ) { return vmathV3Sum(&vec); } static inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 ) { return vmathV3Dot(&vec0, &vec1); } static inline float vmathV3LengthSqr_V( VmathVector3 vec ) { return vmathV3LengthSqr(&vec); } static inline float vmathV3Length_V( VmathVector3 vec ) { return vmathV3Length(&vec); } static inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec ) { VmathVector3 result; vmathV3Normalize(&result, &vec); return result; } static inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 ) { VmathVector3 result; vmathV3Cross(&result, &vec0, &vec1); return result; } static inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 ) { VmathVector3 result; vmathV3Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathV3Print_V( VmathVector3 vec ) { vmathV3Print(&vec); } static inline void vmathV3Prints_V( VmathVector3 vec, const char *name ) { vmathV3Prints(&vec, name); } #endif static inline VmathVector4 vmathV4MakeFromElems_V( float _x, float _y, float _z, float _w ) { VmathVector4 result; vmathV4MakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float _w ) { VmathVector4 result; vmathV4MakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec ) { VmathVector4 result; vmathV4MakeFromV3(&result, &vec); return result; } static inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt ) { VmathVector4 result; vmathV4MakeFromP3(&result, &pnt); return result; } static inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat ) { VmathVector4 result; vmathV4MakeFromQ(&result, &quat); return result; } static inline VmathVector4 vmathV4MakeFromScalar_V( float scalar ) { VmathVector4 result; vmathV4MakeFromScalar(&result, scalar); return result; } static inline VmathVector4 vmathV4MakeFrom128_V( vec_float4 vf4 ) { VmathVector4 result; vmathV4MakeFrom128(&result, vf4); return result; } static inline VmathVector4 vmathV4MakeXAxis_V( ) { VmathVector4 result; vmathV4MakeXAxis(&result); return result; } static inline VmathVector4 vmathV4MakeYAxis_V( ) { VmathVector4 result; vmathV4MakeYAxis(&result); return result; } static inline VmathVector4 vmathV4MakeZAxis_V( ) { VmathVector4 result; vmathV4MakeZAxis(&result); return result; } static inline VmathVector4 vmathV4MakeWAxis_V( ) { VmathVector4 result; vmathV4MakeWAxis(&result); return result; } static inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 ) { VmathVector4 result; vmathV4Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline vec_float4 vmathV4Get128_V( VmathVector4 vec ) { return vmathV4Get128(&vec); } static inline void vmathV4StoreHalfFloats_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3, vec_ushort8 *twoQuads ) { vmathV4StoreHalfFloats(&vec0, &vec1, &vec2, &vec3, twoQuads); } static inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec ) { vmathV4SetXYZ(result, &vec); } static inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec ) { VmathVector3 result; vmathV4GetXYZ(&result, &vec); return result; } static inline void vmathV4SetX_V( VmathVector4 *result, float _x ) { vmathV4SetX(result, _x); } static inline float vmathV4GetX_V( VmathVector4 vec ) { return vmathV4GetX(&vec); } static inline void vmathV4SetY_V( VmathVector4 *result, float _y ) { vmathV4SetY(result, _y); } static inline float vmathV4GetY_V( VmathVector4 vec ) { return vmathV4GetY(&vec); } static inline void vmathV4SetZ_V( VmathVector4 *result, float _z ) { vmathV4SetZ(result, _z); } static inline float vmathV4GetZ_V( VmathVector4 vec ) { return vmathV4GetZ(&vec); } static inline void vmathV4SetW_V( VmathVector4 *result, float _w ) { vmathV4SetW(result, _w); } static inline float vmathV4GetW_V( VmathVector4 vec ) { return vmathV4GetW(&vec); } static inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value ) { vmathV4SetElem(result, idx, value); } static inline float vmathV4GetElem_V( VmathVector4 vec, int idx ) { return vmathV4GetElem(&vec, idx); } static inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Add(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4Sub(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar ) { VmathVector4 result; vmathV4ScalarMul(&result, &vec, scalar); return result; } static inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar ) { VmathVector4 result; vmathV4ScalarDiv(&result, &vec, scalar); return result; } static inline VmathVector4 vmathV4Neg_V( VmathVector4 vec ) { VmathVector4 result; vmathV4Neg(&result, &vec); return result; } static inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4RecipPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4SqrtPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4RsqrtPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec ) { VmathVector4 result; vmathV4AbsPerElem(&result, &vec); return result; } static inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MaxPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV4MaxElem_V( VmathVector4 vec ) { return vmathV4MaxElem(&vec); } static inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ) { VmathVector4 result; vmathV4MinPerElem(&result, &vec0, &vec1); return result; } static inline float vmathV4MinElem_V( VmathVector4 vec ) { return vmathV4MinElem(&vec); } static inline float vmathV4Sum_V( VmathVector4 vec ) { return vmathV4Sum(&vec); } static inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 ) { return vmathV4Dot(&vec0, &vec1); } static inline float vmathV4LengthSqr_V( VmathVector4 vec ) { return vmathV4LengthSqr(&vec); } static inline float vmathV4Length_V( VmathVector4 vec ) { return vmathV4Length(&vec); } static inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec ) { VmathVector4 result; vmathV4Normalize(&result, &vec); return result; } static inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 ) { VmathVector4 result; vmathV4Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathV4Print_V( VmathVector4 vec ) { vmathV4Print(&vec); } static inline void vmathV4Prints_V( VmathVector4 vec, const char *name ) { vmathV4Prints(&vec, name); } #endif static inline VmathPoint3 vmathP3MakeFromElems_V( float _x, float _y, float _z ) { VmathPoint3 result; vmathP3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec ) { VmathPoint3 result; vmathP3MakeFromV3(&result, &vec); return result; } static inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar ) { VmathPoint3 result; vmathP3MakeFromScalar(&result, scalar); return result; } static inline VmathPoint3 vmathP3MakeFrom128_V( vec_float4 vf4 ) { VmathPoint3 result; vmathP3MakeFrom128(&result, vf4); return result; } static inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3Lerp(&result, t, &pnt0, &pnt1); return result; } static inline vec_float4 vmathP3Get128_V( VmathPoint3 pnt ) { return vmathP3Get128(&pnt); } static inline void vmathP3StoreXYZ_V( VmathPoint3 pnt, vec_float4 *quad ) { vmathP3StoreXYZ(&pnt, quad); } static inline void vmathP3LoadXYZArray_V( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads ) { vmathP3LoadXYZArray(pnt0, pnt1, pnt2, pnt3, threeQuads); } static inline void vmathP3StoreXYZArray_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, vec_float4 *threeQuads ) { vmathP3StoreXYZArray(&pnt0, &pnt1, &pnt2, &pnt3, threeQuads); } static inline void vmathP3StoreHalfFloats_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, VmathPoint3 pnt4, VmathPoint3 pnt5, VmathPoint3 pnt6, VmathPoint3 pnt7, vec_ushort8 *threeQuads ) { vmathP3StoreHalfFloats(&pnt0, &pnt1, &pnt2, &pnt3, &pnt4, &pnt5, &pnt6, &pnt7, threeQuads); } static inline void vmathP3SetX_V( VmathPoint3 *result, float _x ) { vmathP3SetX(result, _x); } static inline float vmathP3GetX_V( VmathPoint3 pnt ) { return vmathP3GetX(&pnt); } static inline void vmathP3SetY_V( VmathPoint3 *result, float _y ) { vmathP3SetY(result, _y); } static inline float vmathP3GetY_V( VmathPoint3 pnt ) { return vmathP3GetY(&pnt); } static inline void vmathP3SetZ_V( VmathPoint3 *result, float _z ) { vmathP3SetZ(result, _z); } static inline float vmathP3GetZ_V( VmathPoint3 pnt ) { return vmathP3GetZ(&pnt); } static inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value ) { vmathP3SetElem(result, idx, value); } static inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx ) { return vmathP3GetElem(&pnt, idx); } static inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathVector3 result; vmathP3Sub(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec1 ) { VmathPoint3 result; vmathP3AddV3(&result, &pnt, &vec1); return result; } static inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec1 ) { VmathPoint3 result; vmathP3SubV3(&result, &pnt, &vec1); return result; } static inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MulPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3DivPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3RecipPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3SqrtPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3RsqrtPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt ) { VmathPoint3 result; vmathP3AbsPerElem(&result, &pnt); return result; } static inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3CopySignPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MaxPerElem(&result, &pnt0, &pnt1); return result; } static inline float vmathP3MaxElem_V( VmathPoint3 pnt ) { return vmathP3MaxElem(&pnt); } static inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { VmathPoint3 result; vmathP3MinPerElem(&result, &pnt0, &pnt1); return result; } static inline float vmathP3MinElem_V( VmathPoint3 pnt ) { return vmathP3MinElem(&pnt); } static inline float vmathP3Sum_V( VmathPoint3 pnt ) { return vmathP3Sum(&pnt); } static inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal ) { VmathPoint3 result; vmathP3Scale(&result, &pnt, scaleVal); return result; } static inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec ) { VmathPoint3 result; vmathP3NonUniformScale(&result, &pnt, &scaleVec); return result; } static inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec ) { return vmathP3Projection(&pnt, &unitVec); } static inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt ) { return vmathP3DistSqrFromOrigin(&pnt); } static inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt ) { return vmathP3DistFromOrigin(&pnt); } static inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { return vmathP3DistSqr(&pnt0, &pnt1); } static inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ) { return vmathP3Dist(&pnt0, &pnt1); } static inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 ) { VmathPoint3 result; vmathP3Select(&result, &pnt0, &pnt1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathP3Print_V( VmathPoint3 pnt ) { vmathP3Print(&pnt); } static inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name ) { vmathP3Prints(&pnt, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/vec_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_SOA_C_H #define _VECTORMATH_VEC_SOA_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for shuffles, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_SHUF_X 0x00010203 #define _VECTORMATH_SHUF_Y 0x04050607 #define _VECTORMATH_SHUF_Z 0x08090a0b #define _VECTORMATH_SHUF_W 0x0c0d0e0f #define _VECTORMATH_SHUF_A 0x10111213 #define _VECTORMATH_SHUF_B 0x14151617 #define _VECTORMATH_SHUF_C 0x18191a1b #define _VECTORMATH_SHUF_D 0x1c1d1e1f #define _VECTORMATH_SHUF_0 0x80808080 #define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_ZDW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZDXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YAWC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XYCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline void vmathSoaV3Copy( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathSoaV3MakeFromElems( VmathSoaVector3 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z ) { result->x = _x; result->y = _y; result->z = _z; } static inline void vmathSoaV3MakeFromP3( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; } static inline void vmathSoaV3MakeFromScalar( VmathSoaVector3 *result, vec_float4 scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; } static inline void vmathSoaV3MakeFromAos( VmathSoaVector3 *result, const VmathVector3 *vec ) { vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_float4 vec128 = vec->vec128; result->x = spu_shuffle( vec128, vec128, shuffle_xxxx ); result->y = spu_shuffle( vec128, vec128, shuffle_yyyy ); result->z = spu_shuffle( vec128, vec128, shuffle_zzzz ); } static inline void vmathSoaV3MakeFrom4Aos( VmathSoaVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( vec0->vec128, vec2->vec128, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( vec1->vec128, vec3->vec128, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( vec0->vec128, vec2->vec128, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( vec1->vec128, vec3->vec128, _VECTORMATH_SHUF_ZCWD ); result->x = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); result->y = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); result->z = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); } static inline void vmathSoaV3MakeXAxis( VmathSoaVector3 *result ) { vmathSoaV3MakeFromElems( result, spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f) ); } static inline void vmathSoaV3MakeYAxis( VmathSoaVector3 *result ) { vmathSoaV3MakeFromElems( result, spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f) ); } static inline void vmathSoaV3MakeZAxis( VmathSoaVector3 *result ) { vmathSoaV3MakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) ); } static inline void vmathSoaV3Lerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { VmathSoaVector3 tmpV3_0, tmpV3_1; vmathSoaV3Sub( &tmpV3_0, vec1, vec0 ); vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathSoaV3Add( result, vec0, &tmpV3_1 ); } static inline void vmathSoaV3Slerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 ) { VmathSoaVector3 tmpV3_0, tmpV3_1; vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = vmathSoaV3Dot( unitVec0, unitVec1 ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = recipf4( sinf4( angle ) ); 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 ); scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask ); vmathSoaV3ScalarMul( &tmpV3_0, unitVec0, scale0 ); vmathSoaV3ScalarMul( &tmpV3_1, unitVec1, scale1 ); vmathSoaV3Add( result, &tmpV3_0, &tmpV3_1 ); } static inline void vmathSoaV3Get4Aos( const VmathSoaVector3 *vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 ) { vec_float4 tmp0, tmp1; tmp0 = spu_shuffle( vec->x, vec->z, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( vec->x, vec->z, _VECTORMATH_SHUF_ZCWD ); vmathV3MakeFrom128( result0, spu_shuffle( tmp0, vec->y, _VECTORMATH_SHUF_XAYB ) ); vmathV3MakeFrom128( result1, spu_shuffle( tmp0, vec->y, _VECTORMATH_SHUF_ZBW0 ) ); vmathV3MakeFrom128( result2, spu_shuffle( tmp1, vec->y, _VECTORMATH_SHUF_XCY0 ) ); vmathV3MakeFrom128( result3, spu_shuffle( tmp1, vec->y, _VECTORMATH_SHUF_ZDW0 ) ); } static inline void vmathSoaV3LoadXYZArray( VmathSoaVector3 *vec, const vec_float4 *threeQuads ) { vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyxy = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_XYCD ); zxzx = spu_shuffle( zxyz, xyzx, _VECTORMATH_SHUF_XYCD ); yzyz = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_XYCD ); vmathSoaV3SetX( vec, spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XDZB ) ); vmathSoaV3SetY( vec, spu_shuffle( xyxy, yzyz, _VECTORMATH_SHUF_YAWC ) ); vmathSoaV3SetZ( vec, spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_ZBXD ) ); } static inline void vmathSoaV3StoreXYZArray( const VmathSoaVector3 *vec, vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz; xyxy = spu_shuffle( vec->x, vec->y, _VECTORMATH_SHUF_XAZC ); zxzx = spu_shuffle( vec->z, vec->x, _VECTORMATH_SHUF_ZDXB ); yzyz = spu_shuffle( vec->y, vec->z, _VECTORMATH_SHUF_YBWD ); xyzx = spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XYCD ); yzxy = spu_shuffle( yzyz, xyxy, _VECTORMATH_SHUF_XYCD ); zxyz = spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_XYCD ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } static inline void vmathSoaV3StoreHalfFloats( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_ushort8 *threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; vmathSoaV3StoreXYZArray( vec0, xyz0 ); vmathSoaV3StoreXYZArray( vec1, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } static inline void vmathSoaV3SetX( VmathSoaVector3 *result, vec_float4 _x ) { result->x = _x; } static inline vec_float4 vmathSoaV3GetX( const VmathSoaVector3 *vec ) { return vec->x; } static inline void vmathSoaV3SetY( VmathSoaVector3 *result, vec_float4 _y ) { result->y = _y; } static inline vec_float4 vmathSoaV3GetY( const VmathSoaVector3 *vec ) { return vec->y; } static inline void vmathSoaV3SetZ( VmathSoaVector3 *result, vec_float4 _z ) { result->z = _z; } static inline vec_float4 vmathSoaV3GetZ( const VmathSoaVector3 *vec ) { return vec->z; } static inline void vmathSoaV3SetElem( VmathSoaVector3 *result, int idx, vec_float4 value ) { *(&result->x + idx) = value; } static inline vec_float4 vmathSoaV3GetElem( const VmathSoaVector3 *vec, int idx ) { return *(&vec->x + idx); } static inline void vmathSoaV3Add( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = spu_add( vec0->x, vec1->x ); result->y = spu_add( vec0->y, vec1->y ); result->z = spu_add( vec0->z, vec1->z ); } static inline void vmathSoaV3Sub( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = spu_sub( vec0->x, vec1->x ); result->y = spu_sub( vec0->y, vec1->y ); result->z = spu_sub( vec0->z, vec1->z ); } static inline void vmathSoaV3AddP3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec, const VmathSoaPoint3 *pnt1 ) { result->x = spu_add( vec->x, pnt1->x ); result->y = spu_add( vec->y, pnt1->y ); result->z = spu_add( vec->z, pnt1->z ); } static inline void vmathSoaV3ScalarMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar ) { result->x = spu_mul( vec->x, scalar ); result->y = spu_mul( vec->y, scalar ); result->z = spu_mul( vec->z, scalar ); } static inline void vmathSoaV3ScalarDiv( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar ) { result->x = divf4( vec->x, scalar ); result->y = divf4( vec->y, scalar ); result->z = divf4( vec->z, scalar ); } static inline void vmathSoaV3Neg( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = negatef4( vec->x ); result->y = negatef4( vec->y ); result->z = negatef4( vec->z ); } static inline void vmathSoaV3MulPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = spu_mul( vec0->x, vec1->x ); result->y = spu_mul( vec0->y, vec1->y ); result->z = spu_mul( vec0->z, vec1->z ); } static inline void vmathSoaV3DivPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = divf4( vec0->x, vec1->x ); result->y = divf4( vec0->y, vec1->y ); result->z = divf4( vec0->z, vec1->z ); } static inline void vmathSoaV3RecipPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = recipf4( vec->x ); result->y = recipf4( vec->y ); result->z = recipf4( vec->z ); } static inline void vmathSoaV3SqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = sqrtf4( vec->x ); result->y = sqrtf4( vec->y ); result->z = sqrtf4( vec->z ); } static inline void vmathSoaV3RsqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = rsqrtf4( vec->x ); result->y = rsqrtf4( vec->y ); result->z = rsqrtf4( vec->z ); } static inline void vmathSoaV3AbsPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { result->x = fabsf4( vec->x ); result->y = fabsf4( vec->y ); result->z = fabsf4( vec->z ); } static inline void vmathSoaV3CopySignPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = copysignf4( vec0->x, vec1->x ); result->y = copysignf4( vec0->y, vec1->y ); result->z = copysignf4( vec0->z, vec1->z ); } static inline void vmathSoaV3MaxPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = fmaxf4( vec0->x, vec1->x ); result->y = fmaxf4( vec0->y, vec1->y ); result->z = fmaxf4( vec0->z, vec1->z ); } static inline vec_float4 vmathSoaV3MaxElem( const VmathSoaVector3 *vec ) { vec_float4 result; result = fmaxf4( vec->x, vec->y ); result = fmaxf4( vec->z, result ); return result; } static inline void vmathSoaV3MinPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { result->x = fminf4( vec0->x, vec1->x ); result->y = fminf4( vec0->y, vec1->y ); result->z = fminf4( vec0->z, vec1->z ); } static inline vec_float4 vmathSoaV3MinElem( const VmathSoaVector3 *vec ) { vec_float4 result; result = fminf4( vec->x, vec->y ); result = fminf4( vec->z, result ); return result; } static inline vec_float4 vmathSoaV3Sum( const VmathSoaVector3 *vec ) { vec_float4 result; result = spu_add( vec->x, vec->y ); result = spu_add( result, vec->z ); return result; } static inline vec_float4 vmathSoaV3Dot( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { vec_float4 result; result = spu_mul( vec0->x, vec1->x ); result = spu_add( result, spu_mul( vec0->y, vec1->y ) ); result = spu_add( result, spu_mul( vec0->z, vec1->z ) ); return result; } static inline vec_float4 vmathSoaV3LengthSqr( const VmathSoaVector3 *vec ) { vec_float4 result; result = spu_mul( vec->x, vec->x ); result = spu_add( result, spu_mul( vec->y, vec->y ) ); result = spu_add( result, spu_mul( vec->z, vec->z ) ); return result; } static inline vec_float4 vmathSoaV3Length( const VmathSoaVector3 *vec ) { return sqrtf4( vmathSoaV3LengthSqr( vec ) ); } static inline void vmathSoaV3Normalize( VmathSoaVector3 *result, const VmathSoaVector3 *vec ) { vec_float4 lenSqr, lenInv; lenSqr = vmathSoaV3LengthSqr( vec ); lenInv = rsqrtf4( lenSqr ); result->x = spu_mul( vec->x, lenInv ); result->y = spu_mul( vec->y, lenInv ); result->z = spu_mul( vec->z, lenInv ); } static inline void vmathSoaV3Cross( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ) { vec_float4 tmpX, tmpY, tmpZ; tmpX = spu_sub( spu_mul( vec0->y, vec1->z ), spu_mul( vec0->z, vec1->y ) ); tmpY = spu_sub( spu_mul( vec0->z, vec1->x ), spu_mul( vec0->x, vec1->z ) ); tmpZ = spu_sub( spu_mul( vec0->x, vec1->y ), spu_mul( vec0->y, vec1->x ) ); vmathSoaV3MakeFromElems( result, tmpX, tmpY, tmpZ ); } static inline void vmathSoaV3Select( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_uint4 select1 ) { result->x = spu_sel( vec0->x, vec1->x, select1 ); result->y = spu_sel( vec0->y, vec1->y, select1 ); result->z = spu_sel( vec0->z, vec1->z, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaV3Print( const VmathSoaVector3 *vec ) { VmathVector3 vec0, vec1, vec2, vec3; vmathSoaV3Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathV3Print( &vec0 ); printf("slot 1:\n"); vmathV3Print( &vec1 ); printf("slot 2:\n"); vmathV3Print( &vec2 ); printf("slot 3:\n"); vmathV3Print( &vec3 ); } static inline void vmathSoaV3Prints( const VmathSoaVector3 *vec, const char *name ) { VmathVector3 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vmathSoaV3Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathV3Print( &vec0 ); printf("slot 1:\n"); vmathV3Print( &vec1 ); printf("slot 2:\n"); vmathV3Print( &vec2 ); printf("slot 3:\n"); vmathV3Print( &vec3 ); } #endif static inline void vmathSoaV4Copy( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = vec->w; } static inline void vmathSoaV4MakeFromElems( VmathSoaVector4 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { result->x = _x; result->y = _y; result->z = _z; result->w = _w; } static inline void vmathSoaV4MakeFromV3Scalar( VmathSoaVector4 *result, const VmathSoaVector3 *xyz, vec_float4 _w ) { vmathSoaV4SetXYZ( result, xyz ); vmathSoaV4SetW( result, _w ); } static inline void vmathSoaV4MakeFromV3( VmathSoaVector4 *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; result->w = spu_splats(0.0f); } static inline void vmathSoaV4MakeFromP3( VmathSoaVector4 *result, const VmathSoaPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; result->w = spu_splats(1.0f); } static inline void vmathSoaV4MakeFromQ( VmathSoaVector4 *result, const VmathSoaQuat *quat ) { result->x = quat->x; result->y = quat->y; result->z = quat->z; result->w = quat->w; } static inline void vmathSoaV4MakeFromScalar( VmathSoaVector4 *result, vec_float4 scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; result->w = scalar; } static inline void vmathSoaV4MakeFromAos( VmathSoaVector4 *result, const VmathVector4 *vec ) { vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); vec_float4 vec128 = vec->vec128; result->x = spu_shuffle( vec128, vec128, shuffle_xxxx ); result->y = spu_shuffle( vec128, vec128, shuffle_yyyy ); result->z = spu_shuffle( vec128, vec128, shuffle_zzzz ); result->w = spu_shuffle( vec128, vec128, shuffle_wwww ); } static inline void vmathSoaV4MakeFrom4Aos( VmathSoaVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( vec0->vec128, vec2->vec128, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( vec1->vec128, vec3->vec128, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( vec0->vec128, vec2->vec128, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( vec1->vec128, vec3->vec128, _VECTORMATH_SHUF_ZCWD ); result->x = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); result->y = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); result->z = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); result->w = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ); } static inline void vmathSoaV4MakeXAxis( VmathSoaVector4 *result ) { vmathSoaV4MakeFromElems( result, spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ); } static inline void vmathSoaV4MakeYAxis( VmathSoaVector4 *result ) { vmathSoaV4MakeFromElems( result, spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f) ); } static inline void vmathSoaV4MakeZAxis( VmathSoaVector4 *result ) { vmathSoaV4MakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f) ); } static inline void vmathSoaV4MakeWAxis( VmathSoaVector4 *result ) { vmathSoaV4MakeFromElems( result, spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) ); } static inline void vmathSoaV4Lerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { VmathSoaVector4 tmpV4_0, tmpV4_1; vmathSoaV4Sub( &tmpV4_0, vec1, vec0 ); vmathSoaV4ScalarMul( &tmpV4_1, &tmpV4_0, t ); vmathSoaV4Add( result, vec0, &tmpV4_1 ); } static inline void vmathSoaV4Slerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *unitVec0, const VmathSoaVector4 *unitVec1 ) { VmathSoaVector4 tmpV4_0, tmpV4_1; vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = vmathSoaV4Dot( unitVec0, unitVec1 ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = recipf4( sinf4( angle ) ); 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 ); scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask ); vmathSoaV4ScalarMul( &tmpV4_0, unitVec0, scale0 ); vmathSoaV4ScalarMul( &tmpV4_1, unitVec1, scale1 ); vmathSoaV4Add( result, &tmpV4_0, &tmpV4_1 ); } static inline void vmathSoaV4Get4Aos( const VmathSoaVector4 *vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( vec->x, vec->z, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( vec->y, vec->w, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( vec->x, vec->z, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( vec->y, vec->w, _VECTORMATH_SHUF_ZCWD ); vmathV4MakeFrom128( result0, spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ) ); vmathV4MakeFrom128( result1, spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ) ); vmathV4MakeFrom128( result2, spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ) ); vmathV4MakeFrom128( result3, spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ) ); } static inline void vmathSoaV4StoreHalfFloats( const VmathSoaVector4 *vec, vec_ushort8 *twoQuads ) { VmathVector4 v0, v1, v2, v3; vmathSoaV4Get4Aos( vec, &v0, &v1, &v2, &v3 ); twoQuads[0] = _vmath2VfToHalfFloats(v0.vec128, v1.vec128); twoQuads[1] = _vmath2VfToHalfFloats(v2.vec128, v3.vec128); } static inline void vmathSoaV4SetXYZ( VmathSoaVector4 *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathSoaV4GetXYZ( VmathSoaVector3 *result, const VmathSoaVector4 *vec ) { vmathSoaV3MakeFromElems( result, vec->x, vec->y, vec->z ); } static inline void vmathSoaV4SetX( VmathSoaVector4 *result, vec_float4 _x ) { result->x = _x; } static inline vec_float4 vmathSoaV4GetX( const VmathSoaVector4 *vec ) { return vec->x; } static inline void vmathSoaV4SetY( VmathSoaVector4 *result, vec_float4 _y ) { result->y = _y; } static inline vec_float4 vmathSoaV4GetY( const VmathSoaVector4 *vec ) { return vec->y; } static inline void vmathSoaV4SetZ( VmathSoaVector4 *result, vec_float4 _z ) { result->z = _z; } static inline vec_float4 vmathSoaV4GetZ( const VmathSoaVector4 *vec ) { return vec->z; } static inline void vmathSoaV4SetW( VmathSoaVector4 *result, vec_float4 _w ) { result->w = _w; } static inline vec_float4 vmathSoaV4GetW( const VmathSoaVector4 *vec ) { return vec->w; } static inline void vmathSoaV4SetElem( VmathSoaVector4 *result, int idx, vec_float4 value ) { *(&result->x + idx) = value; } static inline vec_float4 vmathSoaV4GetElem( const VmathSoaVector4 *vec, int idx ) { return *(&vec->x + idx); } static inline void vmathSoaV4Add( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = spu_add( vec0->x, vec1->x ); result->y = spu_add( vec0->y, vec1->y ); result->z = spu_add( vec0->z, vec1->z ); result->w = spu_add( vec0->w, vec1->w ); } static inline void vmathSoaV4Sub( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = spu_sub( vec0->x, vec1->x ); result->y = spu_sub( vec0->y, vec1->y ); result->z = spu_sub( vec0->z, vec1->z ); result->w = spu_sub( vec0->w, vec1->w ); } static inline void vmathSoaV4ScalarMul( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar ) { result->x = spu_mul( vec->x, scalar ); result->y = spu_mul( vec->y, scalar ); result->z = spu_mul( vec->z, scalar ); result->w = spu_mul( vec->w, scalar ); } static inline void vmathSoaV4ScalarDiv( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar ) { result->x = divf4( vec->x, scalar ); result->y = divf4( vec->y, scalar ); result->z = divf4( vec->z, scalar ); result->w = divf4( vec->w, scalar ); } static inline void vmathSoaV4Neg( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = negatef4( vec->x ); result->y = negatef4( vec->y ); result->z = negatef4( vec->z ); result->w = negatef4( vec->w ); } static inline void vmathSoaV4MulPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = spu_mul( vec0->x, vec1->x ); result->y = spu_mul( vec0->y, vec1->y ); result->z = spu_mul( vec0->z, vec1->z ); result->w = spu_mul( vec0->w, vec1->w ); } static inline void vmathSoaV4DivPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = divf4( vec0->x, vec1->x ); result->y = divf4( vec0->y, vec1->y ); result->z = divf4( vec0->z, vec1->z ); result->w = divf4( vec0->w, vec1->w ); } static inline void vmathSoaV4RecipPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = recipf4( vec->x ); result->y = recipf4( vec->y ); result->z = recipf4( vec->z ); result->w = recipf4( vec->w ); } static inline void vmathSoaV4SqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = sqrtf4( vec->x ); result->y = sqrtf4( vec->y ); result->z = sqrtf4( vec->z ); result->w = sqrtf4( vec->w ); } static inline void vmathSoaV4RsqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = rsqrtf4( vec->x ); result->y = rsqrtf4( vec->y ); result->z = rsqrtf4( vec->z ); result->w = rsqrtf4( vec->w ); } static inline void vmathSoaV4AbsPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { result->x = fabsf4( vec->x ); result->y = fabsf4( vec->y ); result->z = fabsf4( vec->z ); result->w = fabsf4( vec->w ); } static inline void vmathSoaV4CopySignPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = copysignf4( vec0->x, vec1->x ); result->y = copysignf4( vec0->y, vec1->y ); result->z = copysignf4( vec0->z, vec1->z ); result->w = copysignf4( vec0->w, vec1->w ); } static inline void vmathSoaV4MaxPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = fmaxf4( vec0->x, vec1->x ); result->y = fmaxf4( vec0->y, vec1->y ); result->z = fmaxf4( vec0->z, vec1->z ); result->w = fmaxf4( vec0->w, vec1->w ); } static inline vec_float4 vmathSoaV4MaxElem( const VmathSoaVector4 *vec ) { vec_float4 result; result = fmaxf4( vec->x, vec->y ); result = fmaxf4( vec->z, result ); result = fmaxf4( vec->w, result ); return result; } static inline void vmathSoaV4MinPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { result->x = fminf4( vec0->x, vec1->x ); result->y = fminf4( vec0->y, vec1->y ); result->z = fminf4( vec0->z, vec1->z ); result->w = fminf4( vec0->w, vec1->w ); } static inline vec_float4 vmathSoaV4MinElem( const VmathSoaVector4 *vec ) { vec_float4 result; result = fminf4( vec->x, vec->y ); result = fminf4( vec->z, result ); result = fminf4( vec->w, result ); return result; } static inline vec_float4 vmathSoaV4Sum( const VmathSoaVector4 *vec ) { vec_float4 result; result = spu_add( vec->x, vec->y ); result = spu_add( result, vec->z ); result = spu_add( result, vec->w ); return result; } static inline vec_float4 vmathSoaV4Dot( const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ) { vec_float4 result; result = spu_mul( vec0->x, vec1->x ); result = spu_add( result, spu_mul( vec0->y, vec1->y ) ); result = spu_add( result, spu_mul( vec0->z, vec1->z ) ); result = spu_add( result, spu_mul( vec0->w, vec1->w ) ); return result; } static inline vec_float4 vmathSoaV4LengthSqr( const VmathSoaVector4 *vec ) { vec_float4 result; result = spu_mul( vec->x, vec->x ); result = spu_add( result, spu_mul( vec->y, vec->y ) ); result = spu_add( result, spu_mul( vec->z, vec->z ) ); result = spu_add( result, spu_mul( vec->w, vec->w ) ); return result; } static inline vec_float4 vmathSoaV4Length( const VmathSoaVector4 *vec ) { return sqrtf4( vmathSoaV4LengthSqr( vec ) ); } static inline void vmathSoaV4Normalize( VmathSoaVector4 *result, const VmathSoaVector4 *vec ) { vec_float4 lenSqr, lenInv; lenSqr = vmathSoaV4LengthSqr( vec ); lenInv = rsqrtf4( lenSqr ); result->x = spu_mul( vec->x, lenInv ); result->y = spu_mul( vec->y, lenInv ); result->z = spu_mul( vec->z, lenInv ); result->w = spu_mul( vec->w, lenInv ); } static inline void vmathSoaV4Select( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1, vec_uint4 select1 ) { result->x = spu_sel( vec0->x, vec1->x, select1 ); result->y = spu_sel( vec0->y, vec1->y, select1 ); result->z = spu_sel( vec0->z, vec1->z, select1 ); result->w = spu_sel( vec0->w, vec1->w, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaV4Print( const VmathSoaVector4 *vec ) { VmathVector4 vec0, vec1, vec2, vec3; vmathSoaV4Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathV4Print( &vec0 ); printf("slot 1:\n"); vmathV4Print( &vec1 ); printf("slot 2:\n"); vmathV4Print( &vec2 ); printf("slot 3:\n"); vmathV4Print( &vec3 ); } static inline void vmathSoaV4Prints( const VmathSoaVector4 *vec, const char *name ) { VmathVector4 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vmathSoaV4Get4Aos( vec, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathV4Print( &vec0 ); printf("slot 1:\n"); vmathV4Print( &vec1 ); printf("slot 2:\n"); vmathV4Print( &vec2 ); printf("slot 3:\n"); vmathV4Print( &vec3 ); } #endif static inline void vmathSoaP3Copy( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = pnt->x; result->y = pnt->y; result->z = pnt->z; } static inline void vmathSoaP3MakeFromElems( VmathSoaPoint3 *result, vec_float4 _x, vec_float4 _y, vec_float4 _z ) { result->x = _x; result->y = _y; result->z = _z; } static inline void vmathSoaP3MakeFromV3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec ) { result->x = vec->x; result->y = vec->y; result->z = vec->z; } static inline void vmathSoaP3MakeFromScalar( VmathSoaPoint3 *result, vec_float4 scalar ) { result->x = scalar; result->y = scalar; result->z = scalar; } static inline void vmathSoaP3MakeFromAos( VmathSoaPoint3 *result, const VmathPoint3 *pnt ) { vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_float4 vec128 = pnt->vec128; result->x = spu_shuffle( vec128, vec128, shuffle_xxxx ); result->y = spu_shuffle( vec128, vec128, shuffle_yyyy ); result->z = spu_shuffle( vec128, vec128, shuffle_zzzz ); } static inline void vmathSoaP3MakeFrom4Aos( VmathSoaPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( pnt0->vec128, pnt2->vec128, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( pnt1->vec128, pnt3->vec128, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( pnt0->vec128, pnt2->vec128, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( pnt1->vec128, pnt3->vec128, _VECTORMATH_SHUF_ZCWD ); result->x = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); result->y = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); result->z = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); } static inline void vmathSoaP3Lerp( VmathSoaPoint3 *result, vec_float4 t, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { VmathSoaVector3 tmpV3_0, tmpV3_1; vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 ); vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, t ); vmathSoaP3AddV3( result, pnt0, &tmpV3_1 ); } static inline void vmathSoaP3Get4Aos( const VmathSoaPoint3 *pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 ) { vec_float4 tmp0, tmp1; tmp0 = spu_shuffle( pnt->x, pnt->z, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( pnt->x, pnt->z, _VECTORMATH_SHUF_ZCWD ); vmathP3MakeFrom128( result0, spu_shuffle( tmp0, pnt->y, _VECTORMATH_SHUF_XAYB ) ); vmathP3MakeFrom128( result1, spu_shuffle( tmp0, pnt->y, _VECTORMATH_SHUF_ZBW0 ) ); vmathP3MakeFrom128( result2, spu_shuffle( tmp1, pnt->y, _VECTORMATH_SHUF_XCY0 ) ); vmathP3MakeFrom128( result3, spu_shuffle( tmp1, pnt->y, _VECTORMATH_SHUF_ZDW0 ) ); } static inline void vmathSoaP3LoadXYZArray( VmathSoaPoint3 *vec, const vec_float4 *threeQuads ) { vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyxy = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_XYCD ); zxzx = spu_shuffle( zxyz, xyzx, _VECTORMATH_SHUF_XYCD ); yzyz = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_XYCD ); vmathSoaP3SetX( vec, spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XDZB ) ); vmathSoaP3SetY( vec, spu_shuffle( xyxy, yzyz, _VECTORMATH_SHUF_YAWC ) ); vmathSoaP3SetZ( vec, spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_ZBXD ) ); } static inline void vmathSoaP3StoreXYZArray( const VmathSoaPoint3 *vec, vec_float4 *threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz; xyxy = spu_shuffle( vec->x, vec->y, _VECTORMATH_SHUF_XAZC ); zxzx = spu_shuffle( vec->z, vec->x, _VECTORMATH_SHUF_ZDXB ); yzyz = spu_shuffle( vec->y, vec->z, _VECTORMATH_SHUF_YBWD ); xyzx = spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XYCD ); yzxy = spu_shuffle( yzyz, xyxy, _VECTORMATH_SHUF_XYCD ); zxyz = spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_XYCD ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } static inline void vmathSoaP3StoreHalfFloats( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_ushort8 *threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; vmathSoaP3StoreXYZArray( pnt0, xyz0 ); vmathSoaP3StoreXYZArray( pnt1, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } static inline void vmathSoaP3SetX( VmathSoaPoint3 *result, vec_float4 _x ) { result->x = _x; } static inline vec_float4 vmathSoaP3GetX( const VmathSoaPoint3 *pnt ) { return pnt->x; } static inline void vmathSoaP3SetY( VmathSoaPoint3 *result, vec_float4 _y ) { result->y = _y; } static inline vec_float4 vmathSoaP3GetY( const VmathSoaPoint3 *pnt ) { return pnt->y; } static inline void vmathSoaP3SetZ( VmathSoaPoint3 *result, vec_float4 _z ) { result->z = _z; } static inline vec_float4 vmathSoaP3GetZ( const VmathSoaPoint3 *pnt ) { return pnt->z; } static inline void vmathSoaP3SetElem( VmathSoaPoint3 *result, int idx, vec_float4 value ) { *(&result->x + idx) = value; } static inline vec_float4 vmathSoaP3GetElem( const VmathSoaPoint3 *pnt, int idx ) { return *(&pnt->x + idx); } static inline void vmathSoaP3Sub( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = spu_sub( pnt0->x, pnt1->x ); result->y = spu_sub( pnt0->y, pnt1->y ); result->z = spu_sub( pnt0->z, pnt1->z ); } static inline void vmathSoaP3AddV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec1 ) { result->x = spu_add( pnt->x, vec1->x ); result->y = spu_add( pnt->y, vec1->y ); result->z = spu_add( pnt->z, vec1->z ); } static inline void vmathSoaP3SubV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec1 ) { result->x = spu_sub( pnt->x, vec1->x ); result->y = spu_sub( pnt->y, vec1->y ); result->z = spu_sub( pnt->z, vec1->z ); } static inline void vmathSoaP3MulPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = spu_mul( pnt0->x, pnt1->x ); result->y = spu_mul( pnt0->y, pnt1->y ); result->z = spu_mul( pnt0->z, pnt1->z ); } static inline void vmathSoaP3DivPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = divf4( pnt0->x, pnt1->x ); result->y = divf4( pnt0->y, pnt1->y ); result->z = divf4( pnt0->z, pnt1->z ); } static inline void vmathSoaP3RecipPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = recipf4( pnt->x ); result->y = recipf4( pnt->y ); result->z = recipf4( pnt->z ); } static inline void vmathSoaP3SqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = sqrtf4( pnt->x ); result->y = sqrtf4( pnt->y ); result->z = sqrtf4( pnt->z ); } static inline void vmathSoaP3RsqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = rsqrtf4( pnt->x ); result->y = rsqrtf4( pnt->y ); result->z = rsqrtf4( pnt->z ); } static inline void vmathSoaP3AbsPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ) { result->x = fabsf4( pnt->x ); result->y = fabsf4( pnt->y ); result->z = fabsf4( pnt->z ); } static inline void vmathSoaP3CopySignPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = copysignf4( pnt0->x, pnt1->x ); result->y = copysignf4( pnt0->y, pnt1->y ); result->z = copysignf4( pnt0->z, pnt1->z ); } static inline void vmathSoaP3MaxPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = fmaxf4( pnt0->x, pnt1->x ); result->y = fmaxf4( pnt0->y, pnt1->y ); result->z = fmaxf4( pnt0->z, pnt1->z ); } static inline vec_float4 vmathSoaP3MaxElem( const VmathSoaPoint3 *pnt ) { vec_float4 result; result = fmaxf4( pnt->x, pnt->y ); result = fmaxf4( pnt->z, result ); return result; } static inline void vmathSoaP3MinPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { result->x = fminf4( pnt0->x, pnt1->x ); result->y = fminf4( pnt0->y, pnt1->y ); result->z = fminf4( pnt0->z, pnt1->z ); } static inline vec_float4 vmathSoaP3MinElem( const VmathSoaPoint3 *pnt ) { vec_float4 result; result = fminf4( pnt->x, pnt->y ); result = fminf4( pnt->z, result ); return result; } static inline vec_float4 vmathSoaP3Sum( const VmathSoaPoint3 *pnt ) { vec_float4 result; result = spu_add( pnt->x, pnt->y ); result = spu_add( result, pnt->z ); return result; } static inline void vmathSoaP3Scale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, vec_float4 scaleVal ) { VmathSoaPoint3 tmpP3_0; vmathSoaP3MakeFromScalar( &tmpP3_0, scaleVal ); vmathSoaP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline void vmathSoaP3NonUniformScale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *scaleVec ) { VmathSoaPoint3 tmpP3_0; vmathSoaP3MakeFromV3( &tmpP3_0, scaleVec ); vmathSoaP3MulPerElem( result, pnt, &tmpP3_0 ); } static inline vec_float4 vmathSoaP3Projection( const VmathSoaPoint3 *pnt, const VmathSoaVector3 *unitVec ) { vec_float4 result; result = spu_mul( pnt->x, unitVec->x ); result = spu_add( result, spu_mul( pnt->y, unitVec->y ) ); result = spu_add( result, spu_mul( pnt->z, unitVec->z ) ); return result; } static inline vec_float4 vmathSoaP3DistSqrFromOrigin( const VmathSoaPoint3 *pnt ) { VmathSoaVector3 tmpV3_0; vmathSoaV3MakeFromP3( &tmpV3_0, pnt ); return vmathSoaV3LengthSqr( &tmpV3_0 ); } static inline vec_float4 vmathSoaP3DistFromOrigin( const VmathSoaPoint3 *pnt ) { VmathSoaVector3 tmpV3_0; vmathSoaV3MakeFromP3( &tmpV3_0, pnt ); return vmathSoaV3Length( &tmpV3_0 ); } static inline vec_float4 vmathSoaP3DistSqr( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { VmathSoaVector3 tmpV3_0; vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathSoaV3LengthSqr( &tmpV3_0 ); } static inline vec_float4 vmathSoaP3Dist( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ) { VmathSoaVector3 tmpV3_0; vmathSoaP3Sub( &tmpV3_0, pnt1, pnt0 ); return vmathSoaV3Length( &tmpV3_0 ); } static inline void vmathSoaP3Select( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_uint4 select1 ) { result->x = spu_sel( pnt0->x, pnt1->x, select1 ); result->y = spu_sel( pnt0->y, pnt1->y, select1 ); result->z = spu_sel( pnt0->z, pnt1->z, select1 ); } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaP3Print( const VmathSoaPoint3 *pnt ) { VmathPoint3 vec0, vec1, vec2, vec3; vmathSoaP3Get4Aos( pnt, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathP3Print( &vec0 ); printf("slot 1:\n"); vmathP3Print( &vec1 ); printf("slot 2:\n"); vmathP3Print( &vec2 ); printf("slot 3:\n"); vmathP3Print( &vec3 ); } static inline void vmathSoaP3Prints( const VmathSoaPoint3 *pnt, const char *name ) { VmathPoint3 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vmathSoaP3Get4Aos( pnt, &vec0, &vec1, &vec2, &vec3 ); printf("slot 0:\n"); vmathP3Print( &vec0 ); printf("slot 1:\n"); vmathP3Print( &vec1 ); printf("slot 2:\n"); vmathP3Print( &vec2 ); printf("slot 3:\n"); vmathP3Print( &vec3 ); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/vec_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_SOA_V_C_H #define _VECTORMATH_VEC_SOA_V_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*----------------------------------------------------------------------------- * Constants * for shuffles, words are labeled [x,y,z,w] [a,b,c,d] */ #define _VECTORMATH_SHUF_X 0x00010203 #define _VECTORMATH_SHUF_Y 0x04050607 #define _VECTORMATH_SHUF_Z 0x08090a0b #define _VECTORMATH_SHUF_W 0x0c0d0e0f #define _VECTORMATH_SHUF_A 0x10111213 #define _VECTORMATH_SHUF_B 0x14151617 #define _VECTORMATH_SHUF_C 0x18191a1b #define _VECTORMATH_SHUF_D 0x1c1d1e1f #define _VECTORMATH_SHUF_0 0x80808080 #define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_ZDW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZDXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YAWC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XYCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SLERP_TOL 0.999f /*----------------------------------------------------------------------------- * Definitions */ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif static inline VmathSoaVector3 vmathSoaV3MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z ) { VmathSoaVector3 result; vmathSoaV3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathSoaVector3 vmathSoaV3MakeFromP3_V( VmathSoaPoint3 pnt ) { VmathSoaVector3 result; vmathSoaV3MakeFromP3(&result, &pnt); return result; } static inline VmathSoaVector3 vmathSoaV3MakeFromScalar_V( vec_float4 scalar ) { VmathSoaVector3 result; vmathSoaV3MakeFromScalar(&result, scalar); return result; } static inline VmathSoaVector3 vmathSoaV3MakeFromAos_V( VmathVector3 vec ) { VmathSoaVector3 result; vmathSoaV3MakeFromAos(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3MakeFrom4Aos_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3 ) { VmathSoaVector3 result; vmathSoaV3MakeFrom4Aos(&result, &vec0, &vec1, &vec2, &vec3); return result; } static inline VmathSoaVector3 vmathSoaV3MakeXAxis_V( ) { VmathSoaVector3 result; vmathSoaV3MakeXAxis(&result); return result; } static inline VmathSoaVector3 vmathSoaV3MakeYAxis_V( ) { VmathSoaVector3 result; vmathSoaV3MakeYAxis(&result); return result; } static inline VmathSoaVector3 vmathSoaV3MakeZAxis_V( ) { VmathSoaVector3 result; vmathSoaV3MakeZAxis(&result); return result; } static inline VmathSoaVector3 vmathSoaV3Lerp_V( vec_float4 t, VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3Slerp_V( vec_float4 t, VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 ) { VmathSoaVector3 result; vmathSoaV3Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline void vmathSoaV3Get4Aos_V( VmathSoaVector3 vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 ) { vmathSoaV3Get4Aos(&vec, result0, result1, result2, result3); } static inline void vmathSoaV3LoadXYZArray_V( VmathSoaVector3 *vec, const vec_float4 *threeQuads ) { vmathSoaV3LoadXYZArray(vec, threeQuads); } static inline void vmathSoaV3StoreXYZArray_V( VmathSoaVector3 vec, vec_float4 *threeQuads ) { vmathSoaV3StoreXYZArray(&vec, threeQuads); } static inline void vmathSoaV3StoreHalfFloats_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_ushort8 *threeQuads ) { vmathSoaV3StoreHalfFloats(&vec0, &vec1, threeQuads); } static inline void vmathSoaV3SetX_V( VmathSoaVector3 *result, vec_float4 _x ) { vmathSoaV3SetX(result, _x); } static inline vec_float4 vmathSoaV3GetX_V( VmathSoaVector3 vec ) { return vmathSoaV3GetX(&vec); } static inline void vmathSoaV3SetY_V( VmathSoaVector3 *result, vec_float4 _y ) { vmathSoaV3SetY(result, _y); } static inline vec_float4 vmathSoaV3GetY_V( VmathSoaVector3 vec ) { return vmathSoaV3GetY(&vec); } static inline void vmathSoaV3SetZ_V( VmathSoaVector3 *result, vec_float4 _z ) { vmathSoaV3SetZ(result, _z); } static inline vec_float4 vmathSoaV3GetZ_V( VmathSoaVector3 vec ) { return vmathSoaV3GetZ(&vec); } static inline void vmathSoaV3SetElem_V( VmathSoaVector3 *result, int idx, vec_float4 value ) { vmathSoaV3SetElem(result, idx, value); } static inline vec_float4 vmathSoaV3GetElem_V( VmathSoaVector3 vec, int idx ) { return vmathSoaV3GetElem(&vec, idx); } static inline VmathSoaVector3 vmathSoaV3Add_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3Add(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3Sub_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3Sub(&result, &vec0, &vec1); return result; } static inline VmathSoaPoint3 vmathSoaV3AddP3_V( VmathSoaVector3 vec, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaV3AddP3(&result, &vec, &pnt1); return result; } static inline VmathSoaVector3 vmathSoaV3ScalarMul_V( VmathSoaVector3 vec, vec_float4 scalar ) { VmathSoaVector3 result; vmathSoaV3ScalarMul(&result, &vec, scalar); return result; } static inline VmathSoaVector3 vmathSoaV3ScalarDiv_V( VmathSoaVector3 vec, vec_float4 scalar ) { VmathSoaVector3 result; vmathSoaV3ScalarDiv(&result, &vec, scalar); return result; } static inline VmathSoaVector3 vmathSoaV3Neg_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3Neg(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3MulPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3DivPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3RecipPerElem_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3RecipPerElem(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3SqrtPerElem_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3SqrtPerElem(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3RsqrtPerElem_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3RsqrtPerElem(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3AbsPerElem_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3AbsPerElem(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3CopySignPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3MaxPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3MaxPerElem(&result, &vec0, &vec1); return result; } static inline vec_float4 vmathSoaV3MaxElem_V( VmathSoaVector3 vec ) { return vmathSoaV3MaxElem(&vec); } static inline VmathSoaVector3 vmathSoaV3MinPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3MinPerElem(&result, &vec0, &vec1); return result; } static inline vec_float4 vmathSoaV3MinElem_V( VmathSoaVector3 vec ) { return vmathSoaV3MinElem(&vec); } static inline vec_float4 vmathSoaV3Sum_V( VmathSoaVector3 vec ) { return vmathSoaV3Sum(&vec); } static inline vec_float4 vmathSoaV3Dot_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { return vmathSoaV3Dot(&vec0, &vec1); } static inline vec_float4 vmathSoaV3LengthSqr_V( VmathSoaVector3 vec ) { return vmathSoaV3LengthSqr(&vec); } static inline vec_float4 vmathSoaV3Length_V( VmathSoaVector3 vec ) { return vmathSoaV3Length(&vec); } static inline VmathSoaVector3 vmathSoaV3Normalize_V( VmathSoaVector3 vec ) { VmathSoaVector3 result; vmathSoaV3Normalize(&result, &vec); return result; } static inline VmathSoaVector3 vmathSoaV3Cross_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ) { VmathSoaVector3 result; vmathSoaV3Cross(&result, &vec0, &vec1); return result; } static inline VmathSoaVector3 vmathSoaV3Select_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_uint4 select1 ) { VmathSoaVector3 result; vmathSoaV3Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaV3Print_V( VmathSoaVector3 vec ) { vmathSoaV3Print(&vec); } static inline void vmathSoaV3Prints_V( VmathSoaVector3 vec, const char *name ) { vmathSoaV3Prints(&vec, name); } #endif static inline VmathSoaVector4 vmathSoaV4MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { VmathSoaVector4 result; vmathSoaV4MakeFromElems(&result, _x, _y, _z, _w); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 _w ) { VmathSoaVector4 result; vmathSoaV4MakeFromV3Scalar(&result, &xyz, _w); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromV3_V( VmathSoaVector3 vec ) { VmathSoaVector4 result; vmathSoaV4MakeFromV3(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromP3_V( VmathSoaPoint3 pnt ) { VmathSoaVector4 result; vmathSoaV4MakeFromP3(&result, &pnt); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromQ_V( VmathSoaQuat quat ) { VmathSoaVector4 result; vmathSoaV4MakeFromQ(&result, &quat); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromScalar_V( vec_float4 scalar ) { VmathSoaVector4 result; vmathSoaV4MakeFromScalar(&result, scalar); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFromAos_V( VmathVector4 vec ) { VmathSoaVector4 result; vmathSoaV4MakeFromAos(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4MakeFrom4Aos_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3 ) { VmathSoaVector4 result; vmathSoaV4MakeFrom4Aos(&result, &vec0, &vec1, &vec2, &vec3); return result; } static inline VmathSoaVector4 vmathSoaV4MakeXAxis_V( ) { VmathSoaVector4 result; vmathSoaV4MakeXAxis(&result); return result; } static inline VmathSoaVector4 vmathSoaV4MakeYAxis_V( ) { VmathSoaVector4 result; vmathSoaV4MakeYAxis(&result); return result; } static inline VmathSoaVector4 vmathSoaV4MakeZAxis_V( ) { VmathSoaVector4 result; vmathSoaV4MakeZAxis(&result); return result; } static inline VmathSoaVector4 vmathSoaV4MakeWAxis_V( ) { VmathSoaVector4 result; vmathSoaV4MakeWAxis(&result); return result; } static inline VmathSoaVector4 vmathSoaV4Lerp_V( vec_float4 t, VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4Lerp(&result, t, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4Slerp_V( vec_float4 t, VmathSoaVector4 unitVec0, VmathSoaVector4 unitVec1 ) { VmathSoaVector4 result; vmathSoaV4Slerp(&result, t, &unitVec0, &unitVec1); return result; } static inline void vmathSoaV4Get4Aos_V( VmathSoaVector4 vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 ) { vmathSoaV4Get4Aos(&vec, result0, result1, result2, result3); } static inline void vmathSoaV4StoreHalfFloats_V( VmathSoaVector4 vec, vec_ushort8 *twoQuads ) { vmathSoaV4StoreHalfFloats(&vec, twoQuads); } static inline void vmathSoaV4SetXYZ_V( VmathSoaVector4 *result, VmathSoaVector3 vec ) { vmathSoaV4SetXYZ(result, &vec); } static inline VmathSoaVector3 vmathSoaV4GetXYZ_V( VmathSoaVector4 vec ) { VmathSoaVector3 result; vmathSoaV4GetXYZ(&result, &vec); return result; } static inline void vmathSoaV4SetX_V( VmathSoaVector4 *result, vec_float4 _x ) { vmathSoaV4SetX(result, _x); } static inline vec_float4 vmathSoaV4GetX_V( VmathSoaVector4 vec ) { return vmathSoaV4GetX(&vec); } static inline void vmathSoaV4SetY_V( VmathSoaVector4 *result, vec_float4 _y ) { vmathSoaV4SetY(result, _y); } static inline vec_float4 vmathSoaV4GetY_V( VmathSoaVector4 vec ) { return vmathSoaV4GetY(&vec); } static inline void vmathSoaV4SetZ_V( VmathSoaVector4 *result, vec_float4 _z ) { vmathSoaV4SetZ(result, _z); } static inline vec_float4 vmathSoaV4GetZ_V( VmathSoaVector4 vec ) { return vmathSoaV4GetZ(&vec); } static inline void vmathSoaV4SetW_V( VmathSoaVector4 *result, vec_float4 _w ) { vmathSoaV4SetW(result, _w); } static inline vec_float4 vmathSoaV4GetW_V( VmathSoaVector4 vec ) { return vmathSoaV4GetW(&vec); } static inline void vmathSoaV4SetElem_V( VmathSoaVector4 *result, int idx, vec_float4 value ) { vmathSoaV4SetElem(result, idx, value); } static inline vec_float4 vmathSoaV4GetElem_V( VmathSoaVector4 vec, int idx ) { return vmathSoaV4GetElem(&vec, idx); } static inline VmathSoaVector4 vmathSoaV4Add_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4Add(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4Sub_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4Sub(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4ScalarMul_V( VmathSoaVector4 vec, vec_float4 scalar ) { VmathSoaVector4 result; vmathSoaV4ScalarMul(&result, &vec, scalar); return result; } static inline VmathSoaVector4 vmathSoaV4ScalarDiv_V( VmathSoaVector4 vec, vec_float4 scalar ) { VmathSoaVector4 result; vmathSoaV4ScalarDiv(&result, &vec, scalar); return result; } static inline VmathSoaVector4 vmathSoaV4Neg_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4Neg(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4MulPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4MulPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4DivPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4DivPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4RecipPerElem_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4RecipPerElem(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4SqrtPerElem_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4SqrtPerElem(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4RsqrtPerElem_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4RsqrtPerElem(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4AbsPerElem_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4AbsPerElem(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4CopySignPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4CopySignPerElem(&result, &vec0, &vec1); return result; } static inline VmathSoaVector4 vmathSoaV4MaxPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4MaxPerElem(&result, &vec0, &vec1); return result; } static inline vec_float4 vmathSoaV4MaxElem_V( VmathSoaVector4 vec ) { return vmathSoaV4MaxElem(&vec); } static inline VmathSoaVector4 vmathSoaV4MinPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { VmathSoaVector4 result; vmathSoaV4MinPerElem(&result, &vec0, &vec1); return result; } static inline vec_float4 vmathSoaV4MinElem_V( VmathSoaVector4 vec ) { return vmathSoaV4MinElem(&vec); } static inline vec_float4 vmathSoaV4Sum_V( VmathSoaVector4 vec ) { return vmathSoaV4Sum(&vec); } static inline vec_float4 vmathSoaV4Dot_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ) { return vmathSoaV4Dot(&vec0, &vec1); } static inline vec_float4 vmathSoaV4LengthSqr_V( VmathSoaVector4 vec ) { return vmathSoaV4LengthSqr(&vec); } static inline vec_float4 vmathSoaV4Length_V( VmathSoaVector4 vec ) { return vmathSoaV4Length(&vec); } static inline VmathSoaVector4 vmathSoaV4Normalize_V( VmathSoaVector4 vec ) { VmathSoaVector4 result; vmathSoaV4Normalize(&result, &vec); return result; } static inline VmathSoaVector4 vmathSoaV4Select_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1, vec_uint4 select1 ) { VmathSoaVector4 result; vmathSoaV4Select(&result, &vec0, &vec1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaV4Print_V( VmathSoaVector4 vec ) { vmathSoaV4Print(&vec); } static inline void vmathSoaV4Prints_V( VmathSoaVector4 vec, const char *name ) { vmathSoaV4Prints(&vec, name); } #endif static inline VmathSoaPoint3 vmathSoaP3MakeFromElems_V( vec_float4 _x, vec_float4 _y, vec_float4 _z ) { VmathSoaPoint3 result; vmathSoaP3MakeFromElems(&result, _x, _y, _z); return result; } static inline VmathSoaPoint3 vmathSoaP3MakeFromV3_V( VmathSoaVector3 vec ) { VmathSoaPoint3 result; vmathSoaP3MakeFromV3(&result, &vec); return result; } static inline VmathSoaPoint3 vmathSoaP3MakeFromScalar_V( vec_float4 scalar ) { VmathSoaPoint3 result; vmathSoaP3MakeFromScalar(&result, scalar); return result; } static inline VmathSoaPoint3 vmathSoaP3MakeFromAos_V( VmathPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3MakeFromAos(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3MakeFrom4Aos_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3 ) { VmathSoaPoint3 result; vmathSoaP3MakeFrom4Aos(&result, &pnt0, &pnt1, &pnt2, &pnt3); return result; } static inline VmathSoaPoint3 vmathSoaP3Lerp_V( vec_float4 t, VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3Lerp(&result, t, &pnt0, &pnt1); return result; } static inline void vmathSoaP3Get4Aos_V( VmathSoaPoint3 pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 ) { vmathSoaP3Get4Aos(&pnt, result0, result1, result2, result3); } static inline void vmathSoaP3LoadXYZArray_V( VmathSoaPoint3 *vec, const vec_float4 *threeQuads ) { vmathSoaP3LoadXYZArray(vec, threeQuads); } static inline void vmathSoaP3StoreXYZArray_V( VmathSoaPoint3 vec, vec_float4 *threeQuads ) { vmathSoaP3StoreXYZArray(&vec, threeQuads); } static inline void vmathSoaP3StoreHalfFloats_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_ushort8 *threeQuads ) { vmathSoaP3StoreHalfFloats(&pnt0, &pnt1, threeQuads); } static inline void vmathSoaP3SetX_V( VmathSoaPoint3 *result, vec_float4 _x ) { vmathSoaP3SetX(result, _x); } static inline vec_float4 vmathSoaP3GetX_V( VmathSoaPoint3 pnt ) { return vmathSoaP3GetX(&pnt); } static inline void vmathSoaP3SetY_V( VmathSoaPoint3 *result, vec_float4 _y ) { vmathSoaP3SetY(result, _y); } static inline vec_float4 vmathSoaP3GetY_V( VmathSoaPoint3 pnt ) { return vmathSoaP3GetY(&pnt); } static inline void vmathSoaP3SetZ_V( VmathSoaPoint3 *result, vec_float4 _z ) { vmathSoaP3SetZ(result, _z); } static inline vec_float4 vmathSoaP3GetZ_V( VmathSoaPoint3 pnt ) { return vmathSoaP3GetZ(&pnt); } static inline void vmathSoaP3SetElem_V( VmathSoaPoint3 *result, int idx, vec_float4 value ) { vmathSoaP3SetElem(result, idx, value); } static inline vec_float4 vmathSoaP3GetElem_V( VmathSoaPoint3 pnt, int idx ) { return vmathSoaP3GetElem(&pnt, idx); } static inline VmathSoaVector3 vmathSoaP3Sub_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaVector3 result; vmathSoaP3Sub(&result, &pnt0, &pnt1); return result; } static inline VmathSoaPoint3 vmathSoaP3AddV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec1 ) { VmathSoaPoint3 result; vmathSoaP3AddV3(&result, &pnt, &vec1); return result; } static inline VmathSoaPoint3 vmathSoaP3SubV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec1 ) { VmathSoaPoint3 result; vmathSoaP3SubV3(&result, &pnt, &vec1); return result; } static inline VmathSoaPoint3 vmathSoaP3MulPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3MulPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathSoaPoint3 vmathSoaP3DivPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3DivPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathSoaPoint3 vmathSoaP3RecipPerElem_V( VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3RecipPerElem(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3SqrtPerElem_V( VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3SqrtPerElem(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3RsqrtPerElem_V( VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3RsqrtPerElem(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3AbsPerElem_V( VmathSoaPoint3 pnt ) { VmathSoaPoint3 result; vmathSoaP3AbsPerElem(&result, &pnt); return result; } static inline VmathSoaPoint3 vmathSoaP3CopySignPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3CopySignPerElem(&result, &pnt0, &pnt1); return result; } static inline VmathSoaPoint3 vmathSoaP3MaxPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3MaxPerElem(&result, &pnt0, &pnt1); return result; } static inline vec_float4 vmathSoaP3MaxElem_V( VmathSoaPoint3 pnt ) { return vmathSoaP3MaxElem(&pnt); } static inline VmathSoaPoint3 vmathSoaP3MinPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { VmathSoaPoint3 result; vmathSoaP3MinPerElem(&result, &pnt0, &pnt1); return result; } static inline vec_float4 vmathSoaP3MinElem_V( VmathSoaPoint3 pnt ) { return vmathSoaP3MinElem(&pnt); } static inline vec_float4 vmathSoaP3Sum_V( VmathSoaPoint3 pnt ) { return vmathSoaP3Sum(&pnt); } static inline VmathSoaPoint3 vmathSoaP3Scale_V( VmathSoaPoint3 pnt, vec_float4 scaleVal ) { VmathSoaPoint3 result; vmathSoaP3Scale(&result, &pnt, scaleVal); return result; } static inline VmathSoaPoint3 vmathSoaP3NonUniformScale_V( VmathSoaPoint3 pnt, VmathSoaVector3 scaleVec ) { VmathSoaPoint3 result; vmathSoaP3NonUniformScale(&result, &pnt, &scaleVec); return result; } static inline vec_float4 vmathSoaP3Projection_V( VmathSoaPoint3 pnt, VmathSoaVector3 unitVec ) { return vmathSoaP3Projection(&pnt, &unitVec); } static inline vec_float4 vmathSoaP3DistSqrFromOrigin_V( VmathSoaPoint3 pnt ) { return vmathSoaP3DistSqrFromOrigin(&pnt); } static inline vec_float4 vmathSoaP3DistFromOrigin_V( VmathSoaPoint3 pnt ) { return vmathSoaP3DistFromOrigin(&pnt); } static inline vec_float4 vmathSoaP3DistSqr_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { return vmathSoaP3DistSqr(&pnt0, &pnt1); } static inline vec_float4 vmathSoaP3Dist_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ) { return vmathSoaP3Dist(&pnt0, &pnt1); } static inline VmathSoaPoint3 vmathSoaP3Select_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_uint4 select1 ) { VmathSoaPoint3 result; vmathSoaP3Select(&result, &pnt0, &pnt1, select1); return result; } #ifdef _VECTORMATH_DEBUG static inline void vmathSoaP3Print_V( VmathSoaPoint3 pnt ) { vmathSoaP3Print(&pnt); } static inline void vmathSoaP3Prints_V( VmathSoaPoint3 pnt, const char *name ) { vmathSoaP3Prints(&pnt, name); } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif ================================================ FILE: samples/vectormath/spu/c/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_C_SPU_H #define _VECTORMATH_AOS_C_SPU_H #include #include #include #ifdef _VECTORMATH_DEBUG #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_AOS_C_TYPES_H #define _VECTORMATH_AOS_C_TYPES_H /* A 3-D vector in array-of-structures format */ typedef struct _VmathVector3 { vec_float4 vec128; } VmathVector3; /* A 4-D vector in array-of-structures format */ typedef struct _VmathVector4 { vec_float4 vec128; } VmathVector4; /* A 3-D point in array-of-structures format */ typedef struct _VmathPoint3 { vec_float4 vec128; } VmathPoint3; /* A quaternion in array-of-structures format */ typedef struct _VmathQuat { vec_float4 vec128; } VmathQuat; /* A 3x3 matrix in array-of-structures format */ typedef struct _VmathMatrix3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; } VmathMatrix3; /* A 4x4 matrix in array-of-structures format */ typedef struct _VmathMatrix4 { VmathVector4 col0; VmathVector4 col1; VmathVector4 col2; VmathVector4 col3; } VmathMatrix4; /* A 3x4 transformation matrix in array-of-structures format */ typedef struct _VmathTransform3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; VmathVector3 col3; } VmathTransform3; #endif /* * Copy a 3-D vector */ static inline void vmathV3Copy( VmathVector3 *result, const VmathVector3 *vec ); /* * Construct a 3-D vector from x, y, and z elements */ static inline void vmathV3MakeFromElems( VmathVector3 *result, float x, float y, float z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline void vmathV3MakeFromP3( VmathVector3 *result, const VmathPoint3 *pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline void vmathV3MakeFromScalar( VmathVector3 *result, float scalar ); /* * Set vector float data in a 3-D vector */ static inline void vmathV3MakeFrom128( VmathVector3 *result, vec_float4 vf4 ); /* * Get vector float data from a 3-D vector */ static inline vec_float4 vmathV3Get128( const VmathVector3 *vec ); /* * Set the x element of a 3-D vector */ static inline void vmathV3SetX( VmathVector3 *result, float x ); /* * Set the y element of a 3-D vector */ static inline void vmathV3SetY( VmathVector3 *result, float y ); /* * Set the z element of a 3-D vector */ static inline void vmathV3SetZ( VmathVector3 *result, float z ); /* * Get the x element of a 3-D vector */ static inline float vmathV3GetX( const VmathVector3 *vec ); /* * Get the y element of a 3-D vector */ static inline float vmathV3GetY( const VmathVector3 *vec ); /* * Get the z element of a 3-D vector */ static inline float vmathV3GetZ( const VmathVector3 *vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathV3SetElem( VmathVector3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline float vmathV3GetElem( const VmathVector3 *vec, int idx ); /* * Add two 3-D vectors */ static inline void vmathV3Add( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline void vmathV3Sub( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline void vmathV3AddP3( VmathPoint3 *result, const VmathVector3 *vec, const VmathPoint3 *pnt ); /* * Multiply a 3-D vector by a scalar */ static inline void vmathV3ScalarMul( VmathVector3 *result, const VmathVector3 *vec, float scalar ); /* * Divide a 3-D vector by a scalar */ static inline void vmathV3ScalarDiv( VmathVector3 *result, const VmathVector3 *vec, float scalar ); /* * Negate all elements of a 3-D vector */ static inline void vmathV3Neg( VmathVector3 *result, const VmathVector3 *vec ); /* * Construct x axis */ static inline void vmathV3MakeXAxis( VmathVector3 *result ); /* * Construct y axis */ static inline void vmathV3MakeYAxis( VmathVector3 *result ); /* * Construct z axis */ static inline void vmathV3MakeZAxis( VmathVector3 *result ); /* * Multiply two 3-D vectors per element */ static inline void vmathV3MulPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathV3DivPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathV3RecipPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathV3SqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathV3RsqrtPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline void vmathV3AbsPerElem( VmathVector3 *result, const VmathVector3 *vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline void vmathV3CopySignPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Maximum of two 3-D vectors per element */ static inline void vmathV3MaxPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Minimum of two 3-D vectors per element */ static inline void vmathV3MinPerElem( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Maximum element of a 3-D vector */ static inline float vmathV3MaxElem( const VmathVector3 *vec ); /* * Minimum element of a 3-D vector */ static inline float vmathV3MinElem( const VmathVector3 *vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline float vmathV3Sum( const VmathVector3 *vec ); /* * Compute the dot product of two 3-D vectors */ static inline float vmathV3Dot( const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline float vmathV3LengthSqr( const VmathVector3 *vec ); /* * Compute the length of a 3-D vector */ static inline float vmathV3Length( const VmathVector3 *vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathV3Normalize( VmathVector3 *result, const VmathVector3 *vec ); /* * Compute cross product of two 3-D vectors */ static inline void vmathV3Cross( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Outer product of two 3-D vectors */ static inline void vmathV3Outer( VmathMatrix3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix * NOTE: * Slower than column post-multiply. */ static inline void vmathV3RowMul( VmathVector3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ); /* * Cross-product matrix of a 3-D vector */ static inline void vmathV3CrossMatrix( VmathMatrix3 *result, const VmathVector3 *vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline void vmathV3CrossMatrixMul( VmathMatrix3 *result, const VmathVector3 *vec, const VmathMatrix3 *mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathV3Lerp( VmathVector3 *result, float t, const VmathVector3 *vec0, const VmathVector3 *vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathV3Slerp( VmathVector3 *result, float t, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ); /* * Conditionally select between two 3-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathV3Select( VmathVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, unsigned int select1 ); /* * Store x, y, and z elements of a 3-D vector in the first three words of a quadword. * The value of the fourth word (the word with the highest address) remains unchanged */ static inline void vmathV3StoreXYZ( const VmathVector3 *vec, vec_float4 *quad ); /* * Load four three-float 3-D vectors, stored in three quadwords */ static inline void vmathV3LoadXYZArray( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads ); /* * Store four 3-D vectors in three quadwords */ static inline void vmathV3StoreXYZArray( const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3, vec_float4 *threeQuads ); /* * Store eight 3-D vectors as half-floats */ static 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 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Print( const VmathVector3 *vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Prints( const VmathVector3 *vec, const char *name ); #endif /* * Copy a 4-D vector */ static inline void vmathV4Copy( VmathVector4 *result, const VmathVector4 *vec ); /* * Construct a 4-D vector from x, y, z, and w elements */ static inline void vmathV4MakeFromElems( VmathVector4 *result, float x, float y, float z, float w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline void vmathV4MakeFromV3Scalar( VmathVector4 *result, const VmathVector3 *xyz, float w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline void vmathV4MakeFromV3( VmathVector4 *result, const VmathVector3 *vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline void vmathV4MakeFromP3( VmathVector4 *result, const VmathPoint3 *pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline void vmathV4MakeFromQ( VmathVector4 *result, const VmathQuat *quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline void vmathV4MakeFromScalar( VmathVector4 *result, float scalar ); /* * Set vector float data in a 4-D vector */ static inline void vmathV4MakeFrom128( VmathVector4 *result, vec_float4 vf4 ); /* * Get vector float data from a 4-D vector */ static inline vec_float4 vmathV4Get128( const VmathVector4 *vec ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathV4SetXYZ( VmathVector4 *result, const VmathVector3 *vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline void vmathV4GetXYZ( VmathVector3 *result, const VmathVector4 *vec ); /* * Set the x element of a 4-D vector */ static inline void vmathV4SetX( VmathVector4 *result, float x ); /* * Set the y element of a 4-D vector */ static inline void vmathV4SetY( VmathVector4 *result, float y ); /* * Set the z element of a 4-D vector */ static inline void vmathV4SetZ( VmathVector4 *result, float z ); /* * Set the w element of a 4-D vector */ static inline void vmathV4SetW( VmathVector4 *result, float w ); /* * Get the x element of a 4-D vector */ static inline float vmathV4GetX( const VmathVector4 *vec ); /* * Get the y element of a 4-D vector */ static inline float vmathV4GetY( const VmathVector4 *vec ); /* * Get the z element of a 4-D vector */ static inline float vmathV4GetZ( const VmathVector4 *vec ); /* * Get the w element of a 4-D vector */ static inline float vmathV4GetW( const VmathVector4 *vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathV4SetElem( VmathVector4 *result, int idx, float value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline float vmathV4GetElem( const VmathVector4 *vec, int idx ); /* * Add two 4-D vectors */ static inline void vmathV4Add( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline void vmathV4Sub( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline void vmathV4ScalarMul( VmathVector4 *result, const VmathVector4 *vec, float scalar ); /* * Divide a 4-D vector by a scalar */ static inline void vmathV4ScalarDiv( VmathVector4 *result, const VmathVector4 *vec, float scalar ); /* * Negate all elements of a 4-D vector */ static inline void vmathV4Neg( VmathVector4 *result, const VmathVector4 *vec ); /* * Construct x axis */ static inline void vmathV4MakeXAxis( VmathVector4 *result ); /* * Construct y axis */ static inline void vmathV4MakeYAxis( VmathVector4 *result ); /* * Construct z axis */ static inline void vmathV4MakeZAxis( VmathVector4 *result ); /* * Construct w axis */ static inline void vmathV4MakeWAxis( VmathVector4 *result ); /* * Multiply two 4-D vectors per element */ static inline void vmathV4MulPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathV4DivPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathV4RecipPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathV4SqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathV4RsqrtPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline void vmathV4AbsPerElem( VmathVector4 *result, const VmathVector4 *vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline void vmathV4CopySignPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Maximum of two 4-D vectors per element */ static inline void vmathV4MaxPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Minimum of two 4-D vectors per element */ static inline void vmathV4MinPerElem( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Maximum element of a 4-D vector */ static inline float vmathV4MaxElem( const VmathVector4 *vec ); /* * Minimum element of a 4-D vector */ static inline float vmathV4MinElem( const VmathVector4 *vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline float vmathV4Sum( const VmathVector4 *vec ); /* * Compute the dot product of two 4-D vectors */ static inline float vmathV4Dot( const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline float vmathV4LengthSqr( const VmathVector4 *vec ); /* * Compute the length of a 4-D vector */ static inline float vmathV4Length( const VmathVector4 *vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathV4Normalize( VmathVector4 *result, const VmathVector4 *vec ); /* * Outer product of two 4-D vectors */ static inline void vmathV4Outer( VmathMatrix4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathV4Lerp( VmathVector4 *result, float t, const VmathVector4 *vec0, const VmathVector4 *vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathV4Slerp( VmathVector4 *result, float t, const VmathVector4 *unitVec0, const VmathVector4 *unitVec1 ); /* * Conditionally select between two 4-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathV4Select( VmathVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, unsigned int select1 ); /* * Store four 4-D vectors as half-floats */ static inline void vmathV4StoreHalfFloats( const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3, vec_ushort8 *twoQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Print( const VmathVector4 *vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Prints( const VmathVector4 *vec, const char *name ); #endif /* * Copy a 3-D point */ static inline void vmathP3Copy( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Construct a 3-D point from x, y, and z elements */ static inline void vmathP3MakeFromElems( VmathPoint3 *result, float x, float y, float z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline void vmathP3MakeFromV3( VmathPoint3 *result, const VmathVector3 *vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline void vmathP3MakeFromScalar( VmathPoint3 *result, float scalar ); /* * Set vector float data in a 3-D point */ static inline void vmathP3MakeFrom128( VmathPoint3 *result, vec_float4 vf4 ); /* * Get vector float data from a 3-D point */ static inline vec_float4 vmathP3Get128( const VmathPoint3 *pnt ); /* * Set the x element of a 3-D point */ static inline void vmathP3SetX( VmathPoint3 *result, float x ); /* * Set the y element of a 3-D point */ static inline void vmathP3SetY( VmathPoint3 *result, float y ); /* * Set the z element of a 3-D point */ static inline void vmathP3SetZ( VmathPoint3 *result, float z ); /* * Get the x element of a 3-D point */ static inline float vmathP3GetX( const VmathPoint3 *pnt ); /* * Get the y element of a 3-D point */ static inline float vmathP3GetY( const VmathPoint3 *pnt ); /* * Get the z element of a 3-D point */ static inline float vmathP3GetZ( const VmathPoint3 *pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathP3SetElem( VmathPoint3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline float vmathP3GetElem( const VmathPoint3 *pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline void vmathP3Sub( VmathVector3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline void vmathP3AddV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline void vmathP3SubV3( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *vec ); /* * Multiply two 3-D points per element */ static inline void vmathP3MulPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathP3DivPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathP3RecipPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathP3SqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathP3RsqrtPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline void vmathP3AbsPerElem( VmathPoint3 *result, const VmathPoint3 *pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline void vmathP3CopySignPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Maximum of two 3-D points per element */ static inline void vmathP3MaxPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Minimum of two 3-D points per element */ static inline void vmathP3MinPerElem( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Maximum element of a 3-D point */ static inline float vmathP3MaxElem( const VmathPoint3 *pnt ); /* * Minimum element of a 3-D point */ static inline float vmathP3MinElem( const VmathPoint3 *pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline float vmathP3Sum( const VmathPoint3 *pnt ); /* * Apply uniform scale to a 3-D point */ static inline void vmathP3Scale( VmathPoint3 *result, const VmathPoint3 *pnt, float scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline void vmathP3NonUniformScale( VmathPoint3 *result, const VmathPoint3 *pnt, const VmathVector3 *scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline float vmathP3Projection( const VmathPoint3 *pnt, const VmathVector3 *unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistSqrFromOrigin( const VmathPoint3 *pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistFromOrigin( const VmathPoint3 *pnt ); /* * Compute the square of the distance between two 3-D points */ static inline float vmathP3DistSqr( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Compute the distance between two 3-D points */ static inline float vmathP3Dist( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathP3Lerp( VmathPoint3 *result, float t, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1 ); /* * Conditionally select between two 3-D points * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathP3Select( VmathPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, unsigned int select1 ); /* * Store x, y, and z elements of a 3-D point in the first three words of a quadword. * The value of the fourth word (the word with the highest address) remains unchanged */ static inline void vmathP3StoreXYZ( const VmathPoint3 *pnt, vec_float4 *quad ); /* * Load four three-float 3-D points, stored in three quadwords */ static inline void vmathP3LoadXYZArray( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads ); /* * Store four 3-D points in three quadwords */ static inline void vmathP3StoreXYZArray( const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3, vec_float4 *threeQuads ); /* * Store eight 3-D points as half-floats */ static 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 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Print( const VmathPoint3 *pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Prints( const VmathPoint3 *pnt, const char *name ); #endif /* * Copy a quaternion */ static inline void vmathQCopy( VmathQuat *result, const VmathQuat *quat ); /* * Construct a quaternion from x, y, z, and w elements */ static inline void vmathQMakeFromElems( VmathQuat *result, float x, float y, float z, float w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline void vmathQMakeFromV3Scalar( VmathQuat *result, const VmathVector3 *xyz, float w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline void vmathQMakeFromV4( VmathQuat *result, const VmathVector4 *vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline void vmathQMakeFromM3( VmathQuat *result, const VmathMatrix3 *rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline void vmathQMakeFromScalar( VmathQuat *result, float scalar ); /* * Set vector float data in a quaternion */ static inline void vmathQMakeFrom128( VmathQuat *result, vec_float4 vf4 ); /* * Get vector float data from a quaternion */ static inline vec_float4 vmathQGet128( const VmathQuat *quat ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathQSetXYZ( VmathQuat *result, const VmathVector3 *vec ); /* * Get the x, y, and z elements of a quaternion */ static inline void vmathQGetXYZ( VmathVector3 *result, const VmathQuat *quat ); /* * Set the x element of a quaternion */ static inline void vmathQSetX( VmathQuat *result, float x ); /* * Set the y element of a quaternion */ static inline void vmathQSetY( VmathQuat *result, float y ); /* * Set the z element of a quaternion */ static inline void vmathQSetZ( VmathQuat *result, float z ); /* * Set the w element of a quaternion */ static inline void vmathQSetW( VmathQuat *result, float w ); /* * Get the x element of a quaternion */ static inline float vmathQGetX( const VmathQuat *quat ); /* * Get the y element of a quaternion */ static inline float vmathQGetY( const VmathQuat *quat ); /* * Get the z element of a quaternion */ static inline float vmathQGetZ( const VmathQuat *quat ); /* * Get the w element of a quaternion */ static inline float vmathQGetW( const VmathQuat *quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathQSetElem( VmathQuat *result, int idx, float value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline float vmathQGetElem( const VmathQuat *quat, int idx ); /* * Add two quaternions */ static inline void vmathQAdd( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Subtract a quaternion from another quaternion */ static inline void vmathQSub( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Multiply two quaternions */ static inline void vmathQMul( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Multiply a quaternion by a scalar */ static inline void vmathQScalarMul( VmathQuat *result, const VmathQuat *quat, float scalar ); /* * Divide a quaternion by a scalar */ static inline void vmathQScalarDiv( VmathQuat *result, const VmathQuat *quat, float scalar ); /* * Negate all elements of a quaternion */ static inline void vmathQNeg( VmathQuat *result, const VmathQuat *quat ); /* * Construct an identity quaternion */ static inline void vmathQMakeIdentity( VmathQuat *result ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline void vmathQMakeRotationArc( VmathQuat *result, const VmathVector3 *unitVec0, const VmathVector3 *unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline void vmathQMakeRotationAxis( VmathQuat *result, float radians, const VmathVector3 *unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline void vmathQMakeRotationX( VmathQuat *result, float radians ); /* * Construct a quaternion to rotate around the y axis */ static inline void vmathQMakeRotationY( VmathQuat *result, float radians ); /* * Construct a quaternion to rotate around the z axis */ static inline void vmathQMakeRotationZ( VmathQuat *result, float radians ); /* * Compute the conjugate of a quaternion */ static inline void vmathQConj( VmathQuat *result, const VmathQuat *quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline void vmathQRotate( VmathVector3 *result, const VmathQuat *unitQuat, const VmathVector3 *vec ); /* * Compute the dot product of two quaternions */ static inline float vmathQDot( const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Compute the norm of a quaternion */ static inline float vmathQNorm( const VmathQuat *quat ); /* * Compute the length of a quaternion */ static inline float vmathQLength( const VmathQuat *quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline void vmathQNormalize( VmathQuat *result, const VmathQuat *quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathQLerp( VmathQuat *result, float t, const VmathQuat *quat0, const VmathQuat *quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline void vmathQSlerp( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline void vmathQSquad( VmathQuat *result, float t, const VmathQuat *unitQuat0, const VmathQuat *unitQuat1, const VmathQuat *unitQuat2, const VmathQuat *unitQuat3 ); /* * Conditionally select between two quaternions * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathQSelect( VmathQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrint( const VmathQuat *quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrints( const VmathQuat *quat, const char *name ); #endif /* * Copy a 3x3 matrix */ static inline void vmathM3Copy( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Construct a 3x3 matrix containing the specified columns */ static inline void vmathM3MakeFromCols( VmathMatrix3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline void vmathM3MakeFromQ( VmathMatrix3 *result, const VmathQuat *unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline void vmathM3MakeFromScalar( VmathMatrix3 *result, float scalar ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathM3SetCol0( VmathMatrix3 *result, const VmathVector3 *col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathM3SetCol1( VmathMatrix3 *result, const VmathVector3 *col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathM3SetCol2( VmathMatrix3 *result, const VmathVector3 *col2 ); /* * Get column 0 of a 3x3 matrix */ static inline void vmathM3GetCol0( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Get column 1 of a 3x3 matrix */ static inline void vmathM3GetCol1( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Get column 2 of a 3x3 matrix */ static inline void vmathM3GetCol2( VmathVector3 *result, const VmathMatrix3 *mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetCol( VmathMatrix3 *result, int col, const VmathVector3 *vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetRow( VmathMatrix3 *result, int row, const VmathVector3 *vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3GetCol( VmathVector3 *result, const VmathMatrix3 *mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3GetRow( VmathVector3 *result, const VmathMatrix3 *mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathM3SetElem( VmathMatrix3 *result, int col, int row, float val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline float vmathM3GetElem( const VmathMatrix3 *mat, int col, int row ); /* * Add two 3x3 matrices */ static inline void vmathM3Add( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline void vmathM3Sub( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline void vmathM3Neg( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline void vmathM3ScalarMul( VmathMatrix3 *result, const VmathMatrix3 *mat, float scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline void vmathM3MulV3( VmathVector3 *result, const VmathMatrix3 *mat, const VmathVector3 *vec ); /* * Multiply two 3x3 matrices */ static inline void vmathM3Mul( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Construct an identity 3x3 matrix */ static inline void vmathM3MakeIdentity( VmathMatrix3 *result ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline void vmathM3MakeRotationX( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline void vmathM3MakeRotationY( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline void vmathM3MakeRotationZ( VmathMatrix3 *result, float radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline void vmathM3MakeRotationZYX( VmathMatrix3 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline void vmathM3MakeRotationAxis( VmathMatrix3 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathM3MakeRotationQ( VmathMatrix3 *result, const VmathQuat *unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline void vmathM3MakeScale( VmathMatrix3 *result, const VmathVector3 *scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM3AppendScale( VmathMatrix3 *result, const VmathMatrix3 *mat, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM3PrependScale( VmathMatrix3 *result, const VmathVector3 *scaleVec, const VmathMatrix3 *mat ); /* * Multiply two 3x3 matrices per element */ static inline void vmathM3MulPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline void vmathM3AbsPerElem( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Transpose of a 3x3 matrix */ static inline void vmathM3Transpose( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathM3Inverse( VmathMatrix3 *result, const VmathMatrix3 *mat ); /* * Determinant of a 3x3 matrix */ static inline float vmathM3Determinant( const VmathMatrix3 *mat ); /* * Conditionally select between two 3x3 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathM3Select( VmathMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Print( const VmathMatrix3 *mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Prints( const VmathMatrix3 *mat, const char *name ); #endif /* * Copy a 4x4 matrix */ static inline void vmathM4Copy( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Construct a 4x4 matrix containing the specified columns */ static inline void vmathM4MakeFromCols( VmathMatrix4 *result, const VmathVector4 *col0, const VmathVector4 *col1, const VmathVector4 *col2, const VmathVector4 *col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline void vmathM4MakeFromT3( VmathMatrix4 *result, const VmathTransform3 *mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathM4MakeFromM3V3( VmathMatrix4 *result, const VmathMatrix3 *mat, const VmathVector3 *translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathM4MakeFromQV3( VmathMatrix4 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline void vmathM4MakeFromScalar( VmathMatrix4 *result, float scalar ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetUpper3x3( VmathMatrix4 *result, const VmathMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline void vmathM4GetUpper3x3( VmathMatrix3 *result, const VmathMatrix4 *mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline void vmathM4GetTranslation( VmathVector3 *result, const VmathMatrix4 *mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathM4SetCol0( VmathMatrix4 *result, const VmathVector4 *col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathM4SetCol1( VmathMatrix4 *result, const VmathVector4 *col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathM4SetCol2( VmathMatrix4 *result, const VmathVector4 *col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathM4SetCol3( VmathMatrix4 *result, const VmathVector4 *col3 ); /* * Get column 0 of a 4x4 matrix */ static inline void vmathM4GetCol0( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 1 of a 4x4 matrix */ static inline void vmathM4GetCol1( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 2 of a 4x4 matrix */ static inline void vmathM4GetCol2( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Get column 3 of a 4x4 matrix */ static inline void vmathM4GetCol3( VmathVector4 *result, const VmathMatrix4 *mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetCol( VmathMatrix4 *result, int col, const VmathVector4 *vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetRow( VmathMatrix4 *result, int row, const VmathVector4 *vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4GetCol( VmathVector4 *result, const VmathMatrix4 *mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4GetRow( VmathVector4 *result, const VmathMatrix4 *mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathM4SetElem( VmathMatrix4 *result, int col, int row, float val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline float vmathM4GetElem( const VmathMatrix4 *mat, int col, int row ); /* * Add two 4x4 matrices */ static inline void vmathM4Add( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline void vmathM4Sub( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline void vmathM4Neg( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline void vmathM4ScalarMul( VmathMatrix4 *result, const VmathMatrix4 *mat, float scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline void vmathM4MulV4( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector4 *vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline void vmathM4MulV3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathVector3 *vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline void vmathM4MulP3( VmathVector4 *result, const VmathMatrix4 *mat, const VmathPoint3 *pnt ); /* * Multiply two 4x4 matrices */ static inline void vmathM4Mul( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline void vmathM4MulT3( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathTransform3 *tfrm ); /* * Construct an identity 4x4 matrix */ static inline void vmathM4MakeIdentity( VmathMatrix4 *result ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline void vmathM4MakeRotationX( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline void vmathM4MakeRotationZYX( VmathMatrix4 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline void vmathM4MakeRotationAxis( VmathMatrix4 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathM4MakeRotationQ( VmathMatrix4 *result, const VmathQuat *unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline void vmathM4MakeScale( VmathMatrix4 *result, const VmathVector3 *scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline void vmathM4MakeTranslation( VmathMatrix4 *result, const VmathVector3 *translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline void vmathM4MakeLookAt( VmathMatrix4 *result, const VmathPoint3 *eyePos, const VmathPoint3 *lookAtPos, const VmathVector3 *upVec ); /* * Construct a perspective projection matrix */ static inline void vmathM4MakePerspective( VmathMatrix4 *result, float fovyRadians, float aspect, float zNear, float zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline void vmathM4MakeFrustum( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ); /* * Construct an orthographic projection matrix */ static inline void vmathM4MakeOrthographic( VmathMatrix4 *result, float left, float right, float bottom, float top, float zNear, float zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM4AppendScale( VmathMatrix4 *result, const VmathMatrix4 *mat, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathM4PrependScale( VmathMatrix4 *result, const VmathVector3 *scaleVec, const VmathMatrix4 *mat ); /* * Multiply two 4x4 matrices per element */ static inline void vmathM4MulPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline void vmathM4AbsPerElem( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Transpose of a 4x4 matrix */ static inline void vmathM4Transpose( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathM4Inverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline void vmathM4AffineInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline void vmathM4OrthoInverse( VmathMatrix4 *result, const VmathMatrix4 *mat ); /* * Determinant of a 4x4 matrix */ static inline float vmathM4Determinant( const VmathMatrix4 *mat ); /* * Conditionally select between two 4x4 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathM4Select( VmathMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Print( const VmathMatrix4 *mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Prints( const VmathMatrix4 *mat, const char *name ); #endif /* * Copy a 3x4 transformation matrix */ static inline void vmathT3Copy( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline void vmathT3MakeFromCols( VmathTransform3 *result, const VmathVector3 *col0, const VmathVector3 *col1, const VmathVector3 *col2, const VmathVector3 *col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathT3MakeFromM3V3( VmathTransform3 *result, const VmathMatrix3 *tfrm, const VmathVector3 *translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathT3MakeFromQV3( VmathTransform3 *result, const VmathQuat *unitQuat, const VmathVector3 *translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline void vmathT3MakeFromScalar( VmathTransform3 *result, float scalar ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathT3SetUpper3x3( VmathTransform3 *result, const VmathMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline void vmathT3GetUpper3x3( VmathMatrix3 *result, const VmathTransform3 *tfrm ); /* * Set translation component */ static inline void vmathT3SetTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline void vmathT3GetTranslation( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathT3SetCol0( VmathTransform3 *result, const VmathVector3 *col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathT3SetCol1( VmathTransform3 *result, const VmathVector3 *col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathT3SetCol2( VmathTransform3 *result, const VmathVector3 *col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathT3SetCol3( VmathTransform3 *result, const VmathVector3 *col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline void vmathT3GetCol0( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline void vmathT3GetCol1( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline void vmathT3GetCol2( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline void vmathT3GetCol3( VmathVector3 *result, const VmathTransform3 *tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetCol( VmathTransform3 *result, int col, const VmathVector3 *vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetRow( VmathTransform3 *result, int row, const VmathVector4 *vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3GetCol( VmathVector3 *result, const VmathTransform3 *tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3GetRow( VmathVector4 *result, const VmathTransform3 *tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathT3SetElem( VmathTransform3 *result, int col, int row, float val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline float vmathT3GetElem( const VmathTransform3 *tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline void vmathT3MulV3( VmathVector3 *result, const VmathTransform3 *tfrm, const VmathVector3 *vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline void vmathT3MulP3( VmathPoint3 *result, const VmathTransform3 *tfrm, const VmathPoint3 *pnt ); /* * Multiply two 3x4 transformation matrices */ static inline void vmathT3Mul( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline void vmathT3MakeIdentity( VmathTransform3 *result ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline void vmathT3MakeRotationX( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline void vmathT3MakeRotationY( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline void vmathT3MakeRotationZ( VmathTransform3 *result, float radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline void vmathT3MakeRotationZYX( VmathTransform3 *result, const VmathVector3 *radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline void vmathT3MakeRotationAxis( VmathTransform3 *result, float radians, const VmathVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathT3MakeRotationQ( VmathTransform3 *result, const VmathQuat *unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline void vmathT3MakeScale( VmathTransform3 *result, const VmathVector3 *scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline void vmathT3MakeTranslation( VmathTransform3 *result, const VmathVector3 *translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathT3AppendScale( VmathTransform3 *result, const VmathTransform3 *tfrm, const VmathVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathT3PrependScale( VmathTransform3 *result, const VmathVector3 *scaleVec, const VmathTransform3 *tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline void vmathT3MulPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline void vmathT3AbsPerElem( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline void vmathT3Inverse( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline void vmathT3OrthoInverse( VmathTransform3 *result, const VmathTransform3 *tfrm ); /* * Conditionally select between two 3x4 transformation matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathT3Select( VmathTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Print( const VmathTransform3 *tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Prints( const VmathTransform3 *tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vec_aos.h" #include "quat_aos.h" #include "mat_aos.h" #endif ================================================ FILE: samples/vectormath/spu/c/vectormath_aos_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_C_V_SPU_H #define _VECTORMATH_AOS_C_V_SPU_H #include #include #ifdef _VECTORMATH_DEBUG #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_AOS_C_TYPES_H #define _VECTORMATH_AOS_C_TYPES_H /* A 3-D vector in array-of-structures format */ typedef struct _VmathVector3 { vec_float4 vec128; } VmathVector3; /* A 4-D vector in array-of-structures format */ typedef struct _VmathVector4 { vec_float4 vec128; } VmathVector4; /* A 3-D point in array-of-structures format */ typedef struct _VmathPoint3 { vec_float4 vec128; } VmathPoint3; /* A quaternion in array-of-structures format */ typedef struct _VmathQuat { vec_float4 vec128; } VmathQuat; /* A 3x3 matrix in array-of-structures format */ typedef struct _VmathMatrix3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; } VmathMatrix3; /* A 4x4 matrix in array-of-structures format */ typedef struct _VmathMatrix4 { VmathVector4 col0; VmathVector4 col1; VmathVector4 col2; VmathVector4 col3; } VmathMatrix4; /* A 3x4 transformation matrix in array-of-structures format */ typedef struct _VmathTransform3 { VmathVector3 col0; VmathVector3 col1; VmathVector3 col2; VmathVector3 col3; } VmathTransform3; #endif /* * Construct a 3-D vector from x, y, and z elements */ static inline VmathVector3 vmathV3MakeFromElems_V( float x, float y, float z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline VmathVector3 vmathV3MakeFromP3_V( VmathPoint3 pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline VmathVector3 vmathV3MakeFromScalar_V( float scalar ); /* * Set vector float data in a 3-D vector */ static inline VmathVector3 vmathV3MakeFrom128_V( vec_float4 vf4 ); /* * Get vector float data from a 3-D vector */ static inline vec_float4 vmathV3Get128_V( VmathVector3 vec ); /* * Set the x element of a 3-D vector */ static inline void vmathV3SetX_V( VmathVector3 *result, float x ); /* * Set the y element of a 3-D vector */ static inline void vmathV3SetY_V( VmathVector3 *result, float y ); /* * Set the z element of a 3-D vector */ static inline void vmathV3SetZ_V( VmathVector3 *result, float z ); /* * Get the x element of a 3-D vector */ static inline float vmathV3GetX_V( VmathVector3 vec ); /* * Get the y element of a 3-D vector */ static inline float vmathV3GetY_V( VmathVector3 vec ); /* * Get the z element of a 3-D vector */ static inline float vmathV3GetZ_V( VmathVector3 vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathV3SetElem_V( VmathVector3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline float vmathV3GetElem_V( VmathVector3 vec, int idx ); /* * Add two 3-D vectors */ static inline VmathVector3 vmathV3Add_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline VmathVector3 vmathV3Sub_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline VmathPoint3 vmathV3AddP3_V( VmathVector3 vec, VmathPoint3 pnt ); /* * Multiply a 3-D vector by a scalar */ static inline VmathVector3 vmathV3ScalarMul_V( VmathVector3 vec, float scalar ); /* * Divide a 3-D vector by a scalar */ static inline VmathVector3 vmathV3ScalarDiv_V( VmathVector3 vec, float scalar ); /* * Negate all elements of a 3-D vector */ static inline VmathVector3 vmathV3Neg_V( VmathVector3 vec ); /* * Construct x axis */ static inline VmathVector3 vmathV3MakeXAxis_V( ); /* * Construct y axis */ static inline VmathVector3 vmathV3MakeYAxis_V( ); /* * Construct z axis */ static inline VmathVector3 vmathV3MakeZAxis_V( ); /* * Multiply two 3-D vectors per element */ static inline VmathVector3 vmathV3MulPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathVector3 vmathV3DivPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathVector3 vmathV3RecipPerElem_V( VmathVector3 vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathVector3 vmathV3SqrtPerElem_V( VmathVector3 vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathVector3 vmathV3RsqrtPerElem_V( VmathVector3 vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline VmathVector3 vmathV3AbsPerElem_V( VmathVector3 vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline VmathVector3 vmathV3CopySignPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Maximum of two 3-D vectors per element */ static inline VmathVector3 vmathV3MaxPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Minimum of two 3-D vectors per element */ static inline VmathVector3 vmathV3MinPerElem_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Maximum element of a 3-D vector */ static inline float vmathV3MaxElem_V( VmathVector3 vec ); /* * Minimum element of a 3-D vector */ static inline float vmathV3MinElem_V( VmathVector3 vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline float vmathV3Sum_V( VmathVector3 vec ); /* * Compute the dot product of two 3-D vectors */ static inline float vmathV3Dot_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline float vmathV3LengthSqr_V( VmathVector3 vec ); /* * Compute the length of a 3-D vector */ static inline float vmathV3Length_V( VmathVector3 vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathVector3 vmathV3Normalize_V( VmathVector3 vec ); /* * Compute cross product of two 3-D vectors */ static inline VmathVector3 vmathV3Cross_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Outer product of two 3-D vectors */ static inline VmathMatrix3 vmathV3Outer_V( VmathVector3 vec0, VmathVector3 vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix * NOTE: * Slower than column post-multiply. */ static inline VmathVector3 vmathV3RowMul_V( VmathVector3 vec, VmathMatrix3 mat ); /* * Cross-product matrix of a 3-D vector */ static inline VmathMatrix3 vmathV3CrossMatrix_V( VmathVector3 vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline VmathMatrix3 vmathV3CrossMatrixMul_V( VmathVector3 vec, VmathMatrix3 mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathVector3 vmathV3Lerp_V( float t, VmathVector3 vec0, VmathVector3 vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathVector3 vmathV3Slerp_V( float t, VmathVector3 unitVec0, VmathVector3 unitVec1 ); /* * Conditionally select between two 3-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathVector3 vmathV3Select_V( VmathVector3 vec0, VmathVector3 vec1, unsigned int select1 ); /* * Store x, y, and z elements of a 3-D vector in the first three words of a quadword. * The value of the fourth word (the word with the highest address) remains unchanged */ static inline void vmathV3StoreXYZ_V( VmathVector3 vec, vec_float4 *quad ); /* * Load four three-float 3-D vectors, stored in three quadwords */ static inline void vmathV3LoadXYZArray_V( VmathVector3 *vec0, VmathVector3 *vec1, VmathVector3 *vec2, VmathVector3 *vec3, const vec_float4 *threeQuads ); /* * Store four 3-D vectors in three quadwords */ static inline void vmathV3StoreXYZArray_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, vec_float4 *threeQuads ); /* * Store eight 3-D vectors as half-floats */ static inline void vmathV3StoreHalfFloats_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3, VmathVector3 vec4, VmathVector3 vec5, VmathVector3 vec6, VmathVector3 vec7, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Print_V( VmathVector3 vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV3Prints_V( VmathVector3 vec, const char *name ); #endif /* * Construct a 4-D vector from x, y, z, and w elements */ static inline VmathVector4 vmathV4MakeFromElems_V( float x, float y, float z, float w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline VmathVector4 vmathV4MakeFromV3Scalar_V( VmathVector3 xyz, float w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline VmathVector4 vmathV4MakeFromV3_V( VmathVector3 vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline VmathVector4 vmathV4MakeFromP3_V( VmathPoint3 pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline VmathVector4 vmathV4MakeFromQ_V( VmathQuat quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline VmathVector4 vmathV4MakeFromScalar_V( float scalar ); /* * Set vector float data in a 4-D vector */ static inline VmathVector4 vmathV4MakeFrom128_V( vec_float4 vf4 ); /* * Get vector float data from a 4-D vector */ static inline vec_float4 vmathV4Get128_V( VmathVector4 vec ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathV4SetXYZ_V( VmathVector4 *result, VmathVector3 vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline VmathVector3 vmathV4GetXYZ_V( VmathVector4 vec ); /* * Set the x element of a 4-D vector */ static inline void vmathV4SetX_V( VmathVector4 *result, float x ); /* * Set the y element of a 4-D vector */ static inline void vmathV4SetY_V( VmathVector4 *result, float y ); /* * Set the z element of a 4-D vector */ static inline void vmathV4SetZ_V( VmathVector4 *result, float z ); /* * Set the w element of a 4-D vector */ static inline void vmathV4SetW_V( VmathVector4 *result, float w ); /* * Get the x element of a 4-D vector */ static inline float vmathV4GetX_V( VmathVector4 vec ); /* * Get the y element of a 4-D vector */ static inline float vmathV4GetY_V( VmathVector4 vec ); /* * Get the z element of a 4-D vector */ static inline float vmathV4GetZ_V( VmathVector4 vec ); /* * Get the w element of a 4-D vector */ static inline float vmathV4GetW_V( VmathVector4 vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathV4SetElem_V( VmathVector4 *result, int idx, float value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline float vmathV4GetElem_V( VmathVector4 vec, int idx ); /* * Add two 4-D vectors */ static inline VmathVector4 vmathV4Add_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline VmathVector4 vmathV4Sub_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline VmathVector4 vmathV4ScalarMul_V( VmathVector4 vec, float scalar ); /* * Divide a 4-D vector by a scalar */ static inline VmathVector4 vmathV4ScalarDiv_V( VmathVector4 vec, float scalar ); /* * Negate all elements of a 4-D vector */ static inline VmathVector4 vmathV4Neg_V( VmathVector4 vec ); /* * Construct x axis */ static inline VmathVector4 vmathV4MakeXAxis_V( ); /* * Construct y axis */ static inline VmathVector4 vmathV4MakeYAxis_V( ); /* * Construct z axis */ static inline VmathVector4 vmathV4MakeZAxis_V( ); /* * Construct w axis */ static inline VmathVector4 vmathV4MakeWAxis_V( ); /* * Multiply two 4-D vectors per element */ static inline VmathVector4 vmathV4MulPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathVector4 vmathV4DivPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathVector4 vmathV4RecipPerElem_V( VmathVector4 vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathVector4 vmathV4SqrtPerElem_V( VmathVector4 vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathVector4 vmathV4RsqrtPerElem_V( VmathVector4 vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline VmathVector4 vmathV4AbsPerElem_V( VmathVector4 vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline VmathVector4 vmathV4CopySignPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Maximum of two 4-D vectors per element */ static inline VmathVector4 vmathV4MaxPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Minimum of two 4-D vectors per element */ static inline VmathVector4 vmathV4MinPerElem_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Maximum element of a 4-D vector */ static inline float vmathV4MaxElem_V( VmathVector4 vec ); /* * Minimum element of a 4-D vector */ static inline float vmathV4MinElem_V( VmathVector4 vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline float vmathV4Sum_V( VmathVector4 vec ); /* * Compute the dot product of two 4-D vectors */ static inline float vmathV4Dot_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline float vmathV4LengthSqr_V( VmathVector4 vec ); /* * Compute the length of a 4-D vector */ static inline float vmathV4Length_V( VmathVector4 vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathVector4 vmathV4Normalize_V( VmathVector4 vec ); /* * Outer product of two 4-D vectors */ static inline VmathMatrix4 vmathV4Outer_V( VmathVector4 vec0, VmathVector4 vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathVector4 vmathV4Lerp_V( float t, VmathVector4 vec0, VmathVector4 vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathVector4 vmathV4Slerp_V( float t, VmathVector4 unitVec0, VmathVector4 unitVec1 ); /* * Conditionally select between two 4-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathVector4 vmathV4Select_V( VmathVector4 vec0, VmathVector4 vec1, unsigned int select1 ); /* * Store four 4-D vectors as half-floats */ static inline void vmathV4StoreHalfFloats_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3, vec_ushort8 *twoQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Print_V( VmathVector4 vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathV4Prints_V( VmathVector4 vec, const char *name ); #endif /* * Construct a 3-D point from x, y, and z elements */ static inline VmathPoint3 vmathP3MakeFromElems_V( float x, float y, float z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline VmathPoint3 vmathP3MakeFromV3_V( VmathVector3 vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline VmathPoint3 vmathP3MakeFromScalar_V( float scalar ); /* * Set vector float data in a 3-D point */ static inline VmathPoint3 vmathP3MakeFrom128_V( vec_float4 vf4 ); /* * Get vector float data from a 3-D point */ static inline vec_float4 vmathP3Get128_V( VmathPoint3 pnt ); /* * Set the x element of a 3-D point */ static inline void vmathP3SetX_V( VmathPoint3 *result, float x ); /* * Set the y element of a 3-D point */ static inline void vmathP3SetY_V( VmathPoint3 *result, float y ); /* * Set the z element of a 3-D point */ static inline void vmathP3SetZ_V( VmathPoint3 *result, float z ); /* * Get the x element of a 3-D point */ static inline float vmathP3GetX_V( VmathPoint3 pnt ); /* * Get the y element of a 3-D point */ static inline float vmathP3GetY_V( VmathPoint3 pnt ); /* * Get the z element of a 3-D point */ static inline float vmathP3GetZ_V( VmathPoint3 pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathP3SetElem_V( VmathPoint3 *result, int idx, float value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline float vmathP3GetElem_V( VmathPoint3 pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline VmathVector3 vmathP3Sub_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline VmathPoint3 vmathP3AddV3_V( VmathPoint3 pnt, VmathVector3 vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline VmathPoint3 vmathP3SubV3_V( VmathPoint3 pnt, VmathVector3 vec ); /* * Multiply two 3-D points per element */ static inline VmathPoint3 vmathP3MulPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathPoint3 vmathP3DivPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathPoint3 vmathP3RecipPerElem_V( VmathPoint3 pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathPoint3 vmathP3SqrtPerElem_V( VmathPoint3 pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathPoint3 vmathP3RsqrtPerElem_V( VmathPoint3 pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline VmathPoint3 vmathP3AbsPerElem_V( VmathPoint3 pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline VmathPoint3 vmathP3CopySignPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Maximum of two 3-D points per element */ static inline VmathPoint3 vmathP3MaxPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Minimum of two 3-D points per element */ static inline VmathPoint3 vmathP3MinPerElem_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Maximum element of a 3-D point */ static inline float vmathP3MaxElem_V( VmathPoint3 pnt ); /* * Minimum element of a 3-D point */ static inline float vmathP3MinElem_V( VmathPoint3 pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline float vmathP3Sum_V( VmathPoint3 pnt ); /* * Apply uniform scale to a 3-D point */ static inline VmathPoint3 vmathP3Scale_V( VmathPoint3 pnt, float scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline VmathPoint3 vmathP3NonUniformScale_V( VmathPoint3 pnt, VmathVector3 scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline float vmathP3Projection_V( VmathPoint3 pnt, VmathVector3 unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistSqrFromOrigin_V( VmathPoint3 pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline float vmathP3DistFromOrigin_V( VmathPoint3 pnt ); /* * Compute the square of the distance between two 3-D points */ static inline float vmathP3DistSqr_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Compute the distance between two 3-D points */ static inline float vmathP3Dist_V( VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathPoint3 vmathP3Lerp_V( float t, VmathPoint3 pnt0, VmathPoint3 pnt1 ); /* * Conditionally select between two 3-D points * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathPoint3 vmathP3Select_V( VmathPoint3 pnt0, VmathPoint3 pnt1, unsigned int select1 ); /* * Store x, y, and z elements of a 3-D point in the first three words of a quadword. * The value of the fourth word (the word with the highest address) remains unchanged */ static inline void vmathP3StoreXYZ_V( VmathPoint3 pnt, vec_float4 *quad ); /* * Load four three-float 3-D points, stored in three quadwords */ static inline void vmathP3LoadXYZArray_V( VmathPoint3 *pnt0, VmathPoint3 *pnt1, VmathPoint3 *pnt2, VmathPoint3 *pnt3, const vec_float4 *threeQuads ); /* * Store four 3-D points in three quadwords */ static inline void vmathP3StoreXYZArray_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, vec_float4 *threeQuads ); /* * Store eight 3-D points as half-floats */ static inline void vmathP3StoreHalfFloats_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3, VmathPoint3 pnt4, VmathPoint3 pnt5, VmathPoint3 pnt6, VmathPoint3 pnt7, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Print_V( VmathPoint3 pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathP3Prints_V( VmathPoint3 pnt, const char *name ); #endif /* * Construct a quaternion from x, y, z, and w elements */ static inline VmathQuat vmathQMakeFromElems_V( float x, float y, float z, float w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline VmathQuat vmathQMakeFromV3Scalar_V( VmathVector3 xyz, float w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline VmathQuat vmathQMakeFromV4_V( VmathVector4 vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline VmathQuat vmathQMakeFromM3_V( VmathMatrix3 rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline VmathQuat vmathQMakeFromScalar_V( float scalar ); /* * Set vector float data in a quaternion */ static inline VmathQuat vmathQMakeFrom128_V( vec_float4 vf4 ); /* * Get vector float data from a quaternion */ static inline vec_float4 vmathQGet128_V( VmathQuat quat ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathQSetXYZ_V( VmathQuat *result, VmathVector3 vec ); /* * Get the x, y, and z elements of a quaternion */ static inline VmathVector3 vmathQGetXYZ_V( VmathQuat quat ); /* * Set the x element of a quaternion */ static inline void vmathQSetX_V( VmathQuat *result, float x ); /* * Set the y element of a quaternion */ static inline void vmathQSetY_V( VmathQuat *result, float y ); /* * Set the z element of a quaternion */ static inline void vmathQSetZ_V( VmathQuat *result, float z ); /* * Set the w element of a quaternion */ static inline void vmathQSetW_V( VmathQuat *result, float w ); /* * Get the x element of a quaternion */ static inline float vmathQGetX_V( VmathQuat quat ); /* * Get the y element of a quaternion */ static inline float vmathQGetY_V( VmathQuat quat ); /* * Get the z element of a quaternion */ static inline float vmathQGetZ_V( VmathQuat quat ); /* * Get the w element of a quaternion */ static inline float vmathQGetW_V( VmathQuat quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathQSetElem_V( VmathQuat *result, int idx, float value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline float vmathQGetElem_V( VmathQuat quat, int idx ); /* * Add two quaternions */ static inline VmathQuat vmathQAdd_V( VmathQuat quat0, VmathQuat quat1 ); /* * Subtract a quaternion from another quaternion */ static inline VmathQuat vmathQSub_V( VmathQuat quat0, VmathQuat quat1 ); /* * Multiply two quaternions */ static inline VmathQuat vmathQMul_V( VmathQuat quat0, VmathQuat quat1 ); /* * Multiply a quaternion by a scalar */ static inline VmathQuat vmathQScalarMul_V( VmathQuat quat, float scalar ); /* * Divide a quaternion by a scalar */ static inline VmathQuat vmathQScalarDiv_V( VmathQuat quat, float scalar ); /* * Negate all elements of a quaternion */ static inline VmathQuat vmathQNeg_V( VmathQuat quat ); /* * Construct an identity quaternion */ static inline VmathQuat vmathQMakeIdentity_V( ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline VmathQuat vmathQMakeRotationArc_V( VmathVector3 unitVec0, VmathVector3 unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline VmathQuat vmathQMakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline VmathQuat vmathQMakeRotationX_V( float radians ); /* * Construct a quaternion to rotate around the y axis */ static inline VmathQuat vmathQMakeRotationY_V( float radians ); /* * Construct a quaternion to rotate around the z axis */ static inline VmathQuat vmathQMakeRotationZ_V( float radians ); /* * Compute the conjugate of a quaternion */ static inline VmathQuat vmathQConj_V( VmathQuat quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline VmathVector3 vmathQRotate_V( VmathQuat unitQuat, VmathVector3 vec ); /* * Compute the dot product of two quaternions */ static inline float vmathQDot_V( VmathQuat quat0, VmathQuat quat1 ); /* * Compute the norm of a quaternion */ static inline float vmathQNorm_V( VmathQuat quat ); /* * Compute the length of a quaternion */ static inline float vmathQLength_V( VmathQuat quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline VmathQuat vmathQNormalize_V( VmathQuat quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathQuat vmathQLerp_V( float t, VmathQuat quat0, VmathQuat quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline VmathQuat vmathQSlerp_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline VmathQuat vmathQSquad_V( float t, VmathQuat unitQuat0, VmathQuat unitQuat1, VmathQuat unitQuat2, VmathQuat unitQuat3 ); /* * Conditionally select between two quaternions * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathQuat vmathQSelect_V( VmathQuat quat0, VmathQuat quat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrint_V( VmathQuat quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathQPrints_V( VmathQuat quat, const char *name ); #endif /* * Construct a 3x3 matrix containing the specified columns */ static inline VmathMatrix3 vmathM3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline VmathMatrix3 vmathM3MakeFromQ_V( VmathQuat unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline VmathMatrix3 vmathM3MakeFromScalar_V( float scalar ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathM3SetCol0_V( VmathMatrix3 *result, VmathVector3 col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathM3SetCol1_V( VmathMatrix3 *result, VmathVector3 col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathM3SetCol2_V( VmathMatrix3 *result, VmathVector3 col2 ); /* * Get column 0 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol0_V( VmathMatrix3 mat ); /* * Get column 1 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol1_V( VmathMatrix3 mat ); /* * Get column 2 of a 3x3 matrix */ static inline VmathVector3 vmathM3GetCol2_V( VmathMatrix3 mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetCol_V( VmathMatrix3 *result, int col, VmathVector3 vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathM3SetRow_V( VmathMatrix3 *result, int row, VmathVector3 vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline VmathVector3 vmathM3GetCol_V( VmathMatrix3 mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline VmathVector3 vmathM3GetRow_V( VmathMatrix3 mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathM3SetElem_V( VmathMatrix3 *result, int col, int row, float val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline float vmathM3GetElem_V( VmathMatrix3 mat, int col, int row ); /* * Add two 3x3 matrices */ static inline VmathMatrix3 vmathM3Add_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline VmathMatrix3 vmathM3Sub_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline VmathMatrix3 vmathM3Neg_V( VmathMatrix3 mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline VmathMatrix3 vmathM3ScalarMul_V( VmathMatrix3 mat, float scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline VmathVector3 vmathM3MulV3_V( VmathMatrix3 mat, VmathVector3 vec ); /* * Multiply two 3x3 matrices */ static inline VmathMatrix3 vmathM3Mul_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Construct an identity 3x3 matrix */ static inline VmathMatrix3 vmathM3MakeIdentity_V( ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline VmathMatrix3 vmathM3MakeRotationX_V( float radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline VmathMatrix3 vmathM3MakeRotationY_V( float radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline VmathMatrix3 vmathM3MakeRotationZ_V( float radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline VmathMatrix3 vmathM3MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline VmathMatrix3 vmathM3MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathMatrix3 vmathM3MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline VmathMatrix3 vmathM3MakeScale_V( VmathVector3 scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix3 vmathM3AppendScale_V( VmathMatrix3 mat, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix3 vmathM3PrependScale_V( VmathVector3 scaleVec, VmathMatrix3 mat ); /* * Multiply two 3x3 matrices per element */ static inline VmathMatrix3 vmathM3MulPerElem_V( VmathMatrix3 mat0, VmathMatrix3 mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline VmathMatrix3 vmathM3AbsPerElem_V( VmathMatrix3 mat ); /* * Transpose of a 3x3 matrix */ static inline VmathMatrix3 vmathM3Transpose_V( VmathMatrix3 mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathMatrix3 vmathM3Inverse_V( VmathMatrix3 mat ); /* * Determinant of a 3x3 matrix */ static inline float vmathM3Determinant_V( VmathMatrix3 mat ); /* * Conditionally select between two 3x3 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathMatrix3 vmathM3Select_V( VmathMatrix3 mat0, VmathMatrix3 mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Print_V( VmathMatrix3 mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM3Prints_V( VmathMatrix3 mat, const char *name ); #endif /* * Construct a 4x4 matrix containing the specified columns */ static inline VmathMatrix4 vmathM4MakeFromCols_V( VmathVector4 col0, VmathVector4 col1, VmathVector4 col2, VmathVector4 col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline VmathMatrix4 vmathM4MakeFromT3_V( VmathTransform3 mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline VmathMatrix4 vmathM4MakeFromM3V3_V( VmathMatrix3 mat, VmathVector3 translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline VmathMatrix4 vmathM4MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline VmathMatrix4 vmathM4MakeFromScalar_V( float scalar ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetUpper3x3_V( VmathMatrix4 *result, VmathMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline VmathMatrix3 vmathM4GetUpper3x3_V( VmathMatrix4 mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathM4SetTranslation_V( VmathMatrix4 *result, VmathVector3 translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline VmathVector3 vmathM4GetTranslation_V( VmathMatrix4 mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathM4SetCol0_V( VmathMatrix4 *result, VmathVector4 col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathM4SetCol1_V( VmathMatrix4 *result, VmathVector4 col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathM4SetCol2_V( VmathMatrix4 *result, VmathVector4 col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathM4SetCol3_V( VmathMatrix4 *result, VmathVector4 col3 ); /* * Get column 0 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol0_V( VmathMatrix4 mat ); /* * Get column 1 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol1_V( VmathMatrix4 mat ); /* * Get column 2 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol2_V( VmathMatrix4 mat ); /* * Get column 3 of a 4x4 matrix */ static inline VmathVector4 vmathM4GetCol3_V( VmathMatrix4 mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetCol_V( VmathMatrix4 *result, int col, VmathVector4 vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathM4SetRow_V( VmathMatrix4 *result, int row, VmathVector4 vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline VmathVector4 vmathM4GetCol_V( VmathMatrix4 mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline VmathVector4 vmathM4GetRow_V( VmathMatrix4 mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathM4SetElem_V( VmathMatrix4 *result, int col, int row, float val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline float vmathM4GetElem_V( VmathMatrix4 mat, int col, int row ); /* * Add two 4x4 matrices */ static inline VmathMatrix4 vmathM4Add_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline VmathMatrix4 vmathM4Sub_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline VmathMatrix4 vmathM4Neg_V( VmathMatrix4 mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline VmathMatrix4 vmathM4ScalarMul_V( VmathMatrix4 mat, float scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline VmathVector4 vmathM4MulV4_V( VmathMatrix4 mat, VmathVector4 vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline VmathVector4 vmathM4MulV3_V( VmathMatrix4 mat, VmathVector3 vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline VmathVector4 vmathM4MulP3_V( VmathMatrix4 mat, VmathPoint3 pnt ); /* * Multiply two 4x4 matrices */ static inline VmathMatrix4 vmathM4Mul_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline VmathMatrix4 vmathM4MulT3_V( VmathMatrix4 mat, VmathTransform3 tfrm ); /* * Construct an identity 4x4 matrix */ static inline VmathMatrix4 vmathM4MakeIdentity_V( ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline VmathMatrix4 vmathM4MakeRotationX_V( float radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline VmathMatrix4 vmathM4MakeRotationY_V( float radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline VmathMatrix4 vmathM4MakeRotationZ_V( float radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline VmathMatrix4 vmathM4MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline VmathMatrix4 vmathM4MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathMatrix4 vmathM4MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline VmathMatrix4 vmathM4MakeScale_V( VmathVector3 scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline VmathMatrix4 vmathM4MakeTranslation_V( VmathVector3 translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline VmathMatrix4 vmathM4MakeLookAt_V( VmathPoint3 eyePos, VmathPoint3 lookAtPos, VmathVector3 upVec ); /* * Construct a perspective projection matrix */ static inline VmathMatrix4 vmathM4MakePerspective_V( float fovyRadians, float aspect, float zNear, float zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline VmathMatrix4 vmathM4MakeFrustum_V( float left, float right, float bottom, float top, float zNear, float zFar ); /* * Construct an orthographic projection matrix */ static inline VmathMatrix4 vmathM4MakeOrthographic_V( float left, float right, float bottom, float top, float zNear, float zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix4 vmathM4AppendScale_V( VmathMatrix4 mat, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathMatrix4 vmathM4PrependScale_V( VmathVector3 scaleVec, VmathMatrix4 mat ); /* * Multiply two 4x4 matrices per element */ static inline VmathMatrix4 vmathM4MulPerElem_V( VmathMatrix4 mat0, VmathMatrix4 mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline VmathMatrix4 vmathM4AbsPerElem_V( VmathMatrix4 mat ); /* * Transpose of a 4x4 matrix */ static inline VmathMatrix4 vmathM4Transpose_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathMatrix4 vmathM4Inverse_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline VmathMatrix4 vmathM4AffineInverse_V( VmathMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline VmathMatrix4 vmathM4OrthoInverse_V( VmathMatrix4 mat ); /* * Determinant of a 4x4 matrix */ static inline float vmathM4Determinant_V( VmathMatrix4 mat ); /* * Conditionally select between two 4x4 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathMatrix4 vmathM4Select_V( VmathMatrix4 mat0, VmathMatrix4 mat1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Print_V( VmathMatrix4 mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathM4Prints_V( VmathMatrix4 mat, const char *name ); #endif /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline VmathTransform3 vmathT3MakeFromCols_V( VmathVector3 col0, VmathVector3 col1, VmathVector3 col2, VmathVector3 col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline VmathTransform3 vmathT3MakeFromM3V3_V( VmathMatrix3 tfrm, VmathVector3 translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline VmathTransform3 vmathT3MakeFromQV3_V( VmathQuat unitQuat, VmathVector3 translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline VmathTransform3 vmathT3MakeFromScalar_V( float scalar ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathT3SetUpper3x3_V( VmathTransform3 *result, VmathMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline VmathMatrix3 vmathT3GetUpper3x3_V( VmathTransform3 tfrm ); /* * Set translation component */ static inline void vmathT3SetTranslation_V( VmathTransform3 *result, VmathVector3 translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetTranslation_V( VmathTransform3 tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathT3SetCol0_V( VmathTransform3 *result, VmathVector3 col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathT3SetCol1_V( VmathTransform3 *result, VmathVector3 col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathT3SetCol2_V( VmathTransform3 *result, VmathVector3 col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathT3SetCol3_V( VmathTransform3 *result, VmathVector3 col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol0_V( VmathTransform3 tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol1_V( VmathTransform3 tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol2_V( VmathTransform3 tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline VmathVector3 vmathT3GetCol3_V( VmathTransform3 tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetCol_V( VmathTransform3 *result, int col, VmathVector3 vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathT3SetRow_V( VmathTransform3 *result, int row, VmathVector4 vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline VmathVector3 vmathT3GetCol_V( VmathTransform3 tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline VmathVector4 vmathT3GetRow_V( VmathTransform3 tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathT3SetElem_V( VmathTransform3 *result, int col, int row, float val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline float vmathT3GetElem_V( VmathTransform3 tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline VmathVector3 vmathT3MulV3_V( VmathTransform3 tfrm, VmathVector3 vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline VmathPoint3 vmathT3MulP3_V( VmathTransform3 tfrm, VmathPoint3 pnt ); /* * Multiply two 3x4 transformation matrices */ static inline VmathTransform3 vmathT3Mul_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline VmathTransform3 vmathT3MakeIdentity_V( ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline VmathTransform3 vmathT3MakeRotationX_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline VmathTransform3 vmathT3MakeRotationY_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline VmathTransform3 vmathT3MakeRotationZ_V( float radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline VmathTransform3 vmathT3MakeRotationZYX_V( VmathVector3 radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline VmathTransform3 vmathT3MakeRotationAxis_V( float radians, VmathVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathTransform3 vmathT3MakeRotationQ_V( VmathQuat unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline VmathTransform3 vmathT3MakeScale_V( VmathVector3 scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline VmathTransform3 vmathT3MakeTranslation_V( VmathVector3 translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathTransform3 vmathT3AppendScale_V( VmathTransform3 tfrm, VmathVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathTransform3 vmathT3PrependScale_V( VmathVector3 scaleVec, VmathTransform3 tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline VmathTransform3 vmathT3MulPerElem_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline VmathTransform3 vmathT3AbsPerElem_V( VmathTransform3 tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline VmathTransform3 vmathT3Inverse_V( VmathTransform3 tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline VmathTransform3 vmathT3OrthoInverse_V( VmathTransform3 tfrm ); /* * Conditionally select between two 3x4 transformation matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathTransform3 vmathT3Select_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, unsigned int select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Print_V( VmathTransform3 tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathT3Prints_V( VmathTransform3 tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vectormath_aos.h" #include "vec_aos_v.h" #include "quat_aos_v.h" #include "mat_aos_v.h" #endif ================================================ FILE: samples/vectormath/spu/c/vectormath_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_C_SPU_H #define _VECTORMATH_SOA_C_SPU_H #include #include #include "vectormath_aos.h" #ifdef _VECTORMATH_DEBUG #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_SOA_C_TYPES_H #define _VECTORMATH_SOA_C_TYPES_H /* A set of four 3-D vectors in structure-of-arrays format */ typedef struct _VmathSoaVector3 { vec_float4 x; vec_float4 y; vec_float4 z; } VmathSoaVector3; /* A set of four 4-D vectors in structure-of-arrays format */ typedef struct _VmathSoaVector4 { vec_float4 x; vec_float4 y; vec_float4 z; vec_float4 w; } VmathSoaVector4; /* A set of four 3-D points in structure-of-arrays format */ typedef struct _VmathSoaPoint3 { vec_float4 x; vec_float4 y; vec_float4 z; } VmathSoaPoint3; /* A set of four quaternions in structure-of-arrays format */ typedef struct _VmathSoaQuat { vec_float4 x; vec_float4 y; vec_float4 z; vec_float4 w; } VmathSoaQuat; /* A set of four 3x3 matrices in structure-of-arrays format */ typedef struct _VmathSoaMatrix3 { VmathSoaVector3 col0; VmathSoaVector3 col1; VmathSoaVector3 col2; } VmathSoaMatrix3; /* A set of four 4x4 matrices in structure-of-arrays format */ typedef struct _VmathSoaMatrix4 { VmathSoaVector4 col0; VmathSoaVector4 col1; VmathSoaVector4 col2; VmathSoaVector4 col3; } VmathSoaMatrix4; /* A set of four 3x4 transformation matrices in structure-of-arrays format */ typedef struct _VmathSoaTransform3 { VmathSoaVector3 col0; VmathSoaVector3 col1; VmathSoaVector3 col2; VmathSoaVector3 col3; } VmathSoaTransform3; #endif /* * Copy a 3-D vector */ static inline void vmathSoaV3Copy( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Construct a 3-D vector from x, y, and z elements */ static inline void vmathSoaV3MakeFromElems( VmathSoaVector3 *result, vec_float4 x, vec_float4 y, vec_float4 z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline void vmathSoaV3MakeFromP3( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline void vmathSoaV3MakeFromScalar( VmathSoaVector3 *result, vec_float4 scalar ); /* * Replicate an AoS 3-D vector */ static inline void vmathSoaV3MakeFromAos( VmathSoaVector3 *result, const VmathVector3 *vec ); /* * Insert four AoS 3-D vectors */ static inline void vmathSoaV3MakeFrom4Aos( VmathSoaVector3 *result, const VmathVector3 *vec0, const VmathVector3 *vec1, const VmathVector3 *vec2, const VmathVector3 *vec3 ); /* * Extract four AoS 3-D vectors */ static inline void vmathSoaV3Get4Aos( const VmathSoaVector3 *vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 ); /* * Set the x element of a 3-D vector */ static inline void vmathSoaV3SetX( VmathSoaVector3 *result, vec_float4 x ); /* * Set the y element of a 3-D vector */ static inline void vmathSoaV3SetY( VmathSoaVector3 *result, vec_float4 y ); /* * Set the z element of a 3-D vector */ static inline void vmathSoaV3SetZ( VmathSoaVector3 *result, vec_float4 z ); /* * Get the x element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetX( const VmathSoaVector3 *vec ); /* * Get the y element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetY( const VmathSoaVector3 *vec ); /* * Get the z element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetZ( const VmathSoaVector3 *vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathSoaV3SetElem( VmathSoaVector3 *result, int idx, vec_float4 value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline vec_float4 vmathSoaV3GetElem( const VmathSoaVector3 *vec, int idx ); /* * Add two 3-D vectors */ static inline void vmathSoaV3Add( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline void vmathSoaV3Sub( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline void vmathSoaV3AddP3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec, const VmathSoaPoint3 *pnt ); /* * Multiply a 3-D vector by a scalar */ static inline void vmathSoaV3ScalarMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar ); /* * Divide a 3-D vector by a scalar */ static inline void vmathSoaV3ScalarDiv( VmathSoaVector3 *result, const VmathSoaVector3 *vec, vec_float4 scalar ); /* * Negate all elements of a 3-D vector */ static inline void vmathSoaV3Neg( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Construct x axis */ static inline void vmathSoaV3MakeXAxis( VmathSoaVector3 *result ); /* * Construct y axis */ static inline void vmathSoaV3MakeYAxis( VmathSoaVector3 *result ); /* * Construct z axis */ static inline void vmathSoaV3MakeZAxis( VmathSoaVector3 *result ); /* * Multiply two 3-D vectors per element */ static inline void vmathSoaV3MulPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathSoaV3DivPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathSoaV3RecipPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathSoaV3SqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathSoaV3RsqrtPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline void vmathSoaV3AbsPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline void vmathSoaV3CopySignPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Maximum of two 3-D vectors per element */ static inline void vmathSoaV3MaxPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Minimum of two 3-D vectors per element */ static inline void vmathSoaV3MinPerElem( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Maximum element of a 3-D vector */ static inline vec_float4 vmathSoaV3MaxElem( const VmathSoaVector3 *vec ); /* * Minimum element of a 3-D vector */ static inline vec_float4 vmathSoaV3MinElem( const VmathSoaVector3 *vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline vec_float4 vmathSoaV3Sum( const VmathSoaVector3 *vec ); /* * Compute the dot product of two 3-D vectors */ static inline vec_float4 vmathSoaV3Dot( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline vec_float4 vmathSoaV3LengthSqr( const VmathSoaVector3 *vec ); /* * Compute the length of a 3-D vector */ static inline vec_float4 vmathSoaV3Length( const VmathSoaVector3 *vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathSoaV3Normalize( VmathSoaVector3 *result, const VmathSoaVector3 *vec ); /* * Compute cross product of two 3-D vectors */ static inline void vmathSoaV3Cross( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Outer product of two 3-D vectors */ static inline void vmathSoaV3Outer( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix */ static inline void vmathSoaV3RowMul( VmathSoaVector3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat ); /* * Cross-product matrix of a 3-D vector */ static inline void vmathSoaV3CrossMatrix( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline void vmathSoaV3CrossMatrixMul( VmathSoaMatrix3 *result, const VmathSoaVector3 *vec, const VmathSoaMatrix3 *mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathSoaV3Lerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathSoaV3Slerp( VmathSoaVector3 *result, vec_float4 t, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 ); /* * Conditionally select between two 3-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaV3Select( VmathSoaVector3 *result, const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_uint4 select1 ); /* * Load four three-float 3-D vectors, stored in three quadwords */ static inline void vmathSoaV3LoadXYZArray( VmathSoaVector3 *vec, const vec_float4 *threeQuads ); /* * Store four slots of an SoA 3-D vector in three quadwords */ static inline void vmathSoaV3StoreXYZArray( const VmathSoaVector3 *vec, vec_float4 *threeQuads ); /* * Store eight slots of two SoA 3-D vectors as half-floats */ static inline void vmathSoaV3StoreHalfFloats( const VmathSoaVector3 *vec0, const VmathSoaVector3 *vec1, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV3Print( const VmathSoaVector3 *vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV3Prints( const VmathSoaVector3 *vec, const char *name ); #endif /* * Copy a 4-D vector */ static inline void vmathSoaV4Copy( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Construct a 4-D vector from x, y, z, and w elements */ static inline void vmathSoaV4MakeFromElems( VmathSoaVector4 *result, vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline void vmathSoaV4MakeFromV3Scalar( VmathSoaVector4 *result, const VmathSoaVector3 *xyz, vec_float4 w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline void vmathSoaV4MakeFromV3( VmathSoaVector4 *result, const VmathSoaVector3 *vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline void vmathSoaV4MakeFromP3( VmathSoaVector4 *result, const VmathSoaPoint3 *pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline void vmathSoaV4MakeFromQ( VmathSoaVector4 *result, const VmathSoaQuat *quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline void vmathSoaV4MakeFromScalar( VmathSoaVector4 *result, vec_float4 scalar ); /* * Replicate an AoS 4-D vector */ static inline void vmathSoaV4MakeFromAos( VmathSoaVector4 *result, const VmathVector4 *vec ); /* * Insert four AoS 4-D vectors */ static inline void vmathSoaV4MakeFrom4Aos( VmathSoaVector4 *result, const VmathVector4 *vec0, const VmathVector4 *vec1, const VmathVector4 *vec2, const VmathVector4 *vec3 ); /* * Extract four AoS 4-D vectors */ static inline void vmathSoaV4Get4Aos( const VmathSoaVector4 *vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathSoaV4SetXYZ( VmathSoaVector4 *result, const VmathSoaVector3 *vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline void vmathSoaV4GetXYZ( VmathSoaVector3 *result, const VmathSoaVector4 *vec ); /* * Set the x element of a 4-D vector */ static inline void vmathSoaV4SetX( VmathSoaVector4 *result, vec_float4 x ); /* * Set the y element of a 4-D vector */ static inline void vmathSoaV4SetY( VmathSoaVector4 *result, vec_float4 y ); /* * Set the z element of a 4-D vector */ static inline void vmathSoaV4SetZ( VmathSoaVector4 *result, vec_float4 z ); /* * Set the w element of a 4-D vector */ static inline void vmathSoaV4SetW( VmathSoaVector4 *result, vec_float4 w ); /* * Get the x element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetX( const VmathSoaVector4 *vec ); /* * Get the y element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetY( const VmathSoaVector4 *vec ); /* * Get the z element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetZ( const VmathSoaVector4 *vec ); /* * Get the w element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetW( const VmathSoaVector4 *vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathSoaV4SetElem( VmathSoaVector4 *result, int idx, vec_float4 value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline vec_float4 vmathSoaV4GetElem( const VmathSoaVector4 *vec, int idx ); /* * Add two 4-D vectors */ static inline void vmathSoaV4Add( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline void vmathSoaV4Sub( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline void vmathSoaV4ScalarMul( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar ); /* * Divide a 4-D vector by a scalar */ static inline void vmathSoaV4ScalarDiv( VmathSoaVector4 *result, const VmathSoaVector4 *vec, vec_float4 scalar ); /* * Negate all elements of a 4-D vector */ static inline void vmathSoaV4Neg( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Construct x axis */ static inline void vmathSoaV4MakeXAxis( VmathSoaVector4 *result ); /* * Construct y axis */ static inline void vmathSoaV4MakeYAxis( VmathSoaVector4 *result ); /* * Construct z axis */ static inline void vmathSoaV4MakeZAxis( VmathSoaVector4 *result ); /* * Construct w axis */ static inline void vmathSoaV4MakeWAxis( VmathSoaVector4 *result ); /* * Multiply two 4-D vectors per element */ static inline void vmathSoaV4MulPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathSoaV4DivPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathSoaV4RecipPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathSoaV4SqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathSoaV4RsqrtPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline void vmathSoaV4AbsPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline void vmathSoaV4CopySignPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Maximum of two 4-D vectors per element */ static inline void vmathSoaV4MaxPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Minimum of two 4-D vectors per element */ static inline void vmathSoaV4MinPerElem( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Maximum element of a 4-D vector */ static inline vec_float4 vmathSoaV4MaxElem( const VmathSoaVector4 *vec ); /* * Minimum element of a 4-D vector */ static inline vec_float4 vmathSoaV4MinElem( const VmathSoaVector4 *vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline vec_float4 vmathSoaV4Sum( const VmathSoaVector4 *vec ); /* * Compute the dot product of two 4-D vectors */ static inline vec_float4 vmathSoaV4Dot( const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline vec_float4 vmathSoaV4LengthSqr( const VmathSoaVector4 *vec ); /* * Compute the length of a 4-D vector */ static inline vec_float4 vmathSoaV4Length( const VmathSoaVector4 *vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline void vmathSoaV4Normalize( VmathSoaVector4 *result, const VmathSoaVector4 *vec ); /* * Outer product of two 4-D vectors */ static inline void vmathSoaV4Outer( VmathSoaMatrix4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathSoaV4Lerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline void vmathSoaV4Slerp( VmathSoaVector4 *result, vec_float4 t, const VmathSoaVector4 *unitVec0, const VmathSoaVector4 *unitVec1 ); /* * Conditionally select between two 4-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaV4Select( VmathSoaVector4 *result, const VmathSoaVector4 *vec0, const VmathSoaVector4 *vec1, vec_uint4 select1 ); /* * Store four slots of an SoA 4-D vector as half-floats */ static inline void vmathSoaV4StoreHalfFloats( const VmathSoaVector4 *vec, vec_ushort8 *twoQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV4Print( const VmathSoaVector4 *vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV4Prints( const VmathSoaVector4 *vec, const char *name ); #endif /* * Copy a 3-D point */ static inline void vmathSoaP3Copy( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Construct a 3-D point from x, y, and z elements */ static inline void vmathSoaP3MakeFromElems( VmathSoaPoint3 *result, vec_float4 x, vec_float4 y, vec_float4 z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline void vmathSoaP3MakeFromV3( VmathSoaPoint3 *result, const VmathSoaVector3 *vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline void vmathSoaP3MakeFromScalar( VmathSoaPoint3 *result, vec_float4 scalar ); /* * Replicate an AoS 3-D point */ static inline void vmathSoaP3MakeFromAos( VmathSoaPoint3 *result, const VmathPoint3 *pnt ); /* * Insert four AoS 3-D points */ static inline void vmathSoaP3MakeFrom4Aos( VmathSoaPoint3 *result, const VmathPoint3 *pnt0, const VmathPoint3 *pnt1, const VmathPoint3 *pnt2, const VmathPoint3 *pnt3 ); /* * Extract four AoS 3-D points */ static inline void vmathSoaP3Get4Aos( const VmathSoaPoint3 *pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 ); /* * Set the x element of a 3-D point */ static inline void vmathSoaP3SetX( VmathSoaPoint3 *result, vec_float4 x ); /* * Set the y element of a 3-D point */ static inline void vmathSoaP3SetY( VmathSoaPoint3 *result, vec_float4 y ); /* * Set the z element of a 3-D point */ static inline void vmathSoaP3SetZ( VmathSoaPoint3 *result, vec_float4 z ); /* * Get the x element of a 3-D point */ static inline vec_float4 vmathSoaP3GetX( const VmathSoaPoint3 *pnt ); /* * Get the y element of a 3-D point */ static inline vec_float4 vmathSoaP3GetY( const VmathSoaPoint3 *pnt ); /* * Get the z element of a 3-D point */ static inline vec_float4 vmathSoaP3GetZ( const VmathSoaPoint3 *pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathSoaP3SetElem( VmathSoaPoint3 *result, int idx, vec_float4 value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline vec_float4 vmathSoaP3GetElem( const VmathSoaPoint3 *pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline void vmathSoaP3Sub( VmathSoaVector3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline void vmathSoaP3AddV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline void vmathSoaP3SubV3( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *vec ); /* * Multiply two 3-D points per element */ static inline void vmathSoaP3MulPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline void vmathSoaP3DivPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline void vmathSoaP3RecipPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline void vmathSoaP3SqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline void vmathSoaP3RsqrtPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline void vmathSoaP3AbsPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline void vmathSoaP3CopySignPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Maximum of two 3-D points per element */ static inline void vmathSoaP3MaxPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Minimum of two 3-D points per element */ static inline void vmathSoaP3MinPerElem( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Maximum element of a 3-D point */ static inline vec_float4 vmathSoaP3MaxElem( const VmathSoaPoint3 *pnt ); /* * Minimum element of a 3-D point */ static inline vec_float4 vmathSoaP3MinElem( const VmathSoaPoint3 *pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline vec_float4 vmathSoaP3Sum( const VmathSoaPoint3 *pnt ); /* * Apply uniform scale to a 3-D point */ static inline void vmathSoaP3Scale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, vec_float4 scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline void vmathSoaP3NonUniformScale( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt, const VmathSoaVector3 *scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline vec_float4 vmathSoaP3Projection( const VmathSoaPoint3 *pnt, const VmathSoaVector3 *unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline vec_float4 vmathSoaP3DistSqrFromOrigin( const VmathSoaPoint3 *pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline vec_float4 vmathSoaP3DistFromOrigin( const VmathSoaPoint3 *pnt ); /* * Compute the square of the distance between two 3-D points */ static inline vec_float4 vmathSoaP3DistSqr( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Compute the distance between two 3-D points */ static inline vec_float4 vmathSoaP3Dist( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathSoaP3Lerp( VmathSoaPoint3 *result, vec_float4 t, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1 ); /* * Conditionally select between two 3-D points * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaP3Select( VmathSoaPoint3 *result, const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_uint4 select1 ); /* * Load four three-float 3-D points, stored in three quadwords */ static inline void vmathSoaP3LoadXYZArray( VmathSoaPoint3 *pnt, const vec_float4 *threeQuads ); /* * Store four slots of an SoA 3-D point in three quadwords */ static inline void vmathSoaP3StoreXYZArray( const VmathSoaPoint3 *pnt, vec_float4 *threeQuads ); /* * Store eight slots of two SoA 3-D points as half-floats */ static inline void vmathSoaP3StoreHalfFloats( const VmathSoaPoint3 *pnt0, const VmathSoaPoint3 *pnt1, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaP3Print( const VmathSoaPoint3 *pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaP3Prints( const VmathSoaPoint3 *pnt, const char *name ); #endif /* * Copy a quaternion */ static inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat ); /* * Construct a quaternion from x, y, z, and w elements */ static inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline void vmathSoaQMakeFromM3( VmathSoaQuat *result, const VmathSoaMatrix3 *rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar ); /* * Replicate an AoS quaternion */ static inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat ); /* * Insert four AoS quaternions */ static inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 ); /* * Extract four AoS quaternions */ static inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec ); /* * Get the x, y, and z elements of a quaternion */ static inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat ); /* * Set the x element of a quaternion */ static inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 x ); /* * Set the y element of a quaternion */ static inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 y ); /* * Set the z element of a quaternion */ static inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 z ); /* * Set the w element of a quaternion */ static inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 w ); /* * Get the x element of a quaternion */ static inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat ); /* * Get the y element of a quaternion */ static inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat ); /* * Get the z element of a quaternion */ static inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat ); /* * Get the w element of a quaternion */ static inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx ); /* * Add two quaternions */ static inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Subtract a quaternion from another quaternion */ static inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Multiply two quaternions */ static inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Multiply a quaternion by a scalar */ static inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar ); /* * Divide a quaternion by a scalar */ static inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar ); /* * Negate all elements of a quaternion */ static inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat ); /* * Construct an identity quaternion */ static inline void vmathSoaQMakeIdentity( VmathSoaQuat *result ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians ); /* * Construct a quaternion to rotate around the y axis */ static inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians ); /* * Construct a quaternion to rotate around the z axis */ static inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians ); /* * Compute the conjugate of a quaternion */ static inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *vec ); /* * Compute the dot product of two quaternions */ static inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Compute the norm of a quaternion */ static inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat ); /* * Compute the length of a quaternion */ static inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 ); /* * Conditionally select between two quaternions * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaQPrint( const VmathSoaQuat *quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name ); #endif /* * Copy a 3x3 matrix */ static inline void vmathSoaM3Copy( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Construct a 3x3 matrix containing the specified columns */ static inline void vmathSoaM3MakeFromCols( VmathSoaMatrix3 *result, const VmathSoaVector3 *col0, const VmathSoaVector3 *col1, const VmathSoaVector3 *col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline void vmathSoaM3MakeFromQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline void vmathSoaM3MakeFromScalar( VmathSoaMatrix3 *result, vec_float4 scalar ); /* * Replicate an AoS 3x3 matrix */ static inline void vmathSoaM3MakeFromAos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat ); /* * Insert four AoS 3x3 matrices */ static inline void vmathSoaM3MakeFrom4Aos( VmathSoaMatrix3 *result, const VmathMatrix3 *mat0, const VmathMatrix3 *mat1, const VmathMatrix3 *mat2, const VmathMatrix3 *mat3 ); /* * Extract four AoS 3x3 matrices */ static inline void vmathSoaM3Get4Aos( const VmathSoaMatrix3 *mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathSoaM3SetCol0( VmathSoaMatrix3 *result, const VmathSoaVector3 *col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathSoaM3SetCol1( VmathSoaMatrix3 *result, const VmathSoaVector3 *col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathSoaM3SetCol2( VmathSoaMatrix3 *result, const VmathSoaVector3 *col2 ); /* * Get column 0 of a 3x3 matrix */ static inline void vmathSoaM3GetCol0( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ); /* * Get column 1 of a 3x3 matrix */ static inline void vmathSoaM3GetCol1( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ); /* * Get column 2 of a 3x3 matrix */ static inline void vmathSoaM3GetCol2( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3SetCol( VmathSoaMatrix3 *result, int col, const VmathSoaVector3 *vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3SetRow( VmathSoaMatrix3 *result, int row, const VmathSoaVector3 *vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3GetCol( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3GetRow( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathSoaM3SetElem( VmathSoaMatrix3 *result, int col, int row, vec_float4 val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline vec_float4 vmathSoaM3GetElem( const VmathSoaMatrix3 *mat, int col, int row ); /* * Add two 3x3 matrices */ static inline void vmathSoaM3Add( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline void vmathSoaM3Sub( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline void vmathSoaM3Neg( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline void vmathSoaM3ScalarMul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, vec_float4 scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline void vmathSoaM3MulV3( VmathSoaVector3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *vec ); /* * Multiply two 3x3 matrices */ static inline void vmathSoaM3Mul( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ); /* * Construct an identity 3x3 matrix */ static inline void vmathSoaM3MakeIdentity( VmathSoaMatrix3 *result ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline void vmathSoaM3MakeRotationX( VmathSoaMatrix3 *result, vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline void vmathSoaM3MakeRotationY( VmathSoaMatrix3 *result, vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline void vmathSoaM3MakeRotationZ( VmathSoaMatrix3 *result, vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline void vmathSoaM3MakeRotationZYX( VmathSoaMatrix3 *result, const VmathSoaVector3 *radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline void vmathSoaM3MakeRotationAxis( VmathSoaMatrix3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathSoaM3MakeRotationQ( VmathSoaMatrix3 *result, const VmathSoaQuat *unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline void vmathSoaM3MakeScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaM3AppendScale( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaM3PrependScale( VmathSoaMatrix3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix3 *mat ); /* * Multiply two 3x3 matrices per element */ static inline void vmathSoaM3MulPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline void vmathSoaM3AbsPerElem( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Transpose of a 3x3 matrix */ static inline void vmathSoaM3Transpose( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathSoaM3Inverse( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat ); /* * Determinant of a 3x3 matrix */ static inline vec_float4 vmathSoaM3Determinant( const VmathSoaMatrix3 *mat ); /* * Conditionally select between two 3x3 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaM3Select( VmathSoaMatrix3 *result, const VmathSoaMatrix3 *mat0, const VmathSoaMatrix3 *mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM3Print( const VmathSoaMatrix3 *mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM3Prints( const VmathSoaMatrix3 *mat, const char *name ); #endif /* * Copy a 4x4 matrix */ static inline void vmathSoaM4Copy( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Construct a 4x4 matrix containing the specified columns */ static inline void vmathSoaM4MakeFromCols( VmathSoaMatrix4 *result, const VmathSoaVector4 *col0, const VmathSoaVector4 *col1, const VmathSoaVector4 *col2, const VmathSoaVector4 *col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline void vmathSoaM4MakeFromT3( VmathSoaMatrix4 *result, const VmathSoaTransform3 *mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathSoaM4MakeFromM3V3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat, const VmathSoaVector3 *translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathSoaM4MakeFromQV3( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline void vmathSoaM4MakeFromScalar( VmathSoaMatrix4 *result, vec_float4 scalar ); /* * Replicate an AoS 4x4 matrix */ static inline void vmathSoaM4MakeFromAos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat ); /* * Insert four AoS 4x4 matrices */ static inline void vmathSoaM4MakeFrom4Aos( VmathSoaMatrix4 *result, const VmathMatrix4 *mat0, const VmathMatrix4 *mat1, const VmathMatrix4 *mat2, const VmathMatrix4 *mat3 ); /* * Extract four AoS 4x4 matrices */ static inline void vmathSoaM4Get4Aos( const VmathSoaMatrix4 *mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathSoaM4SetUpper3x3( VmathSoaMatrix4 *result, const VmathSoaMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline void vmathSoaM4GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaMatrix4 *mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathSoaM4SetTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline void vmathSoaM4GetTranslation( VmathSoaVector3 *result, const VmathSoaMatrix4 *mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathSoaM4SetCol0( VmathSoaMatrix4 *result, const VmathSoaVector4 *col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathSoaM4SetCol1( VmathSoaMatrix4 *result, const VmathSoaVector4 *col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathSoaM4SetCol2( VmathSoaMatrix4 *result, const VmathSoaVector4 *col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathSoaM4SetCol3( VmathSoaMatrix4 *result, const VmathSoaVector4 *col3 ); /* * Get column 0 of a 4x4 matrix */ static inline void vmathSoaM4GetCol0( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ); /* * Get column 1 of a 4x4 matrix */ static inline void vmathSoaM4GetCol1( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ); /* * Get column 2 of a 4x4 matrix */ static inline void vmathSoaM4GetCol2( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ); /* * Get column 3 of a 4x4 matrix */ static inline void vmathSoaM4GetCol3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4SetCol( VmathSoaMatrix4 *result, int col, const VmathSoaVector4 *vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4SetRow( VmathSoaMatrix4 *result, int row, const VmathSoaVector4 *vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4GetCol( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4GetRow( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathSoaM4SetElem( VmathSoaMatrix4 *result, int col, int row, vec_float4 val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline vec_float4 vmathSoaM4GetElem( const VmathSoaMatrix4 *mat, int col, int row ); /* * Add two 4x4 matrices */ static inline void vmathSoaM4Add( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline void vmathSoaM4Sub( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline void vmathSoaM4Neg( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline void vmathSoaM4ScalarMul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, vec_float4 scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline void vmathSoaM4MulV4( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector4 *vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline void vmathSoaM4MulV3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline void vmathSoaM4MulP3( VmathSoaVector4 *result, const VmathSoaMatrix4 *mat, const VmathSoaPoint3 *pnt ); /* * Multiply two 4x4 matrices */ static inline void vmathSoaM4Mul( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline void vmathSoaM4MulT3( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaTransform3 *tfrm ); /* * Construct an identity 4x4 matrix */ static inline void vmathSoaM4MakeIdentity( VmathSoaMatrix4 *result ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline void vmathSoaM4MakeRotationX( VmathSoaMatrix4 *result, vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline void vmathSoaM4MakeRotationY( VmathSoaMatrix4 *result, vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline void vmathSoaM4MakeRotationZ( VmathSoaMatrix4 *result, vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline void vmathSoaM4MakeRotationZYX( VmathSoaMatrix4 *result, const VmathSoaVector3 *radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline void vmathSoaM4MakeRotationAxis( VmathSoaMatrix4 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathSoaM4MakeRotationQ( VmathSoaMatrix4 *result, const VmathSoaQuat *unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline void vmathSoaM4MakeScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline void vmathSoaM4MakeTranslation( VmathSoaMatrix4 *result, const VmathSoaVector3 *translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline void vmathSoaM4MakeLookAt( VmathSoaMatrix4 *result, const VmathSoaPoint3 *eyePos, const VmathSoaPoint3 *lookAtPos, const VmathSoaVector3 *upVec ); /* * Construct a perspective projection matrix */ static inline void vmathSoaM4MakePerspective( VmathSoaMatrix4 *result, vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline void vmathSoaM4MakeFrustum( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); /* * Construct an orthographic projection matrix */ static inline void vmathSoaM4MakeOrthographic( VmathSoaMatrix4 *result, vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaM4AppendScale( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat, const VmathSoaVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaM4PrependScale( VmathSoaMatrix4 *result, const VmathSoaVector3 *scaleVec, const VmathSoaMatrix4 *mat ); /* * Multiply two 4x4 matrices per element */ static inline void vmathSoaM4MulPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline void vmathSoaM4AbsPerElem( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Transpose of a 4x4 matrix */ static inline void vmathSoaM4Transpose( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline void vmathSoaM4Inverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline void vmathSoaM4AffineInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline void vmathSoaM4OrthoInverse( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat ); /* * Determinant of a 4x4 matrix */ static inline vec_float4 vmathSoaM4Determinant( const VmathSoaMatrix4 *mat ); /* * Conditionally select between two 4x4 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaM4Select( VmathSoaMatrix4 *result, const VmathSoaMatrix4 *mat0, const VmathSoaMatrix4 *mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM4Print( const VmathSoaMatrix4 *mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM4Prints( const VmathSoaMatrix4 *mat, const char *name ); #endif /* * Copy a 3x4 transformation matrix */ static inline void vmathSoaT3Copy( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ); /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline void vmathSoaT3MakeFromCols( VmathSoaTransform3 *result, const VmathSoaVector3 *col0, const VmathSoaVector3 *col1, const VmathSoaVector3 *col2, const VmathSoaVector3 *col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline void vmathSoaT3MakeFromM3V3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *tfrm, const VmathSoaVector3 *translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline void vmathSoaT3MakeFromQV3( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat, const VmathSoaVector3 *translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline void vmathSoaT3MakeFromScalar( VmathSoaTransform3 *result, vec_float4 scalar ); /* * Replicate an AoS 3x4 transformation matrix */ static inline void vmathSoaT3MakeFromAos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm ); /* * Insert four AoS 3x4 transformation matrices */ static inline void vmathSoaT3MakeFrom4Aos( VmathSoaTransform3 *result, const VmathTransform3 *tfrm0, const VmathTransform3 *tfrm1, const VmathTransform3 *tfrm2, const VmathTransform3 *tfrm3 ); /* * Extract four AoS 3x4 transformation matrices */ static inline void vmathSoaT3Get4Aos( const VmathSoaTransform3 *tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathSoaT3SetUpper3x3( VmathSoaTransform3 *result, const VmathSoaMatrix3 *mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline void vmathSoaT3GetUpper3x3( VmathSoaMatrix3 *result, const VmathSoaTransform3 *tfrm ); /* * Set translation component */ static inline void vmathSoaT3SetTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline void vmathSoaT3GetTranslation( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol0( VmathSoaTransform3 *result, const VmathSoaVector3 *col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol1( VmathSoaTransform3 *result, const VmathSoaVector3 *col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol2( VmathSoaTransform3 *result, const VmathSoaVector3 *col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol3( VmathSoaTransform3 *result, const VmathSoaVector3 *col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline void vmathSoaT3GetCol0( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline void vmathSoaT3GetCol1( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline void vmathSoaT3GetCol2( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline void vmathSoaT3GetCol3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3SetCol( VmathSoaTransform3 *result, int col, const VmathSoaVector3 *vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3SetRow( VmathSoaTransform3 *result, int row, const VmathSoaVector4 *vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3GetCol( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3GetRow( VmathSoaVector4 *result, const VmathSoaTransform3 *tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathSoaT3SetElem( VmathSoaTransform3 *result, int col, int row, vec_float4 val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline vec_float4 vmathSoaT3GetElem( const VmathSoaTransform3 *tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline void vmathSoaT3MulV3( VmathSoaVector3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline void vmathSoaT3MulP3( VmathSoaPoint3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaPoint3 *pnt ); /* * Multiply two 3x4 transformation matrices */ static inline void vmathSoaT3Mul( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline void vmathSoaT3MakeIdentity( VmathSoaTransform3 *result ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline void vmathSoaT3MakeRotationX( VmathSoaTransform3 *result, vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline void vmathSoaT3MakeRotationY( VmathSoaTransform3 *result, vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline void vmathSoaT3MakeRotationZ( VmathSoaTransform3 *result, vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline void vmathSoaT3MakeRotationZYX( VmathSoaTransform3 *result, const VmathSoaVector3 *radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline void vmathSoaT3MakeRotationAxis( VmathSoaTransform3 *result, vec_float4 radians, const VmathSoaVector3 *unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline void vmathSoaT3MakeRotationQ( VmathSoaTransform3 *result, const VmathSoaQuat *unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline void vmathSoaT3MakeScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline void vmathSoaT3MakeTranslation( VmathSoaTransform3 *result, const VmathSoaVector3 *translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaT3AppendScale( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm, const VmathSoaVector3 *scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline void vmathSoaT3PrependScale( VmathSoaTransform3 *result, const VmathSoaVector3 *scaleVec, const VmathSoaTransform3 *tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline void vmathSoaT3MulPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline void vmathSoaT3AbsPerElem( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline void vmathSoaT3Inverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline void vmathSoaT3OrthoInverse( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm ); /* * Conditionally select between two 3x4 transformation matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline void vmathSoaT3Select( VmathSoaTransform3 *result, const VmathSoaTransform3 *tfrm0, const VmathSoaTransform3 *tfrm1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaT3Print( const VmathSoaTransform3 *tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaT3Prints( const VmathSoaTransform3 *tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vec_soa.h" #include "quat_soa.h" #include "mat_soa.h" #endif ================================================ FILE: samples/vectormath/spu/c/vectormath_soa_v.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_C_V_SPU_H #define _VECTORMATH_SOA_C_V_SPU_H #include #include #include "vectormath_aos_v.h" #ifdef _VECTORMATH_DEBUG #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef _VECTORMATH_SOA_C_TYPES_H #define _VECTORMATH_SOA_C_TYPES_H /* A set of four 3-D vectors in structure-of-arrays format */ typedef struct _VmathSoaVector3 { vec_float4 x; vec_float4 y; vec_float4 z; } VmathSoaVector3; /* A set of four 4-D vectors in structure-of-arrays format */ typedef struct _VmathSoaVector4 { vec_float4 x; vec_float4 y; vec_float4 z; vec_float4 w; } VmathSoaVector4; /* A set of four 3-D points in structure-of-arrays format */ typedef struct _VmathSoaPoint3 { vec_float4 x; vec_float4 y; vec_float4 z; } VmathSoaPoint3; /* A set of four quaternions in structure-of-arrays format */ typedef struct _VmathSoaQuat { vec_float4 x; vec_float4 y; vec_float4 z; vec_float4 w; } VmathSoaQuat; /* A set of four 3x3 matrices in structure-of-arrays format */ typedef struct _VmathSoaMatrix3 { VmathSoaVector3 col0; VmathSoaVector3 col1; VmathSoaVector3 col2; } VmathSoaMatrix3; /* A set of four 4x4 matrices in structure-of-arrays format */ typedef struct _VmathSoaMatrix4 { VmathSoaVector4 col0; VmathSoaVector4 col1; VmathSoaVector4 col2; VmathSoaVector4 col3; } VmathSoaMatrix4; /* A set of four 3x4 transformation matrices in structure-of-arrays format */ typedef struct _VmathSoaTransform3 { VmathSoaVector3 col0; VmathSoaVector3 col1; VmathSoaVector3 col2; VmathSoaVector3 col3; } VmathSoaTransform3; #endif /* * Construct a 3-D vector from x, y, and z elements */ static inline VmathSoaVector3 vmathSoaV3MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z ); /* * Copy elements from a 3-D point into a 3-D vector */ static inline VmathSoaVector3 vmathSoaV3MakeFromP3_V( VmathSoaPoint3 pnt ); /* * Set all elements of a 3-D vector to the same scalar value */ static inline VmathSoaVector3 vmathSoaV3MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 3-D vector */ static inline VmathSoaVector3 vmathSoaV3MakeFromAos_V( VmathVector3 vec ); /* * Insert four AoS 3-D vectors */ static inline VmathSoaVector3 vmathSoaV3MakeFrom4Aos_V( VmathVector3 vec0, VmathVector3 vec1, VmathVector3 vec2, VmathVector3 vec3 ); /* * Extract four AoS 3-D vectors */ static inline void vmathSoaV3Get4Aos_V( VmathSoaVector3 vec, VmathVector3 *result0, VmathVector3 *result1, VmathVector3 *result2, VmathVector3 *result3 ); /* * Set the x element of a 3-D vector */ static inline void vmathSoaV3SetX_V( VmathSoaVector3 *result, vec_float4 x ); /* * Set the y element of a 3-D vector */ static inline void vmathSoaV3SetY_V( VmathSoaVector3 *result, vec_float4 y ); /* * Set the z element of a 3-D vector */ static inline void vmathSoaV3SetZ_V( VmathSoaVector3 *result, vec_float4 z ); /* * Get the x element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetX_V( VmathSoaVector3 vec ); /* * Get the y element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetY_V( VmathSoaVector3 vec ); /* * Get the z element of a 3-D vector */ static inline vec_float4 vmathSoaV3GetZ_V( VmathSoaVector3 vec ); /* * Set an x, y, or z element of a 3-D vector by index */ static inline void vmathSoaV3SetElem_V( VmathSoaVector3 *result, int idx, vec_float4 value ); /* * Get an x, y, or z element of a 3-D vector by index */ static inline vec_float4 vmathSoaV3GetElem_V( VmathSoaVector3 vec, int idx ); /* * Add two 3-D vectors */ static inline VmathSoaVector3 vmathSoaV3Add_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Subtract a 3-D vector from another 3-D vector */ static inline VmathSoaVector3 vmathSoaV3Sub_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Add a 3-D vector to a 3-D point */ static inline VmathSoaPoint3 vmathSoaV3AddP3_V( VmathSoaVector3 vec, VmathSoaPoint3 pnt ); /* * Multiply a 3-D vector by a scalar */ static inline VmathSoaVector3 vmathSoaV3ScalarMul_V( VmathSoaVector3 vec, vec_float4 scalar ); /* * Divide a 3-D vector by a scalar */ static inline VmathSoaVector3 vmathSoaV3ScalarDiv_V( VmathSoaVector3 vec, vec_float4 scalar ); /* * Negate all elements of a 3-D vector */ static inline VmathSoaVector3 vmathSoaV3Neg_V( VmathSoaVector3 vec ); /* * Construct x axis */ static inline VmathSoaVector3 vmathSoaV3MakeXAxis_V( ); /* * Construct y axis */ static inline VmathSoaVector3 vmathSoaV3MakeYAxis_V( ); /* * Construct z axis */ static inline VmathSoaVector3 vmathSoaV3MakeZAxis_V( ); /* * Multiply two 3-D vectors per element */ static inline VmathSoaVector3 vmathSoaV3MulPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Divide two 3-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathSoaVector3 vmathSoaV3DivPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Compute the reciprocal of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathSoaVector3 vmathSoaV3RecipPerElem_V( VmathSoaVector3 vec ); /* * Compute the square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathSoaVector3 vmathSoaV3SqrtPerElem_V( VmathSoaVector3 vec ); /* * Compute the reciprocal square root of a 3-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathSoaVector3 vmathSoaV3RsqrtPerElem_V( VmathSoaVector3 vec ); /* * Compute the absolute value of a 3-D vector per element */ static inline VmathSoaVector3 vmathSoaV3AbsPerElem_V( VmathSoaVector3 vec ); /* * Copy sign from one 3-D vector to another, per element */ static inline VmathSoaVector3 vmathSoaV3CopySignPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Maximum of two 3-D vectors per element */ static inline VmathSoaVector3 vmathSoaV3MaxPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Minimum of two 3-D vectors per element */ static inline VmathSoaVector3 vmathSoaV3MinPerElem_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Maximum element of a 3-D vector */ static inline vec_float4 vmathSoaV3MaxElem_V( VmathSoaVector3 vec ); /* * Minimum element of a 3-D vector */ static inline vec_float4 vmathSoaV3MinElem_V( VmathSoaVector3 vec ); /* * Compute the sum of all elements of a 3-D vector */ static inline vec_float4 vmathSoaV3Sum_V( VmathSoaVector3 vec ); /* * Compute the dot product of two 3-D vectors */ static inline vec_float4 vmathSoaV3Dot_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Compute the square of the length of a 3-D vector */ static inline vec_float4 vmathSoaV3LengthSqr_V( VmathSoaVector3 vec ); /* * Compute the length of a 3-D vector */ static inline vec_float4 vmathSoaV3Length_V( VmathSoaVector3 vec ); /* * Normalize a 3-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathSoaVector3 vmathSoaV3Normalize_V( VmathSoaVector3 vec ); /* * Compute cross product of two 3-D vectors */ static inline VmathSoaVector3 vmathSoaV3Cross_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Outer product of two 3-D vectors */ static inline VmathSoaMatrix3 vmathSoaV3Outer_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Pre-multiply a row vector by a 3x3 matrix */ static inline VmathSoaVector3 vmathSoaV3RowMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat ); /* * Cross-product matrix of a 3-D vector */ static inline VmathSoaMatrix3 vmathSoaV3CrossMatrix_V( VmathSoaVector3 vec ); /* * Create cross-product matrix and multiply * NOTE: * Faster than separately creating a cross-product matrix and multiplying. */ static inline VmathSoaMatrix3 vmathSoaV3CrossMatrixMul_V( VmathSoaVector3 vec, VmathSoaMatrix3 mat ); /* * Linear interpolation between two 3-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathSoaVector3 vmathSoaV3Lerp_V( vec_float4 t, VmathSoaVector3 vec0, VmathSoaVector3 vec1 ); /* * Spherical linear interpolation between two 3-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathSoaVector3 vmathSoaV3Slerp_V( vec_float4 t, VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 ); /* * Conditionally select between two 3-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaVector3 vmathSoaV3Select_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_uint4 select1 ); /* * Load four three-float 3-D vectors, stored in three quadwords */ static inline void vmathSoaV3LoadXYZArray_V( VmathSoaVector3 *vec, const vec_float4 *threeQuads ); /* * Store four slots of an SoA 3-D vector in three quadwords */ static inline void vmathSoaV3StoreXYZArray_V( VmathSoaVector3 vec, vec_float4 *threeQuads ); /* * Store eight slots of two SoA 3-D vectors as half-floats */ static inline void vmathSoaV3StoreHalfFloats_V( VmathSoaVector3 vec0, VmathSoaVector3 vec1, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV3Print_V( VmathSoaVector3 vec ); /* * Print a 3-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV3Prints_V( VmathSoaVector3 vec, const char *name ); #endif /* * Construct a 4-D vector from x, y, z, and w elements */ static inline VmathSoaVector4 vmathSoaV4MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); /* * Construct a 4-D vector from a 3-D vector and a scalar */ static inline VmathSoaVector4 vmathSoaV4MakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 w ); /* * Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 */ static inline VmathSoaVector4 vmathSoaV4MakeFromV3_V( VmathSoaVector3 vec ); /* * Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 */ static inline VmathSoaVector4 vmathSoaV4MakeFromP3_V( VmathSoaPoint3 pnt ); /* * Copy elements from a quaternion into a 4-D vector */ static inline VmathSoaVector4 vmathSoaV4MakeFromQ_V( VmathSoaQuat quat ); /* * Set all elements of a 4-D vector to the same scalar value */ static inline VmathSoaVector4 vmathSoaV4MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 4-D vector */ static inline VmathSoaVector4 vmathSoaV4MakeFromAos_V( VmathVector4 vec ); /* * Insert four AoS 4-D vectors */ static inline VmathSoaVector4 vmathSoaV4MakeFrom4Aos_V( VmathVector4 vec0, VmathVector4 vec1, VmathVector4 vec2, VmathVector4 vec3 ); /* * Extract four AoS 4-D vectors */ static inline void vmathSoaV4Get4Aos_V( VmathSoaVector4 vec, VmathVector4 *result0, VmathVector4 *result1, VmathVector4 *result2, VmathVector4 *result3 ); /* * Set the x, y, and z elements of a 4-D vector * NOTE: * This function does not change the w element. */ static inline void vmathSoaV4SetXYZ_V( VmathSoaVector4 *result, VmathSoaVector3 vec ); /* * Get the x, y, and z elements of a 4-D vector */ static inline VmathSoaVector3 vmathSoaV4GetXYZ_V( VmathSoaVector4 vec ); /* * Set the x element of a 4-D vector */ static inline void vmathSoaV4SetX_V( VmathSoaVector4 *result, vec_float4 x ); /* * Set the y element of a 4-D vector */ static inline void vmathSoaV4SetY_V( VmathSoaVector4 *result, vec_float4 y ); /* * Set the z element of a 4-D vector */ static inline void vmathSoaV4SetZ_V( VmathSoaVector4 *result, vec_float4 z ); /* * Set the w element of a 4-D vector */ static inline void vmathSoaV4SetW_V( VmathSoaVector4 *result, vec_float4 w ); /* * Get the x element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetX_V( VmathSoaVector4 vec ); /* * Get the y element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetY_V( VmathSoaVector4 vec ); /* * Get the z element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetZ_V( VmathSoaVector4 vec ); /* * Get the w element of a 4-D vector */ static inline vec_float4 vmathSoaV4GetW_V( VmathSoaVector4 vec ); /* * Set an x, y, z, or w element of a 4-D vector by index */ static inline void vmathSoaV4SetElem_V( VmathSoaVector4 *result, int idx, vec_float4 value ); /* * Get an x, y, z, or w element of a 4-D vector by index */ static inline vec_float4 vmathSoaV4GetElem_V( VmathSoaVector4 vec, int idx ); /* * Add two 4-D vectors */ static inline VmathSoaVector4 vmathSoaV4Add_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Subtract a 4-D vector from another 4-D vector */ static inline VmathSoaVector4 vmathSoaV4Sub_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Multiply a 4-D vector by a scalar */ static inline VmathSoaVector4 vmathSoaV4ScalarMul_V( VmathSoaVector4 vec, vec_float4 scalar ); /* * Divide a 4-D vector by a scalar */ static inline VmathSoaVector4 vmathSoaV4ScalarDiv_V( VmathSoaVector4 vec, vec_float4 scalar ); /* * Negate all elements of a 4-D vector */ static inline VmathSoaVector4 vmathSoaV4Neg_V( VmathSoaVector4 vec ); /* * Construct x axis */ static inline VmathSoaVector4 vmathSoaV4MakeXAxis_V( ); /* * Construct y axis */ static inline VmathSoaVector4 vmathSoaV4MakeYAxis_V( ); /* * Construct z axis */ static inline VmathSoaVector4 vmathSoaV4MakeZAxis_V( ); /* * Construct w axis */ static inline VmathSoaVector4 vmathSoaV4MakeWAxis_V( ); /* * Multiply two 4-D vectors per element */ static inline VmathSoaVector4 vmathSoaV4MulPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Divide two 4-D vectors per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathSoaVector4 vmathSoaV4DivPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Compute the reciprocal of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathSoaVector4 vmathSoaV4RecipPerElem_V( VmathSoaVector4 vec ); /* * Compute the square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathSoaVector4 vmathSoaV4SqrtPerElem_V( VmathSoaVector4 vec ); /* * Compute the reciprocal square root of a 4-D vector per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathSoaVector4 vmathSoaV4RsqrtPerElem_V( VmathSoaVector4 vec ); /* * Compute the absolute value of a 4-D vector per element */ static inline VmathSoaVector4 vmathSoaV4AbsPerElem_V( VmathSoaVector4 vec ); /* * Copy sign from one 4-D vector to another, per element */ static inline VmathSoaVector4 vmathSoaV4CopySignPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Maximum of two 4-D vectors per element */ static inline VmathSoaVector4 vmathSoaV4MaxPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Minimum of two 4-D vectors per element */ static inline VmathSoaVector4 vmathSoaV4MinPerElem_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Maximum element of a 4-D vector */ static inline vec_float4 vmathSoaV4MaxElem_V( VmathSoaVector4 vec ); /* * Minimum element of a 4-D vector */ static inline vec_float4 vmathSoaV4MinElem_V( VmathSoaVector4 vec ); /* * Compute the sum of all elements of a 4-D vector */ static inline vec_float4 vmathSoaV4Sum_V( VmathSoaVector4 vec ); /* * Compute the dot product of two 4-D vectors */ static inline vec_float4 vmathSoaV4Dot_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Compute the square of the length of a 4-D vector */ static inline vec_float4 vmathSoaV4LengthSqr_V( VmathSoaVector4 vec ); /* * Compute the length of a 4-D vector */ static inline vec_float4 vmathSoaV4Length_V( VmathSoaVector4 vec ); /* * Normalize a 4-D vector * NOTE: * The result is unpredictable when all elements of vec are at or near zero. */ static inline VmathSoaVector4 vmathSoaV4Normalize_V( VmathSoaVector4 vec ); /* * Outer product of two 4-D vectors */ static inline VmathSoaMatrix4 vmathSoaV4Outer_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Linear interpolation between two 4-D vectors * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathSoaVector4 vmathSoaV4Lerp_V( vec_float4 t, VmathSoaVector4 vec0, VmathSoaVector4 vec1 ); /* * Spherical linear interpolation between two 4-D vectors * NOTE: * The result is unpredictable if the vectors point in opposite directions. * Does not clamp t between 0 and 1. */ static inline VmathSoaVector4 vmathSoaV4Slerp_V( vec_float4 t, VmathSoaVector4 unitVec0, VmathSoaVector4 unitVec1 ); /* * Conditionally select between two 4-D vectors * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaVector4 vmathSoaV4Select_V( VmathSoaVector4 vec0, VmathSoaVector4 vec1, vec_uint4 select1 ); /* * Store four slots of an SoA 4-D vector as half-floats */ static inline void vmathSoaV4StoreHalfFloats_V( VmathSoaVector4 vec, vec_ushort8 *twoQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 4-D vector * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV4Print_V( VmathSoaVector4 vec ); /* * Print a 4-D vector and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaV4Prints_V( VmathSoaVector4 vec, const char *name ); #endif /* * Construct a 3-D point from x, y, and z elements */ static inline VmathSoaPoint3 vmathSoaP3MakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z ); /* * Copy elements from a 3-D vector into a 3-D point */ static inline VmathSoaPoint3 vmathSoaP3MakeFromV3_V( VmathSoaVector3 vec ); /* * Set all elements of a 3-D point to the same scalar value */ static inline VmathSoaPoint3 vmathSoaP3MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 3-D point */ static inline VmathSoaPoint3 vmathSoaP3MakeFromAos_V( VmathPoint3 pnt ); /* * Insert four AoS 3-D points */ static inline VmathSoaPoint3 vmathSoaP3MakeFrom4Aos_V( VmathPoint3 pnt0, VmathPoint3 pnt1, VmathPoint3 pnt2, VmathPoint3 pnt3 ); /* * Extract four AoS 3-D points */ static inline void vmathSoaP3Get4Aos_V( VmathSoaPoint3 pnt, VmathPoint3 *result0, VmathPoint3 *result1, VmathPoint3 *result2, VmathPoint3 *result3 ); /* * Set the x element of a 3-D point */ static inline void vmathSoaP3SetX_V( VmathSoaPoint3 *result, vec_float4 x ); /* * Set the y element of a 3-D point */ static inline void vmathSoaP3SetY_V( VmathSoaPoint3 *result, vec_float4 y ); /* * Set the z element of a 3-D point */ static inline void vmathSoaP3SetZ_V( VmathSoaPoint3 *result, vec_float4 z ); /* * Get the x element of a 3-D point */ static inline vec_float4 vmathSoaP3GetX_V( VmathSoaPoint3 pnt ); /* * Get the y element of a 3-D point */ static inline vec_float4 vmathSoaP3GetY_V( VmathSoaPoint3 pnt ); /* * Get the z element of a 3-D point */ static inline vec_float4 vmathSoaP3GetZ_V( VmathSoaPoint3 pnt ); /* * Set an x, y, or z element of a 3-D point by index */ static inline void vmathSoaP3SetElem_V( VmathSoaPoint3 *result, int idx, vec_float4 value ); /* * Get an x, y, or z element of a 3-D point by index */ static inline vec_float4 vmathSoaP3GetElem_V( VmathSoaPoint3 pnt, int idx ); /* * Subtract a 3-D point from another 3-D point */ static inline VmathSoaVector3 vmathSoaP3Sub_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Add a 3-D point to a 3-D vector */ static inline VmathSoaPoint3 vmathSoaP3AddV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec ); /* * Subtract a 3-D vector from a 3-D point */ static inline VmathSoaPoint3 vmathSoaP3SubV3_V( VmathSoaPoint3 pnt, VmathSoaVector3 vec ); /* * Multiply two 3-D points per element */ static inline VmathSoaPoint3 vmathSoaP3MulPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Divide two 3-D points per element * NOTE: * Floating-point behavior matches standard library function divf4. */ static inline VmathSoaPoint3 vmathSoaP3DivPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Compute the reciprocal of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function recipf4. */ static inline VmathSoaPoint3 vmathSoaP3RecipPerElem_V( VmathSoaPoint3 pnt ); /* * Compute the square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function sqrtf4. */ static inline VmathSoaPoint3 vmathSoaP3SqrtPerElem_V( VmathSoaPoint3 pnt ); /* * Compute the reciprocal square root of a 3-D point per element * NOTE: * Floating-point behavior matches standard library function rsqrtf4. */ static inline VmathSoaPoint3 vmathSoaP3RsqrtPerElem_V( VmathSoaPoint3 pnt ); /* * Compute the absolute value of a 3-D point per element */ static inline VmathSoaPoint3 vmathSoaP3AbsPerElem_V( VmathSoaPoint3 pnt ); /* * Copy sign from one 3-D point to another, per element */ static inline VmathSoaPoint3 vmathSoaP3CopySignPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Maximum of two 3-D points per element */ static inline VmathSoaPoint3 vmathSoaP3MaxPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Minimum of two 3-D points per element */ static inline VmathSoaPoint3 vmathSoaP3MinPerElem_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Maximum element of a 3-D point */ static inline vec_float4 vmathSoaP3MaxElem_V( VmathSoaPoint3 pnt ); /* * Minimum element of a 3-D point */ static inline vec_float4 vmathSoaP3MinElem_V( VmathSoaPoint3 pnt ); /* * Compute the sum of all elements of a 3-D point */ static inline vec_float4 vmathSoaP3Sum_V( VmathSoaPoint3 pnt ); /* * Apply uniform scale to a 3-D point */ static inline VmathSoaPoint3 vmathSoaP3Scale_V( VmathSoaPoint3 pnt, vec_float4 scaleVal ); /* * Apply non-uniform scale to a 3-D point */ static inline VmathSoaPoint3 vmathSoaP3NonUniformScale_V( VmathSoaPoint3 pnt, VmathSoaVector3 scaleVec ); /* * Scalar projection of a 3-D point on a unit-length 3-D vector */ static inline vec_float4 vmathSoaP3Projection_V( VmathSoaPoint3 pnt, VmathSoaVector3 unitVec ); /* * Compute the square of the distance of a 3-D point from the coordinate-system origin */ static inline vec_float4 vmathSoaP3DistSqrFromOrigin_V( VmathSoaPoint3 pnt ); /* * Compute the distance of a 3-D point from the coordinate-system origin */ static inline vec_float4 vmathSoaP3DistFromOrigin_V( VmathSoaPoint3 pnt ); /* * Compute the square of the distance between two 3-D points */ static inline vec_float4 vmathSoaP3DistSqr_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Compute the distance between two 3-D points */ static inline vec_float4 vmathSoaP3Dist_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Linear interpolation between two 3-D points * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathSoaPoint3 vmathSoaP3Lerp_V( vec_float4 t, VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1 ); /* * Conditionally select between two 3-D points * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaPoint3 vmathSoaP3Select_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_uint4 select1 ); /* * Load four three-float 3-D points, stored in three quadwords */ static inline void vmathSoaP3LoadXYZArray_V( VmathSoaPoint3 *pnt, const vec_float4 *threeQuads ); /* * Store four slots of an SoA 3-D point in three quadwords */ static inline void vmathSoaP3StoreXYZArray_V( VmathSoaPoint3 pnt, vec_float4 *threeQuads ); /* * Store eight slots of two SoA 3-D points as half-floats */ static inline void vmathSoaP3StoreHalfFloats_V( VmathSoaPoint3 pnt0, VmathSoaPoint3 pnt1, vec_ushort8 *threeQuads ); #ifdef _VECTORMATH_DEBUG /* * Print a 3-D point * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaP3Print_V( VmathSoaPoint3 pnt ); /* * Print a 3-D point and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaP3Prints_V( VmathSoaPoint3 pnt, const char *name ); #endif /* * Construct a quaternion from x, y, z, and w elements */ static inline VmathSoaQuat vmathSoaQMakeFromElems_V( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); /* * Construct a quaternion from a 3-D vector and a scalar */ static inline VmathSoaQuat vmathSoaQMakeFromV3Scalar_V( VmathSoaVector3 xyz, vec_float4 w ); /* * Copy elements from a 4-D vector into a quaternion */ static inline VmathSoaQuat vmathSoaQMakeFromV4_V( VmathSoaVector4 vec ); /* * Convert a rotation matrix to a unit-length quaternion */ static inline VmathSoaQuat vmathSoaQMakeFromM3_V( VmathSoaMatrix3 rotMat ); /* * Set all elements of a quaternion to the same scalar value */ static inline VmathSoaQuat vmathSoaQMakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS quaternion */ static inline VmathSoaQuat vmathSoaQMakeFromAos_V( VmathQuat quat ); /* * Insert four AoS quaternions */ static inline VmathSoaQuat vmathSoaQMakeFrom4Aos_V( VmathQuat quat0, VmathQuat quat1, VmathQuat quat2, VmathQuat quat3 ); /* * Extract four AoS quaternions */ static inline void vmathSoaQGet4Aos_V( VmathSoaQuat quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 ); /* * Set the x, y, and z elements of a quaternion * NOTE: * This function does not change the w element. */ static inline void vmathSoaQSetXYZ_V( VmathSoaQuat *result, VmathSoaVector3 vec ); /* * Get the x, y, and z elements of a quaternion */ static inline VmathSoaVector3 vmathSoaQGetXYZ_V( VmathSoaQuat quat ); /* * Set the x element of a quaternion */ static inline void vmathSoaQSetX_V( VmathSoaQuat *result, vec_float4 x ); /* * Set the y element of a quaternion */ static inline void vmathSoaQSetY_V( VmathSoaQuat *result, vec_float4 y ); /* * Set the z element of a quaternion */ static inline void vmathSoaQSetZ_V( VmathSoaQuat *result, vec_float4 z ); /* * Set the w element of a quaternion */ static inline void vmathSoaQSetW_V( VmathSoaQuat *result, vec_float4 w ); /* * Get the x element of a quaternion */ static inline vec_float4 vmathSoaQGetX_V( VmathSoaQuat quat ); /* * Get the y element of a quaternion */ static inline vec_float4 vmathSoaQGetY_V( VmathSoaQuat quat ); /* * Get the z element of a quaternion */ static inline vec_float4 vmathSoaQGetZ_V( VmathSoaQuat quat ); /* * Get the w element of a quaternion */ static inline vec_float4 vmathSoaQGetW_V( VmathSoaQuat quat ); /* * Set an x, y, z, or w element of a quaternion by index */ static inline void vmathSoaQSetElem_V( VmathSoaQuat *result, int idx, vec_float4 value ); /* * Get an x, y, z, or w element of a quaternion by index */ static inline vec_float4 vmathSoaQGetElem_V( VmathSoaQuat quat, int idx ); /* * Add two quaternions */ static inline VmathSoaQuat vmathSoaQAdd_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Subtract a quaternion from another quaternion */ static inline VmathSoaQuat vmathSoaQSub_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Multiply two quaternions */ static inline VmathSoaQuat vmathSoaQMul_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Multiply a quaternion by a scalar */ static inline VmathSoaQuat vmathSoaQScalarMul_V( VmathSoaQuat quat, vec_float4 scalar ); /* * Divide a quaternion by a scalar */ static inline VmathSoaQuat vmathSoaQScalarDiv_V( VmathSoaQuat quat, vec_float4 scalar ); /* * Negate all elements of a quaternion */ static inline VmathSoaQuat vmathSoaQNeg_V( VmathSoaQuat quat ); /* * Construct an identity quaternion */ static inline VmathSoaQuat vmathSoaQMakeIdentity_V( ); /* * Construct a quaternion to rotate between two unit-length 3-D vectors * NOTE: * The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. */ static inline VmathSoaQuat vmathSoaQMakeRotationArc_V( VmathSoaVector3 unitVec0, VmathSoaVector3 unitVec1 ); /* * Construct a quaternion to rotate around a unit-length 3-D vector */ static inline VmathSoaQuat vmathSoaQMakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ); /* * Construct a quaternion to rotate around the x axis */ static inline VmathSoaQuat vmathSoaQMakeRotationX_V( vec_float4 radians ); /* * Construct a quaternion to rotate around the y axis */ static inline VmathSoaQuat vmathSoaQMakeRotationY_V( vec_float4 radians ); /* * Construct a quaternion to rotate around the z axis */ static inline VmathSoaQuat vmathSoaQMakeRotationZ_V( vec_float4 radians ); /* * Compute the conjugate of a quaternion */ static inline VmathSoaQuat vmathSoaQConj_V( VmathSoaQuat quat ); /* * Use a unit-length quaternion to rotate a 3-D vector */ static inline VmathSoaVector3 vmathSoaQRotate_V( VmathSoaQuat unitQuat, VmathSoaVector3 vec ); /* * Compute the dot product of two quaternions */ static inline vec_float4 vmathSoaQDot_V( VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Compute the norm of a quaternion */ static inline vec_float4 vmathSoaQNorm_V( VmathSoaQuat quat ); /* * Compute the length of a quaternion */ static inline vec_float4 vmathSoaQLength_V( VmathSoaQuat quat ); /* * Normalize a quaternion * NOTE: * The result is unpredictable when all elements of quat are at or near zero. */ static inline VmathSoaQuat vmathSoaQNormalize_V( VmathSoaQuat quat ); /* * Linear interpolation between two quaternions * NOTE: * Does not clamp t between 0 and 1. */ static inline VmathSoaQuat vmathSoaQLerp_V( vec_float4 t, VmathSoaQuat quat0, VmathSoaQuat quat1 ); /* * Spherical linear interpolation between two quaternions * NOTE: * Interpolates along the shortest path between orientations. * Does not clamp t between 0 and 1. */ static inline VmathSoaQuat vmathSoaQSlerp_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1 ); /* * Spherical quadrangle interpolation */ static inline VmathSoaQuat vmathSoaQSquad_V( vec_float4 t, VmathSoaQuat unitQuat0, VmathSoaQuat unitQuat1, VmathSoaQuat unitQuat2, VmathSoaQuat unitQuat3 ); /* * Conditionally select between two quaternions * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaQuat vmathSoaQSelect_V( VmathSoaQuat quat0, VmathSoaQuat quat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a quaternion * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaQPrint_V( VmathSoaQuat quat ); /* * Print a quaternion and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaQPrints_V( VmathSoaQuat quat, const char *name ); #endif /* * Construct a 3x3 matrix containing the specified columns */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromCols_V( VmathSoaVector3 col0, VmathSoaVector3 col1, VmathSoaVector3 col2 ); /* * Construct a 3x3 rotation matrix from a unit-length quaternion */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromQ_V( VmathSoaQuat unitQuat ); /* * Set all elements of a 3x3 matrix to the same scalar value */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3MakeFromAos_V( VmathMatrix3 mat ); /* * Insert four AoS 3x3 matrices */ static inline VmathSoaMatrix3 vmathSoaM3MakeFrom4Aos_V( VmathMatrix3 mat0, VmathMatrix3 mat1, VmathMatrix3 mat2, VmathMatrix3 mat3 ); /* * Extract four AoS 3x3 matrices */ static inline void vmathSoaM3Get4Aos_V( VmathSoaMatrix3 mat, VmathMatrix3 *result0, VmathMatrix3 *result1, VmathMatrix3 *result2, VmathMatrix3 *result3 ); /* * Set column 0 of a 3x3 matrix */ static inline void vmathSoaM3SetCol0_V( VmathSoaMatrix3 *result, VmathSoaVector3 col0 ); /* * Set column 1 of a 3x3 matrix */ static inline void vmathSoaM3SetCol1_V( VmathSoaMatrix3 *result, VmathSoaVector3 col1 ); /* * Set column 2 of a 3x3 matrix */ static inline void vmathSoaM3SetCol2_V( VmathSoaMatrix3 *result, VmathSoaVector3 col2 ); /* * Get column 0 of a 3x3 matrix */ static inline VmathSoaVector3 vmathSoaM3GetCol0_V( VmathSoaMatrix3 mat ); /* * Get column 1 of a 3x3 matrix */ static inline VmathSoaVector3 vmathSoaM3GetCol1_V( VmathSoaMatrix3 mat ); /* * Get column 2 of a 3x3 matrix */ static inline VmathSoaVector3 vmathSoaM3GetCol2_V( VmathSoaMatrix3 mat ); /* * Set the column of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3SetCol_V( VmathSoaMatrix3 *result, int col, VmathSoaVector3 vec ); /* * Set the row of a 3x3 matrix referred to by the specified index */ static inline void vmathSoaM3SetRow_V( VmathSoaMatrix3 *result, int row, VmathSoaVector3 vec ); /* * Get the column of a 3x3 matrix referred to by the specified index */ static inline VmathSoaVector3 vmathSoaM3GetCol_V( VmathSoaMatrix3 mat, int col ); /* * Get the row of a 3x3 matrix referred to by the specified index */ static inline VmathSoaVector3 vmathSoaM3GetRow_V( VmathSoaMatrix3 mat, int row ); /* * Set the element of a 3x3 matrix referred to by column and row indices */ static inline void vmathSoaM3SetElem_V( VmathSoaMatrix3 *result, int col, int row, vec_float4 val ); /* * Get the element of a 3x3 matrix referred to by column and row indices */ static inline vec_float4 vmathSoaM3GetElem_V( VmathSoaMatrix3 mat, int col, int row ); /* * Add two 3x3 matrices */ static inline VmathSoaMatrix3 vmathSoaM3Add_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ); /* * Subtract a 3x3 matrix from another 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3Sub_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ); /* * Negate all elements of a 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3Neg_V( VmathSoaMatrix3 mat ); /* * Multiply a 3x3 matrix by a scalar */ static inline VmathSoaMatrix3 vmathSoaM3ScalarMul_V( VmathSoaMatrix3 mat, vec_float4 scalar ); /* * Multiply a 3x3 matrix by a 3-D vector */ static inline VmathSoaVector3 vmathSoaM3MulV3_V( VmathSoaMatrix3 mat, VmathSoaVector3 vec ); /* * Multiply two 3x3 matrices */ static inline VmathSoaMatrix3 vmathSoaM3Mul_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ); /* * Construct an identity 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3MakeIdentity_V( ); /* * Construct a 3x3 matrix to rotate around the x axis */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationX_V( vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the y axis */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationY_V( vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the z axis */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationZ_V( vec_float4 radians ); /* * Construct a 3x3 matrix to rotate around the x, y, and z axes */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ); /* * Construct a 3x3 matrix to rotate around a unit-length 3-D vector */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathSoaMatrix3 vmathSoaM3MakeRotationQ_V( VmathSoaQuat unitQuat ); /* * Construct a 3x3 matrix to perform scaling */ static inline VmathSoaMatrix3 vmathSoaM3MakeScale_V( VmathSoaVector3 scaleVec ); /* * Append (post-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaMatrix3 vmathSoaM3AppendScale_V( VmathSoaMatrix3 mat, VmathSoaVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x3 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaMatrix3 vmathSoaM3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix3 mat ); /* * Multiply two 3x3 matrices per element */ static inline VmathSoaMatrix3 vmathSoaM3MulPerElem_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1 ); /* * Compute the absolute value of a 3x3 matrix per element */ static inline VmathSoaMatrix3 vmathSoaM3AbsPerElem_V( VmathSoaMatrix3 mat ); /* * Transpose of a 3x3 matrix */ static inline VmathSoaMatrix3 vmathSoaM3Transpose_V( VmathSoaMatrix3 mat ); /* * Compute the inverse of a 3x3 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathSoaMatrix3 vmathSoaM3Inverse_V( VmathSoaMatrix3 mat ); /* * Determinant of a 3x3 matrix */ static inline vec_float4 vmathSoaM3Determinant_V( VmathSoaMatrix3 mat ); /* * Conditionally select between two 3x3 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaMatrix3 vmathSoaM3Select_V( VmathSoaMatrix3 mat0, VmathSoaMatrix3 mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x3 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM3Print_V( VmathSoaMatrix3 mat ); /* * Print a 3x3 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM3Prints_V( VmathSoaMatrix3 mat, const char *name ); #endif /* * Construct a 4x4 matrix containing the specified columns */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromCols_V( VmathSoaVector4 col0, VmathSoaVector4 col1, VmathSoaVector4 col2, VmathSoaVector4 col3 ); /* * Construct a 4x4 matrix from a 3x4 transformation matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromT3_V( VmathSoaTransform3 mat ); /* * Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromM3V3_V( VmathSoaMatrix3 mat, VmathSoaVector3 translateVec ); /* * Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec ); /* * Set all elements of a 4x4 matrix to the same scalar value */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakeFromAos_V( VmathMatrix4 mat ); /* * Insert four AoS 4x4 matrices */ static inline VmathSoaMatrix4 vmathSoaM4MakeFrom4Aos_V( VmathMatrix4 mat0, VmathMatrix4 mat1, VmathMatrix4 mat2, VmathMatrix4 mat3 ); /* * Extract four AoS 4x4 matrices */ static inline void vmathSoaM4Get4Aos_V( VmathSoaMatrix4 mat, VmathMatrix4 *result0, VmathMatrix4 *result1, VmathMatrix4 *result2, VmathMatrix4 *result3 ); /* * Set the upper-left 3x3 submatrix * NOTE: * This function does not change the bottom row elements. */ static inline void vmathSoaM4SetUpper3x3_V( VmathSoaMatrix4 *result, VmathSoaMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 4x4 matrix */ static inline VmathSoaMatrix3 vmathSoaM4GetUpper3x3_V( VmathSoaMatrix4 mat ); /* * Set translation component * NOTE: * This function does not change the bottom row elements. */ static inline void vmathSoaM4SetTranslation_V( VmathSoaMatrix4 *result, VmathSoaVector3 translateVec ); /* * Get the translation component of a 4x4 matrix */ static inline VmathSoaVector3 vmathSoaM4GetTranslation_V( VmathSoaMatrix4 mat ); /* * Set column 0 of a 4x4 matrix */ static inline void vmathSoaM4SetCol0_V( VmathSoaMatrix4 *result, VmathSoaVector4 col0 ); /* * Set column 1 of a 4x4 matrix */ static inline void vmathSoaM4SetCol1_V( VmathSoaMatrix4 *result, VmathSoaVector4 col1 ); /* * Set column 2 of a 4x4 matrix */ static inline void vmathSoaM4SetCol2_V( VmathSoaMatrix4 *result, VmathSoaVector4 col2 ); /* * Set column 3 of a 4x4 matrix */ static inline void vmathSoaM4SetCol3_V( VmathSoaMatrix4 *result, VmathSoaVector4 col3 ); /* * Get column 0 of a 4x4 matrix */ static inline VmathSoaVector4 vmathSoaM4GetCol0_V( VmathSoaMatrix4 mat ); /* * Get column 1 of a 4x4 matrix */ static inline VmathSoaVector4 vmathSoaM4GetCol1_V( VmathSoaMatrix4 mat ); /* * Get column 2 of a 4x4 matrix */ static inline VmathSoaVector4 vmathSoaM4GetCol2_V( VmathSoaMatrix4 mat ); /* * Get column 3 of a 4x4 matrix */ static inline VmathSoaVector4 vmathSoaM4GetCol3_V( VmathSoaMatrix4 mat ); /* * Set the column of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4SetCol_V( VmathSoaMatrix4 *result, int col, VmathSoaVector4 vec ); /* * Set the row of a 4x4 matrix referred to by the specified index */ static inline void vmathSoaM4SetRow_V( VmathSoaMatrix4 *result, int row, VmathSoaVector4 vec ); /* * Get the column of a 4x4 matrix referred to by the specified index */ static inline VmathSoaVector4 vmathSoaM4GetCol_V( VmathSoaMatrix4 mat, int col ); /* * Get the row of a 4x4 matrix referred to by the specified index */ static inline VmathSoaVector4 vmathSoaM4GetRow_V( VmathSoaMatrix4 mat, int row ); /* * Set the element of a 4x4 matrix referred to by column and row indices */ static inline void vmathSoaM4SetElem_V( VmathSoaMatrix4 *result, int col, int row, vec_float4 val ); /* * Get the element of a 4x4 matrix referred to by column and row indices */ static inline vec_float4 vmathSoaM4GetElem_V( VmathSoaMatrix4 mat, int col, int row ); /* * Add two 4x4 matrices */ static inline VmathSoaMatrix4 vmathSoaM4Add_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ); /* * Subtract a 4x4 matrix from another 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4Sub_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ); /* * Negate all elements of a 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4Neg_V( VmathSoaMatrix4 mat ); /* * Multiply a 4x4 matrix by a scalar */ static inline VmathSoaMatrix4 vmathSoaM4ScalarMul_V( VmathSoaMatrix4 mat, vec_float4 scalar ); /* * Multiply a 4x4 matrix by a 4-D vector */ static inline VmathSoaVector4 vmathSoaM4MulV4_V( VmathSoaMatrix4 mat, VmathSoaVector4 vec ); /* * Multiply a 4x4 matrix by a 3-D vector */ static inline VmathSoaVector4 vmathSoaM4MulV3_V( VmathSoaMatrix4 mat, VmathSoaVector3 vec ); /* * Multiply a 4x4 matrix by a 3-D point */ static inline VmathSoaVector4 vmathSoaM4MulP3_V( VmathSoaMatrix4 mat, VmathSoaPoint3 pnt ); /* * Multiply two 4x4 matrices */ static inline VmathSoaMatrix4 vmathSoaM4Mul_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ); /* * Multiply a 4x4 matrix by a 3x4 transformation matrix */ static inline VmathSoaMatrix4 vmathSoaM4MulT3_V( VmathSoaMatrix4 mat, VmathSoaTransform3 tfrm ); /* * Construct an identity 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakeIdentity_V( ); /* * Construct a 4x4 matrix to rotate around the x axis */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationX_V( vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the y axis */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationY_V( vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the z axis */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationZ_V( vec_float4 radians ); /* * Construct a 4x4 matrix to rotate around the x, y, and z axes */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ); /* * Construct a 4x4 matrix to rotate around a unit-length 3-D vector */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathSoaMatrix4 vmathSoaM4MakeRotationQ_V( VmathSoaQuat unitQuat ); /* * Construct a 4x4 matrix to perform scaling */ static inline VmathSoaMatrix4 vmathSoaM4MakeScale_V( VmathSoaVector3 scaleVec ); /* * Construct a 4x4 matrix to perform translation */ static inline VmathSoaMatrix4 vmathSoaM4MakeTranslation_V( VmathSoaVector3 translateVec ); /* * Construct viewing matrix based on eye position, position looked at, and up direction */ static inline VmathSoaMatrix4 vmathSoaM4MakeLookAt_V( VmathSoaPoint3 eyePos, VmathSoaPoint3 lookAtPos, VmathSoaVector3 upVec ); /* * Construct a perspective projection matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakePerspective_V( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ); /* * Construct a perspective projection matrix based on frustum */ static inline VmathSoaMatrix4 vmathSoaM4MakeFrustum_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); /* * Construct an orthographic projection matrix */ static inline VmathSoaMatrix4 vmathSoaM4MakeOrthographic_V( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); /* * Append (post-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaMatrix4 vmathSoaM4AppendScale_V( VmathSoaMatrix4 mat, VmathSoaVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 4x4 matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaMatrix4 vmathSoaM4PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaMatrix4 mat ); /* * Multiply two 4x4 matrices per element */ static inline VmathSoaMatrix4 vmathSoaM4MulPerElem_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1 ); /* * Compute the absolute value of a 4x4 matrix per element */ static inline VmathSoaMatrix4 vmathSoaM4AbsPerElem_V( VmathSoaMatrix4 mat ); /* * Transpose of a 4x4 matrix */ static inline VmathSoaMatrix4 vmathSoaM4Transpose_V( VmathSoaMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix * NOTE: * Result is unpredictable when the determinant of mat is equal to or near 0. */ static inline VmathSoaMatrix4 vmathSoaM4Inverse_V( VmathSoaMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix * NOTE: * 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. */ static inline VmathSoaMatrix4 vmathSoaM4AffineInverse_V( VmathSoaMatrix4 mat ); /* * Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. */ static inline VmathSoaMatrix4 vmathSoaM4OrthoInverse_V( VmathSoaMatrix4 mat ); /* * Determinant of a 4x4 matrix */ static inline vec_float4 vmathSoaM4Determinant_V( VmathSoaMatrix4 mat ); /* * Conditionally select between two 4x4 matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaMatrix4 vmathSoaM4Select_V( VmathSoaMatrix4 mat0, VmathSoaMatrix4 mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 4x4 matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM4Print_V( VmathSoaMatrix4 mat ); /* * Print a 4x4 matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaM4Prints_V( VmathSoaMatrix4 mat, const char *name ); #endif /* * Construct a 3x4 transformation matrix containing the specified columns */ static inline VmathSoaTransform3 vmathSoaT3MakeFromCols_V( VmathSoaVector3 col0, VmathSoaVector3 col1, VmathSoaVector3 col2, VmathSoaVector3 col3 ); /* * Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector */ static inline VmathSoaTransform3 vmathSoaT3MakeFromM3V3_V( VmathSoaMatrix3 tfrm, VmathSoaVector3 translateVec ); /* * Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector */ static inline VmathSoaTransform3 vmathSoaT3MakeFromQV3_V( VmathSoaQuat unitQuat, VmathSoaVector3 translateVec ); /* * Set all elements of a 3x4 transformation matrix to the same scalar value */ static inline VmathSoaTransform3 vmathSoaT3MakeFromScalar_V( vec_float4 scalar ); /* * Replicate an AoS 3x4 transformation matrix */ static inline VmathSoaTransform3 vmathSoaT3MakeFromAos_V( VmathTransform3 tfrm ); /* * Insert four AoS 3x4 transformation matrices */ static inline VmathSoaTransform3 vmathSoaT3MakeFrom4Aos_V( VmathTransform3 tfrm0, VmathTransform3 tfrm1, VmathTransform3 tfrm2, VmathTransform3 tfrm3 ); /* * Extract four AoS 3x4 transformation matrices */ static inline void vmathSoaT3Get4Aos_V( VmathSoaTransform3 tfrm, VmathTransform3 *result0, VmathTransform3 *result1, VmathTransform3 *result2, VmathTransform3 *result3 ); /* * Set the upper-left 3x3 submatrix */ static inline void vmathSoaT3SetUpper3x3_V( VmathSoaTransform3 *result, VmathSoaMatrix3 mat3 ); /* * Get the upper-left 3x3 submatrix of a 3x4 transformation matrix */ static inline VmathSoaMatrix3 vmathSoaT3GetUpper3x3_V( VmathSoaTransform3 tfrm ); /* * Set translation component */ static inline void vmathSoaT3SetTranslation_V( VmathSoaTransform3 *result, VmathSoaVector3 translateVec ); /* * Get the translation component of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetTranslation_V( VmathSoaTransform3 tfrm ); /* * Set column 0 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol0_V( VmathSoaTransform3 *result, VmathSoaVector3 col0 ); /* * Set column 1 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol1_V( VmathSoaTransform3 *result, VmathSoaVector3 col1 ); /* * Set column 2 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol2_V( VmathSoaTransform3 *result, VmathSoaVector3 col2 ); /* * Set column 3 of a 3x4 transformation matrix */ static inline void vmathSoaT3SetCol3_V( VmathSoaTransform3 *result, VmathSoaVector3 col3 ); /* * Get column 0 of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetCol0_V( VmathSoaTransform3 tfrm ); /* * Get column 1 of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetCol1_V( VmathSoaTransform3 tfrm ); /* * Get column 2 of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetCol2_V( VmathSoaTransform3 tfrm ); /* * Get column 3 of a 3x4 transformation matrix */ static inline VmathSoaVector3 vmathSoaT3GetCol3_V( VmathSoaTransform3 tfrm ); /* * Set the column of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3SetCol_V( VmathSoaTransform3 *result, int col, VmathSoaVector3 vec ); /* * Set the row of a 3x4 transformation matrix referred to by the specified index */ static inline void vmathSoaT3SetRow_V( VmathSoaTransform3 *result, int row, VmathSoaVector4 vec ); /* * Get the column of a 3x4 transformation matrix referred to by the specified index */ static inline VmathSoaVector3 vmathSoaT3GetCol_V( VmathSoaTransform3 tfrm, int col ); /* * Get the row of a 3x4 transformation matrix referred to by the specified index */ static inline VmathSoaVector4 vmathSoaT3GetRow_V( VmathSoaTransform3 tfrm, int row ); /* * Set the element of a 3x4 transformation matrix referred to by column and row indices */ static inline void vmathSoaT3SetElem_V( VmathSoaTransform3 *result, int col, int row, vec_float4 val ); /* * Get the element of a 3x4 transformation matrix referred to by column and row indices */ static inline vec_float4 vmathSoaT3GetElem_V( VmathSoaTransform3 tfrm, int col, int row ); /* * Multiply a 3x4 transformation matrix by a 3-D vector */ static inline VmathSoaVector3 vmathSoaT3MulV3_V( VmathSoaTransform3 tfrm, VmathSoaVector3 vec ); /* * Multiply a 3x4 transformation matrix by a 3-D point */ static inline VmathSoaPoint3 vmathSoaT3MulP3_V( VmathSoaTransform3 tfrm, VmathSoaPoint3 pnt ); /* * Multiply two 3x4 transformation matrices */ static inline VmathSoaTransform3 vmathSoaT3Mul_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 ); /* * Construct an identity 3x4 transformation matrix */ static inline VmathSoaTransform3 vmathSoaT3MakeIdentity_V( ); /* * Construct a 3x4 transformation matrix to rotate around the x axis */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationX_V( vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the y axis */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationY_V( vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the z axis */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationZ_V( vec_float4 radians ); /* * Construct a 3x4 transformation matrix to rotate around the x, y, and z axes */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationZYX_V( VmathSoaVector3 radiansXYZ ); /* * Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationAxis_V( vec_float4 radians, VmathSoaVector3 unitVec ); /* * Construct a rotation matrix from a unit-length quaternion */ static inline VmathSoaTransform3 vmathSoaT3MakeRotationQ_V( VmathSoaQuat unitQuat ); /* * Construct a 3x4 transformation matrix to perform scaling */ static inline VmathSoaTransform3 vmathSoaT3MakeScale_V( VmathSoaVector3 scaleVec ); /* * Construct a 3x4 transformation matrix to perform translation */ static inline VmathSoaTransform3 vmathSoaT3MakeTranslation_V( VmathSoaVector3 translateVec ); /* * Append (post-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaTransform3 vmathSoaT3AppendScale_V( VmathSoaTransform3 tfrm, VmathSoaVector3 scaleVec ); /* * Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix * NOTE: * Faster than creating and multiplying a scale transformation matrix. */ static inline VmathSoaTransform3 vmathSoaT3PrependScale_V( VmathSoaVector3 scaleVec, VmathSoaTransform3 tfrm ); /* * Multiply two 3x4 transformation matrices per element */ static inline VmathSoaTransform3 vmathSoaT3MulPerElem_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1 ); /* * Compute the absolute value of a 3x4 transformation matrix per element */ static inline VmathSoaTransform3 vmathSoaT3AbsPerElem_V( VmathSoaTransform3 tfrm ); /* * Inverse of a 3x4 transformation matrix * NOTE: * Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. */ static inline VmathSoaTransform3 vmathSoaT3Inverse_V( VmathSoaTransform3 tfrm ); /* * Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix * NOTE: * This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. */ static inline VmathSoaTransform3 vmathSoaT3OrthoInverse_V( VmathSoaTransform3 tfrm ); /* * Conditionally select between two 3x4 transformation matrices * NOTE: * This function uses a conditional select instruction to avoid a branch. */ static inline VmathSoaTransform3 vmathSoaT3Select_V( VmathSoaTransform3 tfrm0, VmathSoaTransform3 tfrm1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG /* * Print a 3x4 transformation matrix * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaT3Print_V( VmathSoaTransform3 tfrm ); /* * Print a 3x4 transformation matrix and an associated string identifier * NOTE: * Function is only defined when _VECTORMATH_DEBUG is defined. */ static inline void vmathSoaT3Prints_V( VmathSoaTransform3 tfrm, const char *name ); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #include "vectormath_soa.h" #include "vec_soa_v.h" #include "quat_soa_v.h" #include "mat_soa_v.h" #endif ================================================ FILE: samples/vectormath/spu/cpp/boolInVec.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _BOOLINVEC_H #define _BOOLINVEC_H #include namespace Vectormath { class floatInVec; //-------------------------------------------------------------------------------------------------- // boolInVec class // class boolInVec { private: vec_uint4 mData; inline boolInVec(vec_uint4 vec); public: inline boolInVec() {} // matches standard type conversions // inline boolInVec(floatInVec vec); // explicit cast from bool // explicit inline boolInVec(bool scalar); #ifdef _VECTORMATH_NO_SCALAR_CAST // explicit cast to bool // inline bool getAsBool() const; #else // implicit cast to bool // inline operator bool() const; #endif // get vector data // bool value is in the 0 word slot of vector as 0 (false) or -1 (true) // inline vec_uint4 get128() const; // operators // inline const boolInVec operator ! () const; inline boolInVec& operator = (boolInVec vec); inline boolInVec& operator &= (boolInVec vec); inline boolInVec& operator ^= (boolInVec vec); inline boolInVec& operator |= (boolInVec vec); // friend functions // friend inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); friend inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); friend inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); friend inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); friend inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); friend inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); friend inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); }; //-------------------------------------------------------------------------------------------------- // boolInVec functions // // operators // inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); // select between vec0 and vec1 using boolInVec. // false selects vec0, true selects vec1 // inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); } // namespace Vectormath //-------------------------------------------------------------------------------------------------- // boolInVec implementation // #include "floatInVec.h" namespace Vectormath { inline boolInVec::boolInVec(vec_uint4 vec) { mData = vec; } inline boolInVec::boolInVec(floatInVec vec) { *this = (vec != floatInVec(0.0f)); } inline boolInVec::boolInVec(bool scalar) { mData = spu_promote((unsigned int)-scalar, 0); } #ifdef _VECTORMATH_NO_SCALAR_CAST inline bool boolInVec::getAsBool() const #else inline boolInVec::operator bool() const #endif { return (bool)spu_extract(mData, 0); } inline vec_uint4 boolInVec::get128() const { return mData; } inline const boolInVec boolInVec::operator ! () const { return boolInVec(spu_nor(mData, mData)); } inline boolInVec& boolInVec::operator = (boolInVec vec) { mData = vec.mData; return *this; } inline boolInVec& boolInVec::operator &= (boolInVec vec) { *this = *this & vec; return *this; } inline boolInVec& boolInVec::operator ^= (boolInVec vec) { *this = *this ^ vec; return *this; } inline boolInVec& boolInVec::operator |= (boolInVec vec) { *this = *this | vec; return *this; } inline const boolInVec operator == (boolInVec vec0, boolInVec vec1) { return boolInVec(spu_cmpeq(vec0.get128(), vec1.get128())); } inline const boolInVec operator != (boolInVec vec0, boolInVec vec1) { return !(vec0 == vec1); } inline const boolInVec operator & (boolInVec vec0, boolInVec vec1) { return boolInVec(spu_and(vec0.get128(), vec1.get128())); } inline const boolInVec operator | (boolInVec vec0, boolInVec vec1) { return boolInVec(spu_or(vec0.get128(), vec1.get128())); } inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1) { return boolInVec(spu_xor(vec0.get128(), vec1.get128())); } inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1) { return boolInVec(spu_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); } } // namespace Vectormath #endif // boolInVec_h ================================================ FILE: samples/vectormath/spu/cpp/floatInVec.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _FLOATINVEC_H #define _FLOATINVEC_H #include #include #include #undef bool namespace Vectormath { class boolInVec; //-------------------------------------------------------------------------------------------------- // floatInVec class // class floatInVec { private: vec_float4 mData; inline floatInVec(vec_float4 vec); public: inline floatInVec() {} // matches standard type conversions // inline floatInVec(boolInVec vec); // construct from a slot of vec_float4 // inline floatInVec(vec_float4 vec, int slot); // explicit cast from float // explicit inline floatInVec(float scalar); #ifdef _VECTORMATH_NO_SCALAR_CAST // explicit cast to float // inline float getAsFloat() const; #else // implicit cast to float // inline operator float() const; #endif // get vector data // float value is in 0 word slot of vector // inline vec_float4 get128() const; // operators // inline const floatInVec operator ++ (int); inline const floatInVec operator -- (int); inline floatInVec& operator ++ (); inline floatInVec& operator -- (); inline const floatInVec operator - () const; inline floatInVec& operator = (floatInVec vec); inline floatInVec& operator *= (floatInVec vec); inline floatInVec& operator /= (floatInVec vec); inline floatInVec& operator += (floatInVec vec); inline floatInVec& operator -= (floatInVec vec); // friend functions // friend inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); friend inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); friend inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); friend inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); friend inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); }; //-------------------------------------------------------------------------------------------------- // floatInVec functions // // operators // inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); // select between vec0 and vec1 using boolInVec. // false selects vec0, true selects vec1 // inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); } // namespace Vectormath //-------------------------------------------------------------------------------------------------- // floatInVec implementation // #include "boolInVec.h" namespace Vectormath { inline floatInVec::floatInVec(vec_float4 vec) { mData = vec; } inline floatInVec::floatInVec(boolInVec vec) { mData = spu_sel(spu_splats(0.0f), spu_splats(1.0f), vec.get128()); } inline floatInVec::floatInVec(vec_float4 vec, int slot) { mData = spu_promote(spu_extract(vec, slot), 0); } inline floatInVec::floatInVec(float scalar) { mData = spu_promote(scalar, 0); } #ifdef _VECTORMATH_NO_SCALAR_CAST inline float floatInVec::getAsFloat() const #else inline floatInVec::operator float() const #endif { return spu_extract(mData,0); } inline vec_float4 floatInVec::get128() const { return mData; } inline const floatInVec floatInVec::operator ++ (int) { vec_float4 olddata = mData; operator ++(); return floatInVec(olddata); } inline const floatInVec floatInVec::operator -- (int) { vec_float4 olddata = mData; operator --(); return floatInVec(olddata); } inline floatInVec& floatInVec::operator ++ () { *this += floatInVec(1.0f); return *this; } inline floatInVec& floatInVec::operator -- () { *this -= floatInVec(1.0f); return *this; } inline const floatInVec floatInVec::operator - () const { return floatInVec((vec_float4)spu_xor((vec_uint4)mData, spu_splats(0x80000000))); } inline floatInVec& floatInVec::operator = (floatInVec vec) { mData = vec.mData; return *this; } inline floatInVec& floatInVec::operator *= (floatInVec vec) { *this = *this * vec; return *this; } inline floatInVec& floatInVec::operator /= (floatInVec vec) { *this = *this / vec; return *this; } inline floatInVec& floatInVec::operator += (floatInVec vec) { *this = *this + vec; return *this; } inline floatInVec& floatInVec::operator -= (floatInVec vec) { *this = *this - vec; return *this; } inline const floatInVec operator * (floatInVec vec0, floatInVec vec1) { return floatInVec(spu_mul(vec0.get128(), vec1.get128())); } inline const floatInVec operator / (floatInVec num, floatInVec den) { return floatInVec(divf4(num.get128(), den.get128())); } inline const floatInVec operator + (floatInVec vec0, floatInVec vec1) { return floatInVec(spu_add(vec0.get128(), vec1.get128())); } inline const floatInVec operator - (floatInVec vec0, floatInVec vec1) { return floatInVec(spu_sub(vec0.get128(), vec1.get128())); } inline const boolInVec operator < (floatInVec vec0, floatInVec vec1) { return boolInVec(spu_cmpgt(vec1.get128(), vec0.get128())); } inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1) { return !(vec0 > vec1); } inline const boolInVec operator > (floatInVec vec0, floatInVec vec1) { return boolInVec(spu_cmpgt(vec0.get128(), vec1.get128())); } inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1) { return !(vec0 < vec1); } inline const boolInVec operator == (floatInVec vec0, floatInVec vec1) { return boolInVec(spu_cmpeq(vec0.get128(), vec1.get128())); } inline const boolInVec operator != (floatInVec vec0, floatInVec vec1) { return !(vec0 == vec1); } inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1) { return floatInVec(spu_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); } } // namespace Vectormath #endif // floatInVec_h ================================================ FILE: samples/vectormath/spu/cpp/mat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_AOS_CPP_H #define _VECTORMATH_MAT_AOS_CPP_H namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // Constants // for shuffles, words are labeled [x,y,z,w] [a,b,c,d] #define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_0ZB0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_C0X0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_YA00 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_Z }) #define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X }) #define _VECTORMATH_SHUF_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y }) #define _VECTORMATH_SHUF_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZAY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_BZX0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_0ZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A }) #define _VECTORMATH_SHUF_Z0XB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YX0C ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_0, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_CZD0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_BBY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_PI_OVER_2 1.570796327f //----------------------------------------------------------------------------- // Definitions inline Matrix3::Matrix3( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; } inline Matrix3::Matrix3( float scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); } inline Matrix3::Matrix3( Quat unitQuat ) { vec_float4 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); vec_uint4 select_x = (vec_uint4)spu_maskb(0xf000); vec_uint4 select_z = (vec_uint4)spu_maskb(0x00f0); xyzw_2 = spu_add( unitQuat.get128(), unitQuat.get128() ); wwww = spu_shuffle( unitQuat.get128(), unitQuat.get128(), shuffle_wwww ); yzxw = spu_shuffle( unitQuat.get128(), unitQuat.get128(), _VECTORMATH_SHUF_YZXW ); zxyw = spu_shuffle( unitQuat.get128(), unitQuat.get128(), _VECTORMATH_SHUF_ZXYW ); yzxw_2 = spu_shuffle( xyzw_2, xyzw_2, _VECTORMATH_SHUF_YZXW ); zxyw_2 = spu_shuffle( xyzw_2, xyzw_2, _VECTORMATH_SHUF_ZXYW ); tmp0 = spu_mul( yzxw_2, wwww ); tmp1 = spu_nmsub( yzxw, yzxw_2, spu_splats(1.0f) ); tmp2 = spu_mul( yzxw, xyzw_2 ); tmp0 = spu_madd( zxyw, xyzw_2, tmp0 ); tmp1 = spu_nmsub( zxyw, zxyw_2, tmp1 ); tmp2 = spu_nmsub( zxyw_2, wwww, tmp2 ); tmp3 = spu_sel( tmp0, tmp1, select_x ); tmp4 = spu_sel( tmp1, tmp2, select_x ); tmp5 = spu_sel( tmp2, tmp0, select_x ); mCol0 = Vector3( spu_sel( tmp3, tmp2, select_z ) ); mCol1 = Vector3( spu_sel( tmp4, tmp0, select_z ) ); mCol2 = Vector3( spu_sel( tmp5, tmp1, select_z ) ); } inline Matrix3::Matrix3( Vector3 _col0, Vector3 _col1, Vector3 _col2 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; } inline Matrix3 & Matrix3::setCol0( Vector3 _col0 ) { mCol0 = _col0; return *this; } inline Matrix3 & Matrix3::setCol1( Vector3 _col1 ) { mCol1 = _col1; return *this; } inline Matrix3 & Matrix3::setCol2( Vector3 _col2 ) { mCol2 = _col2; return *this; } inline Matrix3 & Matrix3::setCol( int col, Vector3 vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix3 & Matrix3::setRow( int row, Vector3 vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); return *this; } inline Matrix3 & Matrix3::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline float Matrix3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Matrix3::getCol0( ) const { return mCol0; } inline const Vector3 Matrix3::getCol1( ) const { return mCol1; } inline const Vector3 Matrix3::getCol2( ) const { return mCol2; } inline const Vector3 Matrix3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector3 Matrix3::getRow( int row ) const { return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); } inline Vector3 & Matrix3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Matrix3::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; return *this; } inline const Matrix3 transpose( const Matrix3 & mat ) { vec_float4 tmp0, tmp1, res0, res1, res2; tmp0 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_ZCWD ); res0 = spu_shuffle( tmp0, mat.getCol1().get128(), _VECTORMATH_SHUF_XAYB ); res1 = spu_shuffle( tmp0, mat.getCol1().get128(), _VECTORMATH_SHUF_ZBW0 ); res2 = spu_shuffle( tmp1, mat.getCol1().get128(), _VECTORMATH_SHUF_XCY0 ); return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 inverse( const Matrix3 & mat ) { vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() ); tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() ); tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() ); dot = _vmathVfDot3( tmp2, mat.getCol2().get128() ); dot = spu_shuffle( dot, dot, (vec_uchar16)spu_splats(0x00010203) ); invdet = recipf4( dot ); tmp3 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_XAYB ); tmp4 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_ZCWD ); inv0 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_XAYB ); inv1 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_ZBW0 ); inv2 = spu_shuffle( tmp4, tmp1, _VECTORMATH_SHUF_XCY0 ); inv0 = spu_mul( inv0, invdet ); inv1 = spu_mul( inv1, invdet ); inv2 = spu_mul( inv2, invdet ); return Matrix3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ) ); } inline float determinant( const Matrix3 & mat ) { return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); } inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const { return Matrix3( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ) ); } inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const { return Matrix3( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) { *this = *this + mat; return *this; } inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) { *this = *this - mat; return *this; } inline const Matrix3 Matrix3::operator -( ) const { return Matrix3( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ) ); } inline const Matrix3 absPerElem( const Matrix3 & mat ) { return Matrix3( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ) ); } inline const Matrix3 Matrix3::operator *( float scalar ) const { return Matrix3( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ) ); } inline Matrix3 & Matrix3::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) { return mat * scalar; } inline const Vector3 Matrix3::operator *( Vector3 vec ) const { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx ); yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy ); zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz ); res = spu_mul( mCol0.get128(), xxxx ); res = spu_madd( mCol1.get128(), yyyy, res ); res = spu_madd( mCol2.get128(), zzzz, res ); return Vector3( res ); } inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const { return Matrix3( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) { *this = *this * mat; return *this; } inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) { return Matrix3( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ) ); } inline const Matrix3 Matrix3::identity( ) { return Matrix3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationX( float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = (vec_uint4)spu_maskb(0x0f00); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res1 = spu_sel( zero, c, select_y ); res1 = spu_sel( res1, s, select_z ); res2 = spu_sel( zero, negatef4(s), select_y ); res2 = spu_sel( res2, c, select_z ); return Matrix3( Vector3::xAxis( ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 Matrix3::rotationY( float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, negatef4(s), select_z ); res2 = spu_sel( zero, s, select_x ); res2 = spu_sel( res2, c, select_z ); return Matrix3( Vector3( res0 ), Vector3::yAxis( ), Vector3( res2 ) ); } inline const Matrix3 Matrix3::rotationZ( float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_y = (vec_uint4)spu_maskb(0x0f00); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, s, select_y ); res1 = spu_sel( zero, negatef4(s), select_x ); res1 = spu_sel( res1, c, select_y ); return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationZYX( Vector3 radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); angles = radiansXYZ.get128(); angles = spu_insert( 0.0f, angles, 3 ); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 ); Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 ); Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 ); Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 ); X0 = spu_shuffle( s, s, shuffle_xxxx ); X1 = spu_shuffle( c, c, shuffle_xxxx ); tmp = spu_mul( Z0, Y1 ); return Matrix3( Vector3( spu_mul( Z0, Y0 ) ), Vector3( spu_madd( Z1, X1, spu_mul( tmp, X0 ) ) ), Vector3( spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ) ) ); } inline const Matrix3 Matrix3::rotation( float radians, Vector3 unitVec ) { vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); axis = unitVec.get128(); sincosf4( spu_splats( radians ), &s, &c ); xxxx = spu_shuffle( axis, axis, shuffle_xxxx ); yyyy = spu_shuffle( axis, axis, shuffle_yyyy ); zzzz = spu_shuffle( axis, axis, shuffle_zzzz ); oneMinusC = spu_sub( spu_splats(1.0f), c ); axisS = spu_mul( axis, s ); negAxisS = negatef4( axisS ); tmp0 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_0ZB0 ); tmp1 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_C0X0 ); tmp2 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_YA00 ); tmp0 = spu_sel( tmp0, c, (vec_uint4)spu_maskb(0xf000) ); tmp1 = spu_sel( tmp1, c, (vec_uint4)spu_maskb(0x0f00) ); tmp2 = spu_sel( tmp2, c, (vec_uint4)spu_maskb(0x00f0) ); return Matrix3( Vector3( spu_madd( spu_mul( axis, xxxx ), oneMinusC, tmp0 ) ), Vector3( spu_madd( spu_mul( axis, yyyy ), oneMinusC, tmp1 ) ), Vector3( spu_madd( spu_mul( axis, zzzz ), oneMinusC, tmp2 ) ) ); } inline const Matrix3 Matrix3::rotation( Quat unitQuat ) { return Matrix3( unitQuat ); } inline const Matrix3 Matrix3::scale( Vector3 scaleVec ) { vec_float4 zero = spu_splats(0.0f); return Matrix3( Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0xf000) ) ), Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x0f00) ) ), Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x00f0) ) ) ); } inline const Matrix3 appendScale( const Matrix3 & mat, Vector3 scaleVec ) { return Matrix3( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ) ); } inline const Matrix3 prependScale( Vector3 scaleVec, const Matrix3 & mat ) { return Matrix3( mulPerElem( mat.getCol0(), scaleVec ), mulPerElem( mat.getCol1(), scaleVec ), mulPerElem( mat.getCol2(), scaleVec ) ); } inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) { return Matrix3( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix3 & mat ) { print( mat.getRow( 0 ) ); print( mat.getRow( 1 ) ); print( mat.getRow( 2 ) ); } inline void print( const Matrix3 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Matrix4::Matrix4( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; } inline Matrix4::Matrix4( float scalar ) { mCol0 = Vector4( scalar ); mCol1 = Vector4( scalar ); mCol2 = Vector4( scalar ); mCol3 = Vector4( scalar ); } inline Matrix4::Matrix4( const Transform3 & mat ) { mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( mat.getCol3(), 1.0f ); } inline Matrix4::Matrix4( Vector4 _col0, Vector4 _col1, Vector4 _col2, Vector4 _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Matrix4::Matrix4( const Matrix3 & mat, Vector3 translateVec ) { mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( translateVec, 1.0f ); } inline Matrix4::Matrix4( Quat unitQuat, Vector3 translateVec ) { Matrix3 mat; mat = Matrix3( unitQuat ); mCol0 = Vector4( mat.getCol0(), 0.0f ); mCol1 = Vector4( mat.getCol1(), 0.0f ); mCol2 = Vector4( mat.getCol2(), 0.0f ); mCol3 = Vector4( translateVec, 1.0f ); } inline Matrix4 & Matrix4::setCol0( Vector4 _col0 ) { mCol0 = _col0; return *this; } inline Matrix4 & Matrix4::setCol1( Vector4 _col1 ) { mCol1 = _col1; return *this; } inline Matrix4 & Matrix4::setCol2( Vector4 _col2 ) { mCol2 = _col2; return *this; } inline Matrix4 & Matrix4::setCol3( Vector4 _col3 ) { mCol3 = _col3; return *this; } inline Matrix4 & Matrix4::setCol( int col, Vector4 vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix4 & Matrix4::setRow( int row, Vector4 vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Matrix4 & Matrix4::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline float Matrix4::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector4 Matrix4::getCol0( ) const { return mCol0; } inline const Vector4 Matrix4::getCol1( ) const { return mCol1; } inline const Vector4 Matrix4::getCol2( ) const { return mCol2; } inline const Vector4 Matrix4::getCol3( ) const { return mCol3; } inline const Vector4 Matrix4::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Matrix4::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector4 & Matrix4::operator []( int col ) { return *(&mCol0 + col); } inline const Vector4 Matrix4::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; return *this; } inline const Matrix4 transpose( const Matrix4 & mat ) { vec_float4 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; tmp0 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mat.getCol1().get128(), mat.getCol3().get128(), _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( mat.getCol1().get128(), mat.getCol3().get128(), _VECTORMATH_SHUF_ZCWD ); res0 = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); res1 = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); res2 = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); res3 = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ); return Matrix4( Vector4( res0 ), Vector4( res1 ), Vector4( res2 ), Vector4( res3 ) ); } inline const Matrix4 inverse( const Matrix4 & mat ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 in0, in1, in2, in3; vec_float4 tmp0, tmp1, tmp2, tmp3; vec_float4 cof0, cof1, cof2, cof3; vec_float4 t0, t1, t2, t3; vec_float4 t01, t02, t03, t12, t23; vec_float4 t1r, t2r; vec_float4 t01r, t02r, t03r, t12r, t23r; vec_float4 t1r3, t1r3r; vec_float4 det, det1, det2, det3, invdet; in0 = mat.getCol0().get128(); in1 = mat.getCol1().get128(); in2 = mat.getCol2().get128(); in3 = mat.getCol3().get128(); /* Perform transform of the input matrix of the form: * A B C D * E F G H * I J K L * M N O P * * The pseudo transpose of the input matrix is trans: * A E I M * J N B F * C G K O * L P D H */ tmp0 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_XAZC); /* A E C G */ tmp1 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_XAZC); /* I M K O */ tmp2 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_YBWD); /* B F D H */ tmp3 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_YBWD); /* J N L P */ t0 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_XYAB); /* A E I M */ t1 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_XYAB); /* J N B F */ t2 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_ZWCD); /* C G K O */ t3 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_ZWCD); /* L P D H */ /* Generate a cofactor matrix. The computed cofactors reside in * cof0, cof1, cof2, cof3. */ t23 = spu_mul(t2, t3); /* CL GP KD OH */ t23 = spu_shuffle(t23, t23, _VECTORMATH_SHUF_YXWZ); /* GP CL OH KD */ cof0 = spu_mul(t1, t23); /* JGP NCL BOH FKD */ cof1 = spu_mul(t0, t23); /* AGP ECL IOH MKD */ t23r = spu_rlqwbyte(t23, 8); /* OH KD GP CL */ cof0 = spu_msub(t1, t23r, cof0); /* JOH NKD BGP FCL - cof0 */ cof1 = spu_msub(t0, t23r, cof1); /* AOH EKD IGP MCL - cof1 */ cof1 = spu_rlqwbyte(cof1, 8); /* IGP MCL AOH EKD - IOH MKD AGP ECL */ t12 = spu_mul(t1, t2); /* JC NG BK FO */ t12 = spu_shuffle(t12, t12, _VECTORMATH_SHUF_YXWZ); /* NG JC FO BK */ cof0 = spu_madd(t3, t12, cof0); /* LNG PJC DFO HBK + cof0 */ cof3 = spu_mul(t0, t12); /* ANG EJC IFO MBK */ t12r = spu_rlqwbyte(t12, 8); /* FO BK NG JC */ cof0 = spu_nmsub(t3, t12r, cof0); /* cof0 - LFO PBK DNG HJC */ cof3 = spu_msub(t0, t12r, cof3); /* AFO EBK ING MJC - cof3 */ cof3 = spu_rlqwbyte(cof3, 8); /* ING MJC AFO EBK - IFO MBK ANG EJC */ t1r = spu_rlqwbyte(t1, 8); /* B F J N */ t2r = spu_rlqwbyte(t2, 8); /* K O C G */ t1r3 = spu_mul(t1r, t3); /* BL FP JD NH */ t1r3 = spu_shuffle(t1r3, t1r3, _VECTORMATH_SHUF_YXWZ); /* FP BL NH JD */ cof0 = spu_madd(t2r, t1r3, cof0); /* KFP OBL CNH GJD + cof0 */ cof2 = spu_mul(t0, t1r3); /* AFP EBL INH MJD */ t1r3r = spu_rlqwbyte(t1r3, 8); /* NH JD FP BL */ cof0 = spu_nmsub(t2r, t1r3r, cof0); /* cof0 - KNH OJD CFP GBL */ cof2 = spu_msub(t0, t1r3r, cof2); /* ANH EJD IFP MBL - cof2 */ cof2 = spu_rlqwbyte(cof2, 8); /* IFP MBL ANH EJD - INH MJD AFP EBL */ t01 = spu_mul(t0, t1); /* AJ EN IB MF */ t01 = spu_shuffle(t01, t01, _VECTORMATH_SHUF_YXWZ); /* EN AJ MF IB */ cof2 = spu_madd(t3, t01, cof2); /* LEN PAJ DMF HIB + cof2 */ cof3 = spu_msub(t2r, t01, cof3); /* KEN OAJ CMF GIB - cof3 */ t01r = spu_rlqwbyte(t01, 8); /* MF IB EN AJ */ cof2 = spu_msub(t3, t01r, cof2); /* LMF PIB DEN HAJ - cof2 */ cof3 = spu_nmsub(t2r, t01r, cof3); /* cof3 - KMF OIB CEN GAJ */ t03 = spu_mul(t0, t3); /* AL EP ID MH */ t03 = spu_shuffle(t03, t03, _VECTORMATH_SHUF_YXWZ); /* EP AL MH ID */ cof1 = spu_nmsub(t2r, t03, cof1); /* cof1 - KEP OAL CMH GID */ cof2 = spu_madd(t1, t03, cof2); /* JEP NAL BMH FID + cof2 */ t03r = spu_rlqwbyte(t03, 8); /* MH ID EP AL */ cof1 = spu_madd(t2r, t03r, cof1); /* KMH OID CEP GAL + cof1 */ cof2 = spu_nmsub(t1, t03r, cof2); /* cof2 - JMH NID BEP FAL */ t02 = spu_mul(t0, t2r); /* AK EO IC MG */ t02 = spu_shuffle(t02, t02, _VECTORMATH_SHUF_YXWZ); /* E0 AK MG IC */ cof1 = spu_madd(t3, t02, cof1); /* LEO PAK DMG HIC + cof1 */ cof3 = spu_nmsub(t1, t02, cof3); /* cof3 - JEO NAK BMG FIC */ t02r = spu_rlqwbyte(t02, 8); /* MG IC EO AK */ cof1 = spu_nmsub(t3, t02r, cof1); /* cof1 - LMG PIC DEO HAK */ cof3 = spu_madd(t1, t02r, cof3); /* JMG NIC BEO FAK + cof3 */ /* Compute the determinant of the matrix * * det = sum_across(t0 * cof0); * * We perform a sum across the entire vector so that * we don't have to splat the result when multiplying the * cofactors by the inverse of the determinant. */ det = spu_mul(t0, cof0); det1 = spu_rlqwbyte(det, 4); det2 = spu_rlqwbyte(det, 8); det3 = spu_rlqwbyte(det, 12); det = spu_add(det, det1); det2 = spu_add(det2, det3); det = spu_add(det, det2); /* Compute the reciprocal of the determinant. */ invdet = recipf4(det); /* Multiply the cofactors by the reciprocal of the determinant. */ return Matrix4( Vector4( spu_mul(cof0, invdet) ), Vector4( spu_mul(cof1, invdet) ), Vector4( spu_mul(cof2, invdet) ), Vector4( spu_mul(cof3, invdet) ) ); } inline const Matrix4 affineInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( inverse( affineMat ) ); } inline const Matrix4 orthoInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( orthoInverse( affineMat ) ); } inline float determinant( const Matrix4 & mat ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 in0, in1, in2, in3; vec_float4 tmp0, tmp1, tmp2, tmp3; vec_float4 cof0; vec_float4 t0, t1, t2, t3; vec_float4 t12, t23; vec_float4 t1r, t2r; vec_float4 t12r, t23r; vec_float4 t1r3, t1r3r; in0 = mat.getCol0().get128(); in1 = mat.getCol1().get128(); in2 = mat.getCol2().get128(); in3 = mat.getCol3().get128(); /* Perform transform of the input matrix of the form: * A B C D * E F G H * I J K L * M N O P * * The pseudo transpose of the input matrix is trans: * A E I M * J N B F * C G K O * L P D H */ tmp0 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_XAZC); /* A E C G */ tmp1 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_XAZC); /* I M K O */ tmp2 = spu_shuffle(in0, in1, _VECTORMATH_SHUF_YBWD); /* B F D H */ tmp3 = spu_shuffle(in2, in3, _VECTORMATH_SHUF_YBWD); /* J N L P */ t0 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_XYAB); /* A E I M */ t1 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_XYAB); /* J N B F */ t2 = spu_shuffle(tmp0, tmp1, _VECTORMATH_SHUF_ZWCD); /* C G K O */ t3 = spu_shuffle(tmp3, tmp2, _VECTORMATH_SHUF_ZWCD); /* L P D H */ /* Generate a cofactor matrix. The computed cofactors reside in * cof0, cof1, cof2, cof3. */ t23 = spu_mul(t2, t3); /* CL GP KD OH */ t23 = spu_shuffle(t23, t23, _VECTORMATH_SHUF_YXWZ); /* GP CL OH KD */ cof0 = spu_mul(t1, t23); /* JGP NCL BOH FKD */ t23r = spu_rlqwbyte(t23, 8); /* OH KD GP CL */ cof0 = spu_msub(t1, t23r, cof0); /* JOH NKD BGP FCL - cof0 */ t12 = spu_mul(t1, t2); /* JC NG BK FO */ t12 = spu_shuffle(t12, t12, _VECTORMATH_SHUF_YXWZ); /* NG JC FO BK */ cof0 = spu_madd(t3, t12, cof0); /* LNG PJC DFO HBK + cof0 */ t12r = spu_rlqwbyte(t12, 8); /* FO BK NG JC */ cof0 = spu_nmsub(t3, t12r, cof0); /* cof0 - LFO PBK DNG HJC */ t1r = spu_rlqwbyte(t1, 8); /* B F J N */ t2r = spu_rlqwbyte(t2, 8); /* K O C G */ t1r3 = spu_mul(t1r, t3); /* BL FP JD NH */ t1r3 = spu_shuffle(t1r3, t1r3, _VECTORMATH_SHUF_YXWZ); /* FP BL NH JD */ cof0 = spu_madd(t2r, t1r3, cof0); /* KFP OBL CNH GJD + cof0 */ t1r3r = spu_rlqwbyte(t1r3, 8); /* NH JD FP BL */ cof0 = spu_nmsub(t2r, t1r3r, cof0); /* cof0 - KNH OJD CFP GBL */ return spu_extract( _vmathVfDot4(t0,cof0), 0 ); } inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const { return Matrix4( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ), ( mCol3 + mat.mCol3 ) ); } inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const { return Matrix4( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ), ( mCol3 - mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) { *this = *this + mat; return *this; } inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) { *this = *this - mat; return *this; } inline const Matrix4 Matrix4::operator -( ) const { return Matrix4( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ), ( -mCol3 ) ); } inline const Matrix4 absPerElem( const Matrix4 & mat ) { return Matrix4( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ), absPerElem( mat.getCol3() ) ); } inline const Matrix4 Matrix4::operator *( float scalar ) const { return Matrix4( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ), ( mCol3 * scalar ) ); } inline Matrix4 & Matrix4::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) { return mat * scalar; } inline const Vector4 Matrix4::operator *( Vector4 vec ) const { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz, wwww; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx ); yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy ); zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz ); wwww = spu_shuffle( vec.get128(), vec.get128(), shuffle_wwww ); tmp0 = spu_mul( mCol0.get128(), xxxx ); tmp1 = spu_mul( mCol1.get128(), yyyy ); tmp0 = spu_madd( mCol2.get128(), zzzz, tmp0 ); tmp1 = spu_madd( mCol3.get128(), wwww, tmp1 ); res = spu_add( tmp0, tmp1 ); return Vector4( res ); } inline const Vector4 Matrix4::operator *( Vector3 vec ) const { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx ); yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy ); zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz ); res = spu_mul( mCol0.get128(), xxxx ); res = spu_madd( mCol1.get128(), yyyy, res ); res = spu_madd( mCol2.get128(), zzzz, res ); return Vector4( res ); } inline const Vector4 Matrix4::operator *( Point3 pnt ) const { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_xxxx ); yyyy = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_yyyy ); zzzz = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_zzzz ); tmp0 = spu_mul( mCol0.get128(), xxxx ); tmp1 = spu_mul( mCol1.get128(), yyyy ); tmp0 = spu_madd( mCol2.get128(), zzzz, tmp0 ); tmp1 = spu_add( mCol3.get128(), tmp1 ); res = spu_add( tmp0, tmp1 ); return Vector4( res ); } inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const { return Matrix4( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ), ( *this * mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) { *this = *this * mat; return *this; } inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const { return Matrix4( ( *this * tfrm.getCol0() ), ( *this * tfrm.getCol1() ), ( *this * tfrm.getCol2() ), ( *this * Point3( tfrm.getCol3() ) ) ); } inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) { return Matrix4( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ), mulPerElem( mat0.getCol3(), mat1.getCol3() ) ); } inline const Matrix4 Matrix4::identity( ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) { mCol0.setXYZ( mat3.getCol0() ); mCol1.setXYZ( mat3.getCol1() ); mCol2.setXYZ( mat3.getCol2() ); return *this; } inline const Matrix3 Matrix4::getUpper3x3( ) const { return Matrix3( mCol0.getXYZ( ), mCol1.getXYZ( ), mCol2.getXYZ( ) ); } inline Matrix4 & Matrix4::setTranslation( Vector3 translateVec ) { mCol3.setXYZ( translateVec ); return *this; } inline const Vector3 Matrix4::getTranslation( ) const { return mCol3.getXYZ( ); } inline const Matrix4 Matrix4::rotationX( float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = (vec_uint4)spu_maskb(0x0f00); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res1 = spu_sel( zero, c, select_y ); res1 = spu_sel( res1, s, select_z ); res2 = spu_sel( zero, negatef4(s), select_y ); res2 = spu_sel( res2, c, select_z ); return Matrix4( Vector4::xAxis( ), Vector4( res1 ), Vector4( res2 ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationY( float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, negatef4(s), select_z ); res2 = spu_sel( zero, s, select_x ); res2 = spu_sel( res2, c, select_z ); return Matrix4( Vector4( res0 ), Vector4::yAxis( ), Vector4( res2 ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZ( float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_y = (vec_uint4)spu_maskb(0x0f00); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, s, select_y ); res1 = spu_sel( zero, negatef4(s), select_x ); res1 = spu_sel( res1, c, select_y ); return Matrix4( Vector4( res0 ), Vector4( res1 ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZYX( Vector3 radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); angles = radiansXYZ.get128(); angles = spu_insert( 0.0f, angles, 3 ); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 ); Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 ); Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 ); Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 ); X0 = spu_shuffle( s, s, shuffle_xxxx ); X1 = spu_shuffle( c, c, shuffle_xxxx ); tmp = spu_mul( Z0, Y1 ); return Matrix4( Vector4( spu_mul( Z0, Y0 ) ), Vector4( spu_madd( Z1, X1, spu_mul( tmp, X0 ) ) ), Vector4( spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( float radians, Vector3 unitVec ) { vec_float4 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2, zeroW; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); axis = unitVec.get128(); sincosf4( spu_splats( radians ), &s, &c ); xxxx = spu_shuffle( axis, axis, shuffle_xxxx ); yyyy = spu_shuffle( axis, axis, shuffle_yyyy ); zzzz = spu_shuffle( axis, axis, shuffle_zzzz ); oneMinusC = spu_sub( spu_splats(1.0f), c ); axisS = spu_mul( axis, s ); negAxisS = negatef4( axisS ); tmp0 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_0ZB0 ); tmp1 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_C0X0 ); tmp2 = spu_shuffle( axisS, negAxisS, _VECTORMATH_SHUF_YA00 ); tmp0 = spu_sel( tmp0, c, (vec_uint4)spu_maskb(0xf000) ); tmp1 = spu_sel( tmp1, c, (vec_uint4)spu_maskb(0x0f00) ); tmp2 = spu_sel( tmp2, c, (vec_uint4)spu_maskb(0x00f0) ); zeroW = (vec_float4)spu_maskb(0x000f); axis = spu_andc( axis, zeroW ); return Matrix4( Vector4( spu_madd( spu_mul( axis, xxxx ), oneMinusC, tmp0 ) ), Vector4( spu_madd( spu_mul( axis, yyyy ), oneMinusC, tmp1 ) ), Vector4( spu_madd( spu_mul( axis, zzzz ), oneMinusC, tmp2 ) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( Quat unitQuat ) { return Matrix4( Transform3::rotation( unitQuat ) ); } inline const Matrix4 Matrix4::scale( Vector3 scaleVec ) { vec_float4 zero = spu_splats(0.0f); return Matrix4( Vector4( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0xf000) ) ), Vector4( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x0f00) ) ), Vector4( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x00f0) ) ), Vector4::wAxis( ) ); } inline const Matrix4 appendScale( const Matrix4 & mat, Vector3 scaleVec ) { return Matrix4( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ), mat.getCol3() ); } inline const Matrix4 prependScale( Vector3 scaleVec, const Matrix4 & mat ) { Vector4 scale4; scale4 = Vector4( scaleVec, 1.0f ); return Matrix4( mulPerElem( mat.getCol0(), scale4 ), mulPerElem( mat.getCol1(), scale4 ), mulPerElem( mat.getCol2(), scale4 ), mulPerElem( mat.getCol3(), scale4 ) ); } inline const Matrix4 Matrix4::translation( Vector3 translateVec ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4( translateVec, 1.0f ) ); } inline const Matrix4 Matrix4::lookAt( Point3 eyePos, Point3 lookAtPos, Vector3 upVec ) { Matrix4 m4EyeFrame; Vector3 v3X, v3Y, v3Z; v3Y = normalize( upVec ); v3Z = normalize( ( eyePos - lookAtPos ) ); v3X = normalize( cross( v3Y, v3Z ) ); v3Y = cross( v3Z, v3X ); m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); return orthoInverse( m4EyeFrame ); } inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) { float f, rangeInv; vec_float4 zero, col0, col1, col2, col3; f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f ); rangeInv = 1.0f / ( zNear - zFar ); zero = spu_splats(0.0f); col0 = zero; col1 = zero; col2 = zero; col3 = zero; col0 = spu_insert( f / aspect, col0, 0 ); col1 = spu_insert( f, col1, 1 ); col2 = spu_insert( ( zNear + zFar ) * rangeInv, col2, 2 ); col2 = spu_insert( -1.0f, col2, 3 ); col3 = spu_insert( zNear * zFar * rangeInv * 2.0f, col3, 2 ); return Matrix4( Vector4( col0 ), Vector4( col1 ), Vector4( col2 ), Vector4( col3 ) ); } inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 lbf, rtn; vec_float4 diff, sum, inv_diff; vec_float4 diagonal, column, near2; vec_float4 zero = spu_splats(0.0f); lbf = spu_shuffle( spu_promote(left,0), spu_promote(zFar,0), _VECTORMATH_SHUF_XAYB ); rtn = spu_shuffle( spu_promote(right,0), spu_promote(zNear,0), _VECTORMATH_SHUF_XAYB ); lbf = spu_shuffle( lbf, spu_promote(bottom,0), _VECTORMATH_SHUF_XAYB ); rtn = spu_shuffle( rtn, spu_promote(top,0), _VECTORMATH_SHUF_XAYB ); diff = spu_sub( rtn, lbf ); sum = spu_add( rtn, lbf ); inv_diff = recipf4( diff ); near2 = spu_splats( zNear ); near2 = spu_add( near2, near2 ); diagonal = spu_mul( near2, inv_diff ); column = spu_mul( sum, inv_diff ); return Matrix4( Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0xf000) ) ), Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x0f00) ) ), Vector4( spu_sel( column, spu_splats(-1.0f), (vec_uint4)spu_maskb(0x000f) ) ), Vector4( spu_sel( zero, spu_mul( diagonal, spu_splats(zFar) ), (vec_uint4)spu_maskb(0x00f0) ) ) ); } inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) { /* function implementation based on code from STIDC SDK: */ /* -------------------------------------------------------------- */ /* PLEASE DO NOT MODIFY THIS SECTION */ /* This prolog section is automatically generated. */ /* */ /* (C)Copyright */ /* Sony Computer Entertainment, Inc., */ /* Toshiba Corporation, */ /* International Business Machines Corporation, */ /* 2001,2002. */ /* S/T/I Confidential Information */ /* -------------------------------------------------------------- */ vec_float4 lbf, rtn; vec_float4 diff, sum, inv_diff, neg_inv_diff; vec_float4 diagonal, column; vec_float4 zero = spu_splats(0.0f); lbf = spu_shuffle( spu_promote(left,0), spu_promote(zFar,0), _VECTORMATH_SHUF_XAYB ); rtn = spu_shuffle( spu_promote(right,0), spu_promote(zNear,0), _VECTORMATH_SHUF_XAYB ); lbf = spu_shuffle( lbf, spu_promote(bottom,0), _VECTORMATH_SHUF_XAYB ); rtn = spu_shuffle( rtn, spu_promote(top,0), _VECTORMATH_SHUF_XAYB ); diff = spu_sub( rtn, lbf ); sum = spu_add( rtn, lbf ); inv_diff = recipf4( diff ); neg_inv_diff = negatef4( inv_diff ); diagonal = spu_add( inv_diff, inv_diff ); column = spu_mul( sum, spu_sel( neg_inv_diff, inv_diff, (vec_uint4)spu_maskb(0x00f0) ) ); return Matrix4( Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0xf000) ) ), Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x0f00) ) ), Vector4( spu_sel( zero, diagonal, (vec_uint4)spu_maskb(0x00f0) ) ), Vector4( spu_sel( column, spu_splats(1.0f), (vec_uint4)spu_maskb(0x000f) ) ) ); } inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) { return Matrix4( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ), select( mat0.getCol3(), mat1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix4 & mat ) { print( mat.getRow( 0 ) ); print( mat.getRow( 1 ) ); print( mat.getRow( 2 ) ); print( mat.getRow( 3 ) ); } inline void print( const Matrix4 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Transform3::Transform3( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; } inline Transform3::Transform3( float scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); mCol3 = Vector3( scalar ); } inline Transform3::Transform3( Vector3 _col0, Vector3 _col1, Vector3 _col2, Vector3 _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Transform3::Transform3( const Matrix3 & tfrm, Vector3 translateVec ) { this->setUpper3x3( tfrm ); this->setTranslation( translateVec ); } inline Transform3::Transform3( Quat unitQuat, Vector3 translateVec ) { this->setUpper3x3( Matrix3( unitQuat ) ); this->setTranslation( translateVec ); } inline Transform3 & Transform3::setCol0( Vector3 _col0 ) { mCol0 = _col0; return *this; } inline Transform3 & Transform3::setCol1( Vector3 _col1 ) { mCol1 = _col1; return *this; } inline Transform3 & Transform3::setCol2( Vector3 _col2 ) { mCol2 = _col2; return *this; } inline Transform3 & Transform3::setCol3( Vector3 _col3 ) { mCol3 = _col3; return *this; } inline Transform3 & Transform3::setCol( int col, Vector3 vec ) { *(&mCol0 + col) = vec; return *this; } inline Transform3 & Transform3::setRow( int row, Vector4 vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Transform3 & Transform3::setElem( int col, int row, float val ) { (*this)[col].setElem(row, val); return *this; } inline float Transform3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Transform3::getCol0( ) const { return mCol0; } inline const Vector3 Transform3::getCol1( ) const { return mCol1; } inline const Vector3 Transform3::getCol2( ) const { return mCol2; } inline const Vector3 Transform3::getCol3( ) const { return mCol3; } inline const Vector3 Transform3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Transform3::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector3 & Transform3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Transform3::operator []( int col ) const { return *(&mCol0 + col); } inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; return *this; } inline const Transform3 inverse( const Transform3 & tfrm ) { vec_float4 inv0, inv1, inv2, inv3; vec_float4 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() ); tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() ); tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() ); inv3 = negatef4( tfrm.getCol3().get128() ); dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() ); dot = spu_shuffle( dot, dot, shuffle_xxxx ); invdet = recipf4( dot ); tmp3 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_XAYB ); tmp4 = spu_shuffle( tmp0, tmp2, _VECTORMATH_SHUF_ZCWD ); inv0 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_XAYB ); xxxx = spu_shuffle( inv3, inv3, shuffle_xxxx ); inv1 = spu_shuffle( tmp3, tmp1, _VECTORMATH_SHUF_ZBW0 ); inv2 = spu_shuffle( tmp4, tmp1, _VECTORMATH_SHUF_XCY0 ); yyyy = spu_shuffle( inv3, inv3, shuffle_yyyy ); zzzz = spu_shuffle( inv3, inv3, shuffle_zzzz ); inv3 = spu_mul( inv0, xxxx ); inv3 = spu_madd( inv1, yyyy, inv3 ); inv3 = spu_madd( inv2, zzzz, inv3 ); inv0 = spu_mul( inv0, invdet ); inv1 = spu_mul( inv1, invdet ); inv2 = spu_mul( inv2, invdet ); inv3 = spu_mul( inv3, invdet ); return Transform3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ), Vector3( inv3 ) ); } inline const Transform3 orthoInverse( const Transform3 & tfrm ) { vec_float4 inv0, inv1, inv2, inv3; vec_float4 tmp0, tmp1; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); tmp0 = spu_shuffle( tfrm.getCol0().get128(), tfrm.getCol2().get128(), _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( tfrm.getCol0().get128(), tfrm.getCol2().get128(), _VECTORMATH_SHUF_ZCWD ); inv3 = negatef4( tfrm.getCol3().get128() ); inv0 = spu_shuffle( tmp0, tfrm.getCol1().get128(), _VECTORMATH_SHUF_XAYB ); xxxx = spu_shuffle( inv3, inv3, shuffle_xxxx ); inv1 = spu_shuffle( tmp0, tfrm.getCol1().get128(), _VECTORMATH_SHUF_ZBW0 ); inv2 = spu_shuffle( tmp1, tfrm.getCol1().get128(), _VECTORMATH_SHUF_XCY0 ); yyyy = spu_shuffle( inv3, inv3, shuffle_yyyy ); zzzz = spu_shuffle( inv3, inv3, shuffle_zzzz ); inv3 = spu_mul( inv0, xxxx ); inv3 = spu_madd( inv1, yyyy, inv3 ); inv3 = spu_madd( inv2, zzzz, inv3 ); return Transform3( Vector3( inv0 ), Vector3( inv1 ), Vector3( inv2 ), Vector3( inv3 ) ); } inline const Transform3 absPerElem( const Transform3 & tfrm ) { return Transform3( absPerElem( tfrm.getCol0() ), absPerElem( tfrm.getCol1() ), absPerElem( tfrm.getCol2() ), absPerElem( tfrm.getCol3() ) ); } inline const Vector3 Transform3::operator *( Vector3 vec ) const { vec_float4 res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx ); yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy ); zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz ); res = spu_mul( mCol0.get128(), xxxx ); res = spu_madd( mCol1.get128(), yyyy, res ); res = spu_madd( mCol2.get128(), zzzz, res ); return Vector3( res ); } inline const Point3 Transform3::operator *( Point3 pnt ) const { vec_float4 tmp0, tmp1, res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); xxxx = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_xxxx ); yyyy = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_yyyy ); zzzz = spu_shuffle( pnt.get128(), pnt.get128(), shuffle_zzzz ); tmp0 = spu_mul( mCol0.get128(), xxxx ); tmp1 = spu_mul( mCol1.get128(), yyyy ); tmp0 = spu_madd( mCol2.get128(), zzzz, tmp0 ); tmp1 = spu_add( mCol3.get128(), tmp1 ); res = spu_add( tmp0, tmp1 ); return Point3( res ); } inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const { return Transform3( ( *this * tfrm.mCol0 ), ( *this * tfrm.mCol1 ), ( *this * tfrm.mCol2 ), Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) ); } inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) { return Transform3( mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) ); } inline const Transform3 Transform3::identity( ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), Vector3( 0.0f ) ); } inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) { mCol0 = tfrm.getCol0(); mCol1 = tfrm.getCol1(); mCol2 = tfrm.getCol2(); return *this; } inline const Matrix3 Transform3::getUpper3x3( ) const { return Matrix3( mCol0, mCol1, mCol2 ); } inline Transform3 & Transform3::setTranslation( Vector3 translateVec ) { mCol3 = translateVec; return *this; } inline const Vector3 Transform3::getTranslation( ) const { return mCol3; } inline const Transform3 Transform3::rotationX( float radians ) { vec_float4 s, c, res1, res2; vec_uint4 select_y, select_z; vec_float4 zero; select_y = (vec_uint4)spu_maskb(0x0f00); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res1 = spu_sel( zero, c, select_y ); res1 = spu_sel( res1, s, select_z ); res2 = spu_sel( zero, negatef4(s), select_y ); res2 = spu_sel( res2, c, select_z ); return Transform3( Vector3::xAxis( ), Vector3( res1 ), Vector3( res2 ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationY( float radians ) { vec_float4 s, c, res0, res2; vec_uint4 select_x, select_z; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_z = (vec_uint4)spu_maskb(0x00f0); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, negatef4(s), select_z ); res2 = spu_sel( zero, s, select_x ); res2 = spu_sel( res2, c, select_z ); return Transform3( Vector3( res0 ), Vector3::yAxis( ), Vector3( res2 ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationZ( float radians ) { vec_float4 s, c, res0, res1; vec_uint4 select_x, select_y; vec_float4 zero; select_x = (vec_uint4)spu_maskb(0xf000); select_y = (vec_uint4)spu_maskb(0x0f00); zero = spu_splats(0.0f); sincosf4( spu_splats(radians), &s, &c ); res0 = spu_sel( zero, c, select_x ); res0 = spu_sel( res0, s, select_y ); res1 = spu_sel( zero, negatef4(s), select_x ); res1 = spu_sel( res1, c, select_y ); return Transform3( Vector3( res0 ), Vector3( res1 ), Vector3::zAxis( ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotationZYX( Vector3 radiansXYZ ) { vec_float4 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); angles = radiansXYZ.get128(); angles = spu_insert( 0.0f, angles, 3 ); sincosf4( angles, &s, &c ); negS = negatef4( s ); Z0 = spu_shuffle( s, c, _VECTORMATH_SHUF_CZD0 ); Z1 = spu_shuffle( c, negS, _VECTORMATH_SHUF_CZD0 ); Y0 = spu_shuffle( negS, c, _VECTORMATH_SHUF_BBY0 ); Y1 = spu_shuffle( c, s, _VECTORMATH_SHUF_BBY0 ); X0 = spu_shuffle( s, s, shuffle_xxxx ); X1 = spu_shuffle( c, c, shuffle_xxxx ); tmp = spu_mul( Z0, Y1 ); return Transform3( Vector3( spu_mul( Z0, Y0 ) ), Vector3( spu_madd( Z1, X1, spu_mul( tmp, X0 ) ) ), Vector3( spu_nmsub( Z1, X0, spu_mul( tmp, X1 ) ) ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotation( float radians, Vector3 unitVec ) { return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::rotation( Quat unitQuat ) { return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); } inline const Transform3 Transform3::scale( Vector3 scaleVec ) { vec_float4 zero = spu_splats(0.0f); return Transform3( Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0xf000) ) ), Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x0f00) ) ), Vector3( spu_sel( zero, scaleVec.get128(), (vec_uint4)spu_maskb(0x00f0) ) ), Vector3( 0.0f ) ); } inline const Transform3 appendScale( const Transform3 & tfrm, Vector3 scaleVec ) { return Transform3( ( tfrm.getCol0() * scaleVec.getX( ) ), ( tfrm.getCol1() * scaleVec.getY( ) ), ( tfrm.getCol2() * scaleVec.getZ( ) ), tfrm.getCol3() ); } inline const Transform3 prependScale( Vector3 scaleVec, const Transform3 & tfrm ) { return Transform3( mulPerElem( tfrm.getCol0(), scaleVec ), mulPerElem( tfrm.getCol1(), scaleVec ), mulPerElem( tfrm.getCol2(), scaleVec ), mulPerElem( tfrm.getCol3(), scaleVec ) ); } inline const Transform3 Transform3::translation( Vector3 translateVec ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), translateVec ); } inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) { return Transform3( select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Transform3 & tfrm ) { print( tfrm.getRow( 0 ) ); print( tfrm.getRow( 1 ) ); print( tfrm.getRow( 2 ) ); } inline void print( const Transform3 & tfrm, const char * name ) { printf("%s:\n", name); print( tfrm ); } #endif inline Quat::Quat( const Matrix3 & tfrm ) { vec_float4 res; vec_float4 col0, col1, col2; vec_float4 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; vec_float4 zy_xz_yx, yz_zx_xy, sum, diff; vec_float4 radicand, invSqrt, scale; vec_float4 res0, res1, res2, res3; vec_float4 xx, yy, zz; vec_uint4 select_x = (vec_uint4)spu_maskb( 0xf000 ); vec_uint4 select_y = (vec_uint4)spu_maskb( 0x0f00 ); vec_uint4 select_z = (vec_uint4)spu_maskb( 0x00f0 ); vec_uint4 select_w = (vec_uint4)spu_maskb( 0x000f ); vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((unsigned int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((unsigned int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((unsigned int)0x08090a0b); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((unsigned int)0x0c0d0e0f); col0 = tfrm.getCol0().get128(); col1 = tfrm.getCol1().get128(); col2 = tfrm.getCol2().get128(); /* four cases: */ /* trace > 0 */ /* else */ /* xx largest diagonal element */ /* yy largest diagonal element */ /* zz largest diagonal element */ /* compute quaternion for each case */ xx_yy = spu_sel( col0, col1, select_y ); xx_yy_zz_xx = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_XYCX ); yy_zz_xx_yy = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_YCXY ); zz_xx_yy_zz = spu_shuffle( xx_yy, col2, _VECTORMATH_SHUF_CXYC ); diagSum = spu_add( spu_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); diagDiff = spu_sub( spu_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); radicand = spu_add( spu_sel( diagDiff, diagSum, select_w ), spu_splats(1.0f) ); invSqrt = rsqrtf4( radicand ); zy_xz_yx = spu_sel( col0, col1, select_z ); zy_xz_yx = spu_shuffle( zy_xz_yx, col2, _VECTORMATH_SHUF_ZAY0 ); yz_zx_xy = spu_sel( col0, col1, select_x ); yz_zx_xy = spu_shuffle( yz_zx_xy, col2, _VECTORMATH_SHUF_BZX0 ); sum = spu_add( zy_xz_yx, yz_zx_xy ); diff = spu_sub( zy_xz_yx, yz_zx_xy ); scale = spu_mul( invSqrt, spu_splats(0.5f) ); res0 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_0ZYA ); res1 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_Z0XB ); res2 = spu_shuffle( sum, diff, _VECTORMATH_SHUF_YX0C ); res3 = diff; res0 = spu_sel( res0, radicand, select_x ); res1 = spu_sel( res1, radicand, select_y ); res2 = spu_sel( res2, radicand, select_z ); res3 = spu_sel( res3, radicand, select_w ); res0 = spu_mul( res0, spu_shuffle( scale, scale, shuffle_xxxx ) ); res1 = spu_mul( res1, spu_shuffle( scale, scale, shuffle_yyyy ) ); res2 = spu_mul( res2, spu_shuffle( scale, scale, shuffle_zzzz ) ); res3 = spu_mul( res3, spu_shuffle( scale, scale, shuffle_wwww ) ); /* determine case and select answer */ xx = spu_shuffle( col0, col0, shuffle_xxxx ); yy = spu_shuffle( col1, col1, shuffle_yyyy ); zz = spu_shuffle( col2, col2, shuffle_zzzz ); res = spu_sel( res0, res1, spu_cmpgt( yy, xx ) ); res = spu_sel( res, res2, spu_and( spu_cmpgt( zz, xx ), spu_cmpgt( zz, yy ) ) ); res = spu_sel( res, res3, spu_cmpgt( spu_shuffle( diagSum, diagSum, shuffle_xxxx ), spu_splats(0.0f) ) ); mVec128 = res; } inline const Matrix3 outer( Vector3 tfrm0, Vector3 tfrm1 ) { return Matrix3( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ) ); } inline const Matrix4 outer( Vector4 tfrm0, Vector4 tfrm1 ) { return Matrix4( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ), ( tfrm0 * tfrm1.getW( ) ) ); } inline const Vector3 rowMul( Vector3 vec, const Matrix3 & mat ) { vec_float4 tmp0, tmp1, mcol0, mcol1, mcol2, res; vec_float4 xxxx, yyyy, zzzz; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); tmp0 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mat.getCol0().get128(), mat.getCol2().get128(), _VECTORMATH_SHUF_ZCWD ); xxxx = spu_shuffle( vec.get128(), vec.get128(), shuffle_xxxx ); mcol0 = spu_shuffle( tmp0, mat.getCol1().get128(), _VECTORMATH_SHUF_XAYB ); mcol1 = spu_shuffle( tmp0, mat.getCol1().get128(), _VECTORMATH_SHUF_ZBW0 ); mcol2 = spu_shuffle( tmp1, mat.getCol1().get128(), _VECTORMATH_SHUF_XCY0 ); yyyy = spu_shuffle( vec.get128(), vec.get128(), shuffle_yyyy ); res = spu_mul( mcol0, xxxx ); zzzz = spu_shuffle( vec.get128(), vec.get128(), shuffle_zzzz ); res = spu_madd( mcol1, yyyy, res ); res = spu_madd( mcol2, zzzz, res ); return Vector3( res ); } inline const Matrix3 crossMatrix( Vector3 vec ) { vec_float4 neg, res0, res1, res2; neg = negatef4( vec.get128() ); res0 = spu_shuffle( vec.get128(), neg, _VECTORMATH_SHUF_0ZB0 ); res1 = spu_shuffle( vec.get128(), neg, _VECTORMATH_SHUF_C0X0 ); res2 = spu_shuffle( vec.get128(), neg, _VECTORMATH_SHUF_YA00 ); return Matrix3( Vector3( res0 ), Vector3( res1 ), Vector3( res2 ) ); } inline const Matrix3 crossMatrixMul( Vector3 vec, const Matrix3 & mat ) { return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); } } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/spu/cpp/mat_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_MAT_SOA_CPP_H #define _VECTORMATH_MAT_SOA_CPP_H namespace Vectormath { namespace Soa { //----------------------------------------------------------------------------- // Constants #define _VECTORMATH_PI_OVER_2 1.570796327f //----------------------------------------------------------------------------- // Definitions inline Matrix3::Matrix3( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; } inline Matrix3::Matrix3( vec_float4 scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); } inline Matrix3::Matrix3( const Quat & unitQuat ) { vec_float4 qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; qx = unitQuat.getX(); qy = unitQuat.getY(); qz = unitQuat.getZ(); qw = unitQuat.getW(); qx2 = spu_add( qx, qx ); qy2 = spu_add( qy, qy ); qz2 = spu_add( qz, qz ); qxqx2 = spu_mul( qx, qx2 ); qxqy2 = spu_mul( qx, qy2 ); qxqz2 = spu_mul( qx, qz2 ); qxqw2 = spu_mul( qw, qx2 ); qyqy2 = spu_mul( qy, qy2 ); qyqz2 = spu_mul( qy, qz2 ); qyqw2 = spu_mul( qw, qy2 ); qzqz2 = spu_mul( qz, qz2 ); qzqw2 = spu_mul( qw, qz2 ); mCol0 = Vector3( spu_sub( spu_sub( spu_splats(1.0f), qyqy2 ), qzqz2 ), spu_add( qxqy2, qzqw2 ), spu_sub( qxqz2, qyqw2 ) ); mCol1 = Vector3( spu_sub( qxqy2, qzqw2 ), spu_sub( spu_sub( spu_splats(1.0f), qxqx2 ), qzqz2 ), spu_add( qyqz2, qxqw2 ) ); mCol2 = Vector3( spu_add( qxqz2, qyqw2 ), spu_sub( qyqz2, qxqw2 ), spu_sub( spu_sub( spu_splats(1.0f), qxqx2 ), qyqy2 ) ); } inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; } inline Matrix3::Matrix3( const Aos::Matrix3 & mat ) { mCol0 = Vector3( mat.getCol0() ); mCol1 = Vector3( mat.getCol1() ); mCol2 = Vector3( mat.getCol2() ); } inline Matrix3::Matrix3( const Aos::Matrix3 & mat0, const Aos::Matrix3 & mat1, const Aos::Matrix3 & mat2, const Aos::Matrix3 & mat3 ) { mCol0 = Vector3( mat0.getCol0(), mat1.getCol0(), mat2.getCol0(), mat3.getCol0() ); mCol1 = Vector3( mat0.getCol1(), mat1.getCol1(), mat2.getCol1(), mat3.getCol1() ); mCol2 = Vector3( mat0.getCol2(), mat1.getCol2(), mat2.getCol2(), mat3.getCol2() ); } inline void Matrix3::get4Aos( Aos::Matrix3 & result0, Aos::Matrix3 & result1, Aos::Matrix3 & result2, Aos::Matrix3 & result3 ) const { Aos::Vector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; mCol0.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol0( tmpV3_0 ); result1.setCol0( tmpV3_1 ); result2.setCol0( tmpV3_2 ); result3.setCol0( tmpV3_3 ); mCol1.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol1( tmpV3_0 ); result1.setCol1( tmpV3_1 ); result2.setCol1( tmpV3_2 ); result3.setCol1( tmpV3_3 ); mCol2.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol2( tmpV3_0 ); result1.setCol2( tmpV3_1 ); result2.setCol2( tmpV3_2 ); result3.setCol2( tmpV3_3 ); } inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) { mCol0 = _col0; return *this; } inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) { mCol1 = _col1; return *this; } inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) { mCol2 = _col2; return *this; } inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); return *this; } inline Matrix3 & Matrix3::setElem( int col, int row, vec_float4 val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline vec_float4 Matrix3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Matrix3::getCol0( ) const { return mCol0; } inline const Vector3 Matrix3::getCol1( ) const { return mCol1; } inline const Vector3 Matrix3::getCol2( ) const { return mCol2; } inline const Vector3 Matrix3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector3 Matrix3::getRow( int row ) const { return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); } inline Vector3 & Matrix3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Matrix3::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; return *this; } inline const Matrix3 transpose( const Matrix3 & mat ) { return Matrix3( Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) ); } inline const Matrix3 inverse( const Matrix3 & mat ) { Vector3 tmp0, tmp1, tmp2; vec_float4 detinv; tmp0 = cross( mat.getCol1(), mat.getCol2() ); tmp1 = cross( mat.getCol2(), mat.getCol0() ); tmp2 = cross( mat.getCol0(), mat.getCol1() ); detinv = recipf4( dot( mat.getCol2(), tmp2 ) ); return Matrix3( Vector3( spu_mul( tmp0.getX(), detinv ), spu_mul( tmp1.getX(), detinv ), spu_mul( tmp2.getX(), detinv ) ), Vector3( spu_mul( tmp0.getY(), detinv ), spu_mul( tmp1.getY(), detinv ), spu_mul( tmp2.getY(), detinv ) ), Vector3( spu_mul( tmp0.getZ(), detinv ), spu_mul( tmp1.getZ(), detinv ), spu_mul( tmp2.getZ(), detinv ) ) ); } inline vec_float4 determinant( const Matrix3 & mat ) { return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); } inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const { return Matrix3( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ) ); } inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const { return Matrix3( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) { *this = *this + mat; return *this; } inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) { *this = *this - mat; return *this; } inline const Matrix3 Matrix3::operator -( ) const { return Matrix3( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ) ); } inline const Matrix3 absPerElem( const Matrix3 & mat ) { return Matrix3( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ) ); } inline const Matrix3 Matrix3::operator *( vec_float4 scalar ) const { return Matrix3( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ) ); } inline Matrix3 & Matrix3::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Matrix3 operator *( vec_float4 scalar, const Matrix3 & mat ) { return mat * scalar; } inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const { return Vector3( spu_add( spu_add( spu_mul( mCol0.getX(), vec.getX() ), spu_mul( mCol1.getX(), vec.getY() ) ), spu_mul( mCol2.getX(), vec.getZ() ) ), spu_add( spu_add( spu_mul( mCol0.getY(), vec.getX() ), spu_mul( mCol1.getY(), vec.getY() ) ), spu_mul( mCol2.getY(), vec.getZ() ) ), spu_add( spu_add( spu_mul( mCol0.getZ(), vec.getX() ), spu_mul( mCol1.getZ(), vec.getY() ) ), spu_mul( mCol2.getZ(), vec.getZ() ) ) ); } inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const { return Matrix3( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ) ); } inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) { *this = *this * mat; return *this; } inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) { return Matrix3( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ) ); } inline const Matrix3 Matrix3::identity( ) { return Matrix3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationX( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix3( Vector3::xAxis( ), Vector3( spu_splats(0.0f), c, s ), Vector3( spu_splats(0.0f), negatef4( s ), c ) ); } inline const Matrix3 Matrix3::rotationY( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix3( Vector3( c, spu_splats(0.0f), negatef4( s ) ), Vector3::yAxis( ), Vector3( s, spu_splats(0.0f), c ) ); } inline const Matrix3 Matrix3::rotationZ( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix3( Vector3( c, s, spu_splats(0.0f) ), Vector3( negatef4( s ), c, spu_splats(0.0f) ), Vector3::zAxis( ) ); } inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ.getX(), &sX, &cX ); sincosf4( radiansXYZ.getY(), &sY, &cY ); sincosf4( radiansXYZ.getZ(), &sZ, &cZ ); tmp0 = spu_mul( cZ, sY ); tmp1 = spu_mul( sZ, sY ); return Matrix3( Vector3( spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ) ), 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 ) ), 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 ) ) ); } inline const Matrix3 Matrix3::rotation( vec_float4 radians, const Vector3 & unitVec ) { vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx; sincosf4( radians, &s, &c ); x = unitVec.getX(); y = unitVec.getY(); z = unitVec.getZ(); xy = spu_mul( x, y ); yz = spu_mul( y, z ); zx = spu_mul( z, x ); oneMinusC = spu_sub( spu_splats(1.0f), c ); return Matrix3( 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 ) ) ), 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 ) ) ), 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 ) ) ); } inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) { return Matrix3( unitQuat ); } inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) { return Matrix3( Vector3( scaleVec.getX(), spu_splats(0.0f), spu_splats(0.0f) ), Vector3( spu_splats(0.0f), scaleVec.getY(), spu_splats(0.0f) ), Vector3( spu_splats(0.0f), spu_splats(0.0f), scaleVec.getZ() ) ); } inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) { return Matrix3( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ) ); } inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) { return Matrix3( mulPerElem( mat.getCol0(), scaleVec ), mulPerElem( mat.getCol1(), scaleVec ), mulPerElem( mat.getCol2(), scaleVec ) ); } inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, vec_uint4 select1 ) { return Matrix3( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix3 & mat ) { Aos::Matrix3 mat0, mat1, mat2, mat3; mat.get4Aos( mat0, mat1, mat2, mat3 ); printf("slot 0:\n"); print( mat0 ); printf("slot 1:\n"); print( mat1 ); printf("slot 2:\n"); print( mat2 ); printf("slot 3:\n"); print( mat3 ); } inline void print( const Matrix3 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Matrix4::Matrix4( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; } inline Matrix4::Matrix4( vec_float4 scalar ) { mCol0 = Vector4( scalar ); mCol1 = Vector4( scalar ); mCol2 = Vector4( scalar ); mCol3 = Vector4( scalar ); } inline Matrix4::Matrix4( const Transform3 & mat ) { mCol0 = Vector4( mat.getCol0(), spu_splats(0.0f) ); mCol1 = Vector4( mat.getCol1(), spu_splats(0.0f) ); mCol2 = Vector4( mat.getCol2(), spu_splats(0.0f) ); mCol3 = Vector4( mat.getCol3(), spu_splats(1.0f) ); } inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) { mCol0 = Vector4( mat.getCol0(), spu_splats(0.0f) ); mCol1 = Vector4( mat.getCol1(), spu_splats(0.0f) ); mCol2 = Vector4( mat.getCol2(), spu_splats(0.0f) ); mCol3 = Vector4( translateVec, spu_splats(1.0f) ); } inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) { Matrix3 mat; mat = Matrix3( unitQuat ); mCol0 = Vector4( mat.getCol0(), spu_splats(0.0f) ); mCol1 = Vector4( mat.getCol1(), spu_splats(0.0f) ); mCol2 = Vector4( mat.getCol2(), spu_splats(0.0f) ); mCol3 = Vector4( translateVec, spu_splats(1.0f) ); } inline Matrix4::Matrix4( const Aos::Matrix4 & mat ) { mCol0 = Vector4( mat.getCol0() ); mCol1 = Vector4( mat.getCol1() ); mCol2 = Vector4( mat.getCol2() ); mCol3 = Vector4( mat.getCol3() ); } inline Matrix4::Matrix4( const Aos::Matrix4 & mat0, const Aos::Matrix4 & mat1, const Aos::Matrix4 & mat2, const Aos::Matrix4 & mat3 ) { mCol0 = Vector4( mat0.getCol0(), mat1.getCol0(), mat2.getCol0(), mat3.getCol0() ); mCol1 = Vector4( mat0.getCol1(), mat1.getCol1(), mat2.getCol1(), mat3.getCol1() ); mCol2 = Vector4( mat0.getCol2(), mat1.getCol2(), mat2.getCol2(), mat3.getCol2() ); mCol3 = Vector4( mat0.getCol3(), mat1.getCol3(), mat2.getCol3(), mat3.getCol3() ); } inline void Matrix4::get4Aos( Aos::Matrix4 & result0, Aos::Matrix4 & result1, Aos::Matrix4 & result2, Aos::Matrix4 & result3 ) const { Aos::Vector4 tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3; mCol0.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 ); result0.setCol0( tmpV4_0 ); result1.setCol0( tmpV4_1 ); result2.setCol0( tmpV4_2 ); result3.setCol0( tmpV4_3 ); mCol1.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 ); result0.setCol1( tmpV4_0 ); result1.setCol1( tmpV4_1 ); result2.setCol1( tmpV4_2 ); result3.setCol1( tmpV4_3 ); mCol2.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 ); result0.setCol2( tmpV4_0 ); result1.setCol2( tmpV4_1 ); result2.setCol2( tmpV4_2 ); result3.setCol2( tmpV4_3 ); mCol3.get4Aos( tmpV4_0, tmpV4_1, tmpV4_2, tmpV4_3 ); result0.setCol3( tmpV4_0 ); result1.setCol3( tmpV4_1 ); result2.setCol3( tmpV4_2 ); result3.setCol3( tmpV4_3 ); } inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) { mCol0 = _col0; return *this; } inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) { mCol1 = _col1; return *this; } inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) { mCol2 = _col2; return *this; } inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) { mCol3 = _col3; return *this; } inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Matrix4 & Matrix4::setElem( int col, int row, vec_float4 val ) { Vector4 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline vec_float4 Matrix4::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector4 Matrix4::getCol0( ) const { return mCol0; } inline const Vector4 Matrix4::getCol1( ) const { return mCol1; } inline const Vector4 Matrix4::getCol2( ) const { return mCol2; } inline const Vector4 Matrix4::getCol3( ) const { return mCol3; } inline const Vector4 Matrix4::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Matrix4::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector4 & Matrix4::operator []( int col ) { return *(&mCol0 + col); } inline const Vector4 Matrix4::operator []( int col ) const { return *(&mCol0 + col); } inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) { mCol0 = mat.mCol0; mCol1 = mat.mCol1; mCol2 = mat.mCol2; mCol3 = mat.mCol3; return *this; } inline const Matrix4 transpose( const Matrix4 & mat ) { return Matrix4( Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) ); } inline const Matrix4 inverse( const Matrix4 & mat ) { Vector4 res0, res1, res2, res3; 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; mA = mat.getCol0().getX(); mB = mat.getCol0().getY(); mC = mat.getCol0().getZ(); mD = mat.getCol0().getW(); mE = mat.getCol1().getX(); mF = mat.getCol1().getY(); mG = mat.getCol1().getZ(); mH = mat.getCol1().getW(); mI = mat.getCol2().getX(); mJ = mat.getCol2().getY(); mK = mat.getCol2().getZ(); mL = mat.getCol2().getW(); mM = mat.getCol3().getX(); mN = mat.getCol3().getY(); mO = mat.getCol3().getZ(); mP = mat.getCol3().getW(); tmp0 = spu_sub( spu_mul( mK, mD ), spu_mul( mC, mL ) ); tmp1 = spu_sub( spu_mul( mO, mH ), spu_mul( mG, mP ) ); tmp2 = spu_sub( spu_mul( mB, mK ), spu_mul( mJ, mC ) ); tmp3 = spu_sub( spu_mul( mF, mO ), spu_mul( mN, mG ) ); tmp4 = spu_sub( spu_mul( mJ, mD ), spu_mul( mB, mL ) ); tmp5 = spu_sub( spu_mul( mN, mH ), spu_mul( mF, mP ) ); res0.setX( spu_sub( spu_sub( spu_mul( mJ, tmp1 ), spu_mul( mL, tmp3 ) ), spu_mul( mK, tmp5 ) ) ); res0.setY( spu_sub( spu_sub( spu_mul( mN, tmp0 ), spu_mul( mP, tmp2 ) ), spu_mul( mO, tmp4 ) ) ); res0.setZ( spu_sub( spu_add( spu_mul( mD, tmp3 ), spu_mul( mC, tmp5 ) ), spu_mul( mB, tmp1 ) ) ); res0.setW( spu_sub( spu_add( spu_mul( mH, tmp2 ), spu_mul( mG, tmp4 ) ), spu_mul( mF, tmp0 ) ) ); 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() ) ) ); res1.setX( spu_mul( mI, tmp1 ) ); res1.setY( spu_mul( mM, tmp0 ) ); res1.setZ( spu_mul( mA, tmp1 ) ); res1.setW( spu_mul( mE, tmp0 ) ); res3.setX( spu_mul( mI, tmp3 ) ); res3.setY( spu_mul( mM, tmp2 ) ); res3.setZ( spu_mul( mA, tmp3 ) ); res3.setW( spu_mul( mE, tmp2 ) ); res2.setX( spu_mul( mI, tmp5 ) ); res2.setY( spu_mul( mM, tmp4 ) ); res2.setZ( spu_mul( mA, tmp5 ) ); res2.setW( spu_mul( mE, tmp4 ) ); tmp0 = spu_sub( spu_mul( mI, mB ), spu_mul( mA, mJ ) ); tmp1 = spu_sub( spu_mul( mM, mF ), spu_mul( mE, mN ) ); tmp2 = spu_sub( spu_mul( mI, mD ), spu_mul( mA, mL ) ); tmp3 = spu_sub( spu_mul( mM, mH ), spu_mul( mE, mP ) ); tmp4 = spu_sub( spu_mul( mI, mC ), spu_mul( mA, mK ) ); tmp5 = spu_sub( spu_mul( mM, mG ), spu_mul( mE, mO ) ); res2.setX( spu_add( spu_sub( spu_mul( mL, tmp1 ), spu_mul( mJ, tmp3 ) ), res2.getX() ) ); res2.setY( spu_add( spu_sub( spu_mul( mP, tmp0 ), spu_mul( mN, tmp2 ) ), res2.getY() ) ); res2.setZ( spu_sub( spu_sub( spu_mul( mB, tmp3 ), spu_mul( mD, tmp1 ) ), res2.getZ() ) ); res2.setW( spu_sub( spu_sub( spu_mul( mF, tmp2 ), spu_mul( mH, tmp0 ) ), res2.getW() ) ); res3.setX( spu_add( spu_sub( spu_mul( mJ, tmp5 ), spu_mul( mK, tmp1 ) ), res3.getX() ) ); res3.setY( spu_add( spu_sub( spu_mul( mN, tmp4 ), spu_mul( mO, tmp0 ) ), res3.getY() ) ); res3.setZ( spu_sub( spu_sub( spu_mul( mC, tmp1 ), spu_mul( mB, tmp5 ) ), res3.getZ() ) ); res3.setW( spu_sub( spu_sub( spu_mul( mG, tmp0 ), spu_mul( mF, tmp4 ) ), res3.getW() ) ); res1.setX( spu_sub( spu_sub( spu_mul( mK, tmp3 ), spu_mul( mL, tmp5 ) ), res1.getX() ) ); res1.setY( spu_sub( spu_sub( spu_mul( mO, tmp2 ), spu_mul( mP, tmp4 ) ), res1.getY() ) ); res1.setZ( spu_add( spu_sub( spu_mul( mD, tmp5 ), spu_mul( mC, tmp3 ) ), res1.getZ() ) ); res1.setW( spu_add( spu_sub( spu_mul( mH, tmp4 ), spu_mul( mG, tmp2 ) ), res1.getW() ) ); return Matrix4( ( res0 * detInv ), ( res1 * detInv ), ( res2 * detInv ), ( res3 * detInv ) ); } inline const Matrix4 affineInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( inverse( affineMat ) ); } inline const Matrix4 orthoInverse( const Matrix4 & mat ) { Transform3 affineMat; affineMat.setCol0( mat.getCol0().getXYZ( ) ); affineMat.setCol1( mat.getCol1().getXYZ( ) ); affineMat.setCol2( mat.getCol2().getXYZ( ) ); affineMat.setCol3( mat.getCol3().getXYZ( ) ); return Matrix4( orthoInverse( affineMat ) ); } inline vec_float4 determinant( const Matrix4 & mat ) { 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; mA = mat.getCol0().getX(); mB = mat.getCol0().getY(); mC = mat.getCol0().getZ(); mD = mat.getCol0().getW(); mE = mat.getCol1().getX(); mF = mat.getCol1().getY(); mG = mat.getCol1().getZ(); mH = mat.getCol1().getW(); mI = mat.getCol2().getX(); mJ = mat.getCol2().getY(); mK = mat.getCol2().getZ(); mL = mat.getCol2().getW(); mM = mat.getCol3().getX(); mN = mat.getCol3().getY(); mO = mat.getCol3().getZ(); mP = mat.getCol3().getW(); tmp0 = spu_sub( spu_mul( mK, mD ), spu_mul( mC, mL ) ); tmp1 = spu_sub( spu_mul( mO, mH ), spu_mul( mG, mP ) ); tmp2 = spu_sub( spu_mul( mB, mK ), spu_mul( mJ, mC ) ); tmp3 = spu_sub( spu_mul( mF, mO ), spu_mul( mN, mG ) ); tmp4 = spu_sub( spu_mul( mJ, mD ), spu_mul( mB, mL ) ); tmp5 = spu_sub( spu_mul( mN, mH ), spu_mul( mF, mP ) ); dx = spu_sub( spu_sub( spu_mul( mJ, tmp1 ), spu_mul( mL, tmp3 ) ), spu_mul( mK, tmp5 ) ); dy = spu_sub( spu_sub( spu_mul( mN, tmp0 ), spu_mul( mP, tmp2 ) ), spu_mul( mO, tmp4 ) ); dz = spu_sub( spu_add( spu_mul( mD, tmp3 ), spu_mul( mC, tmp5 ) ), spu_mul( mB, tmp1 ) ); dw = spu_sub( spu_add( spu_mul( mH, tmp2 ), spu_mul( mG, tmp4 ) ), spu_mul( mF, tmp0 ) ); return spu_add( spu_add( spu_add( spu_mul( mA, dx ), spu_mul( mE, dy ) ), spu_mul( mI, dz ) ), spu_mul( mM, dw ) ); } inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const { return Matrix4( ( mCol0 + mat.mCol0 ), ( mCol1 + mat.mCol1 ), ( mCol2 + mat.mCol2 ), ( mCol3 + mat.mCol3 ) ); } inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const { return Matrix4( ( mCol0 - mat.mCol0 ), ( mCol1 - mat.mCol1 ), ( mCol2 - mat.mCol2 ), ( mCol3 - mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) { *this = *this + mat; return *this; } inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) { *this = *this - mat; return *this; } inline const Matrix4 Matrix4::operator -( ) const { return Matrix4( ( -mCol0 ), ( -mCol1 ), ( -mCol2 ), ( -mCol3 ) ); } inline const Matrix4 absPerElem( const Matrix4 & mat ) { return Matrix4( absPerElem( mat.getCol0() ), absPerElem( mat.getCol1() ), absPerElem( mat.getCol2() ), absPerElem( mat.getCol3() ) ); } inline const Matrix4 Matrix4::operator *( vec_float4 scalar ) const { return Matrix4( ( mCol0 * scalar ), ( mCol1 * scalar ), ( mCol2 * scalar ), ( mCol3 * scalar ) ); } inline Matrix4 & Matrix4::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Matrix4 operator *( vec_float4 scalar, const Matrix4 & mat ) { return mat * scalar; } inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const { return Vector4( 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() ) ), 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() ) ), 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() ) ), 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() ) ) ); } inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const { return Vector4( spu_add( spu_add( spu_mul( mCol0.getX(), vec.getX() ), spu_mul( mCol1.getX(), vec.getY() ) ), spu_mul( mCol2.getX(), vec.getZ() ) ), spu_add( spu_add( spu_mul( mCol0.getY(), vec.getX() ), spu_mul( mCol1.getY(), vec.getY() ) ), spu_mul( mCol2.getY(), vec.getZ() ) ), spu_add( spu_add( spu_mul( mCol0.getZ(), vec.getX() ), spu_mul( mCol1.getZ(), vec.getY() ) ), spu_mul( mCol2.getZ(), vec.getZ() ) ), spu_add( spu_add( spu_mul( mCol0.getW(), vec.getX() ), spu_mul( mCol1.getW(), vec.getY() ) ), spu_mul( mCol2.getW(), vec.getZ() ) ) ); } inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const { return Vector4( 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() ), 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() ), 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() ), 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() ) ); } inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const { return Matrix4( ( *this * mat.mCol0 ), ( *this * mat.mCol1 ), ( *this * mat.mCol2 ), ( *this * mat.mCol3 ) ); } inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) { *this = *this * mat; return *this; } inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const { return Matrix4( ( *this * tfrm.getCol0() ), ( *this * tfrm.getCol1() ), ( *this * tfrm.getCol2() ), ( *this * Point3( tfrm.getCol3() ) ) ); } inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) { return Matrix4( mulPerElem( mat0.getCol0(), mat1.getCol0() ), mulPerElem( mat0.getCol1(), mat1.getCol1() ), mulPerElem( mat0.getCol2(), mat1.getCol2() ), mulPerElem( mat0.getCol3(), mat1.getCol3() ) ); } inline const Matrix4 Matrix4::identity( ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) { mCol0.setXYZ( mat3.getCol0() ); mCol1.setXYZ( mat3.getCol1() ); mCol2.setXYZ( mat3.getCol2() ); return *this; } inline const Matrix3 Matrix4::getUpper3x3( ) const { return Matrix3( mCol0.getXYZ( ), mCol1.getXYZ( ), mCol2.getXYZ( ) ); } inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) { mCol3.setXYZ( translateVec ); return *this; } inline const Vector3 Matrix4::getTranslation( ) const { return mCol3.getXYZ( ); } inline const Matrix4 Matrix4::rotationX( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix4( Vector4::xAxis( ), Vector4( spu_splats(0.0f), c, s, spu_splats(0.0f) ), Vector4( spu_splats(0.0f), negatef4( s ), c, spu_splats(0.0f) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationY( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix4( Vector4( c, spu_splats(0.0f), negatef4( s ), spu_splats(0.0f) ), Vector4::yAxis( ), Vector4( s, spu_splats(0.0f), c, spu_splats(0.0f) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZ( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Matrix4( Vector4( c, s, spu_splats(0.0f), spu_splats(0.0f) ), Vector4( negatef4( s ), c, spu_splats(0.0f), spu_splats(0.0f) ), Vector4::zAxis( ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ.getX(), &sX, &cX ); sincosf4( radiansXYZ.getY(), &sY, &cY ); sincosf4( radiansXYZ.getZ(), &sZ, &cZ ); tmp0 = spu_mul( cZ, sY ); tmp1 = spu_mul( sZ, sY ); return Matrix4( Vector4( spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ), spu_splats(0.0f) ), 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) ), 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) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( vec_float4 radians, const Vector3 & unitVec ) { vec_float4 x, y, z, s, c, oneMinusC, xy, yz, zx; sincosf4( radians, &s, &c ); x = unitVec.getX(); y = unitVec.getY(); z = unitVec.getZ(); xy = spu_mul( x, y ); yz = spu_mul( y, z ); zx = spu_mul( z, x ); oneMinusC = spu_sub( spu_splats(1.0f), c ); return Matrix4( 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) ), 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) ), 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) ), Vector4::wAxis( ) ); } inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) { return Matrix4( Transform3::rotation( unitQuat ) ); } inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) { return Matrix4( Vector4( scaleVec.getX(), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ), Vector4( spu_splats(0.0f), scaleVec.getY(), spu_splats(0.0f), spu_splats(0.0f) ), Vector4( spu_splats(0.0f), spu_splats(0.0f), scaleVec.getZ(), spu_splats(0.0f) ), Vector4::wAxis( ) ); } inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) { return Matrix4( ( mat.getCol0() * scaleVec.getX( ) ), ( mat.getCol1() * scaleVec.getY( ) ), ( mat.getCol2() * scaleVec.getZ( ) ), mat.getCol3() ); } inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) { Vector4 scale4; scale4 = Vector4( scaleVec, spu_splats(1.0f) ); return Matrix4( mulPerElem( mat.getCol0(), scale4 ), mulPerElem( mat.getCol1(), scale4 ), mulPerElem( mat.getCol2(), scale4 ), mulPerElem( mat.getCol3(), scale4 ) ); } inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) { return Matrix4( Vector4::xAxis( ), Vector4::yAxis( ), Vector4::zAxis( ), Vector4( translateVec, spu_splats(1.0f) ) ); } inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) { Matrix4 m4EyeFrame; Vector3 v3X, v3Y, v3Z; v3Y = normalize( upVec ); v3Z = normalize( ( eyePos - lookAtPos ) ); v3X = normalize( cross( v3Y, v3Z ) ); v3Y = cross( v3Z, v3X ); m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); return orthoInverse( m4EyeFrame ); } inline const Matrix4 Matrix4::perspective( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ) { vec_float4 f, rangeInv; f = tanf4( spu_sub( spu_splats( _VECTORMATH_PI_OVER_2 ), spu_mul( spu_splats(0.5f), fovyRadians ) ) ); rangeInv = recipf4( spu_sub( zNear, zFar ) ); return Matrix4( Vector4( divf4( f, aspect ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ), Vector4( spu_splats(0.0f), f, spu_splats(0.0f), spu_splats(0.0f) ), Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_add( zNear, zFar ), rangeInv ), spu_splats(-1.0f) ), 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) ) ); } inline const Matrix4 Matrix4::frustum( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; sum_rl = spu_add( right, left ); sum_tb = spu_add( top, bottom ); sum_nf = spu_add( zNear, zFar ); inv_rl = recipf4( spu_sub( right, left ) ); inv_tb = recipf4( spu_sub( top, bottom ) ); inv_nf = recipf4( spu_sub( zNear, zFar ) ); n2 = spu_add( zNear, zNear ); return Matrix4( Vector4( spu_mul( n2, inv_rl ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ), Vector4( spu_splats(0.0f), spu_mul( n2, inv_tb ), spu_splats(0.0f), spu_splats(0.0f) ), Vector4( spu_mul( sum_rl, inv_rl ), spu_mul( sum_tb, inv_tb ), spu_mul( sum_nf, inv_nf ), spu_splats(-1.0f) ), Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_mul( spu_mul( n2, inv_nf ), zFar ), spu_splats(0.0f) ) ); } inline const Matrix4 Matrix4::orthographic( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ) { vec_float4 sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; sum_rl = spu_add( right, left ); sum_tb = spu_add( top, bottom ); sum_nf = spu_add( zNear, zFar ); inv_rl = recipf4( spu_sub( right, left ) ); inv_tb = recipf4( spu_sub( top, bottom ) ); inv_nf = recipf4( spu_sub( zNear, zFar ) ); return Matrix4( Vector4( spu_add( inv_rl, inv_rl ), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ), Vector4( spu_splats(0.0f), spu_add( inv_tb, inv_tb ), spu_splats(0.0f), spu_splats(0.0f) ), Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_add( inv_nf, inv_nf ), spu_splats(0.0f) ), 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) ) ); } inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, vec_uint4 select1 ) { return Matrix4( select( mat0.getCol0(), mat1.getCol0(), select1 ), select( mat0.getCol1(), mat1.getCol1(), select1 ), select( mat0.getCol2(), mat1.getCol2(), select1 ), select( mat0.getCol3(), mat1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Matrix4 & mat ) { Aos::Matrix4 mat0, mat1, mat2, mat3; mat.get4Aos( mat0, mat1, mat2, mat3 ); printf("slot 0:\n"); print( mat0 ); printf("slot 1:\n"); print( mat1 ); printf("slot 2:\n"); print( mat2 ); printf("slot 3:\n"); print( mat3 ); } inline void print( const Matrix4 & mat, const char * name ) { printf("%s:\n", name); print( mat ); } #endif inline Transform3::Transform3( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; } inline Transform3::Transform3( vec_float4 scalar ) { mCol0 = Vector3( scalar ); mCol1 = Vector3( scalar ); mCol2 = Vector3( scalar ); mCol3 = Vector3( scalar ); } inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) { mCol0 = _col0; mCol1 = _col1; mCol2 = _col2; mCol3 = _col3; } inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) { this->setUpper3x3( tfrm ); this->setTranslation( translateVec ); } inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) { this->setUpper3x3( Matrix3( unitQuat ) ); this->setTranslation( translateVec ); } inline Transform3::Transform3( const Aos::Transform3 & tfrm ) { mCol0 = Vector3( tfrm.getCol0() ); mCol1 = Vector3( tfrm.getCol1() ); mCol2 = Vector3( tfrm.getCol2() ); mCol3 = Vector3( tfrm.getCol3() ); } inline Transform3::Transform3( const Aos::Transform3 & tfrm0, const Aos::Transform3 & tfrm1, const Aos::Transform3 & tfrm2, const Aos::Transform3 & tfrm3 ) { mCol0 = Vector3( tfrm0.getCol0(), tfrm1.getCol0(), tfrm2.getCol0(), tfrm3.getCol0() ); mCol1 = Vector3( tfrm0.getCol1(), tfrm1.getCol1(), tfrm2.getCol1(), tfrm3.getCol1() ); mCol2 = Vector3( tfrm0.getCol2(), tfrm1.getCol2(), tfrm2.getCol2(), tfrm3.getCol2() ); mCol3 = Vector3( tfrm0.getCol3(), tfrm1.getCol3(), tfrm2.getCol3(), tfrm3.getCol3() ); } inline void Transform3::get4Aos( Aos::Transform3 & result0, Aos::Transform3 & result1, Aos::Transform3 & result2, Aos::Transform3 & result3 ) const { Aos::Vector3 tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3; mCol0.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol0( tmpV3_0 ); result1.setCol0( tmpV3_1 ); result2.setCol0( tmpV3_2 ); result3.setCol0( tmpV3_3 ); mCol1.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol1( tmpV3_0 ); result1.setCol1( tmpV3_1 ); result2.setCol1( tmpV3_2 ); result3.setCol1( tmpV3_3 ); mCol2.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol2( tmpV3_0 ); result1.setCol2( tmpV3_1 ); result2.setCol2( tmpV3_2 ); result3.setCol2( tmpV3_3 ); mCol3.get4Aos( tmpV3_0, tmpV3_1, tmpV3_2, tmpV3_3 ); result0.setCol3( tmpV3_0 ); result1.setCol3( tmpV3_1 ); result2.setCol3( tmpV3_2 ); result3.setCol3( tmpV3_3 ); } inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) { mCol0 = _col0; return *this; } inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) { mCol1 = _col1; return *this; } inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) { mCol2 = _col2; return *this; } inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) { mCol3 = _col3; return *this; } inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) { *(&mCol0 + col) = vec; return *this; } inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) { mCol0.setElem( row, vec.getElem( 0 ) ); mCol1.setElem( row, vec.getElem( 1 ) ); mCol2.setElem( row, vec.getElem( 2 ) ); mCol3.setElem( row, vec.getElem( 3 ) ); return *this; } inline Transform3 & Transform3::setElem( int col, int row, vec_float4 val ) { Vector3 tmpV3_0; tmpV3_0 = this->getCol( col ); tmpV3_0.setElem( row, val ); this->setCol( col, tmpV3_0 ); return *this; } inline vec_float4 Transform3::getElem( int col, int row ) const { return this->getCol( col ).getElem( row ); } inline const Vector3 Transform3::getCol0( ) const { return mCol0; } inline const Vector3 Transform3::getCol1( ) const { return mCol1; } inline const Vector3 Transform3::getCol2( ) const { return mCol2; } inline const Vector3 Transform3::getCol3( ) const { return mCol3; } inline const Vector3 Transform3::getCol( int col ) const { return *(&mCol0 + col); } inline const Vector4 Transform3::getRow( int row ) const { return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); } inline Vector3 & Transform3::operator []( int col ) { return *(&mCol0 + col); } inline const Vector3 Transform3::operator []( int col ) const { return *(&mCol0 + col); } inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) { mCol0 = tfrm.mCol0; mCol1 = tfrm.mCol1; mCol2 = tfrm.mCol2; mCol3 = tfrm.mCol3; return *this; } inline const Transform3 inverse( const Transform3 & tfrm ) { Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; vec_float4 detinv; tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); detinv = recipf4( dot( tfrm.getCol2(), tmp2 ) ); inv0 = Vector3( spu_mul( tmp0.getX(), detinv ), spu_mul( tmp1.getX(), detinv ), spu_mul( tmp2.getX(), detinv ) ); inv1 = Vector3( spu_mul( tmp0.getY(), detinv ), spu_mul( tmp1.getY(), detinv ), spu_mul( tmp2.getY(), detinv ) ); inv2 = Vector3( spu_mul( tmp0.getZ(), detinv ), spu_mul( tmp1.getZ(), detinv ), spu_mul( tmp2.getZ(), detinv ) ); return Transform3( inv0, inv1, inv2, Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) ); } inline const Transform3 orthoInverse( const Transform3 & tfrm ) { Vector3 inv0, inv1, inv2; inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); return Transform3( inv0, inv1, inv2, Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) ); } inline const Transform3 absPerElem( const Transform3 & tfrm ) { return Transform3( absPerElem( tfrm.getCol0() ), absPerElem( tfrm.getCol1() ), absPerElem( tfrm.getCol2() ), absPerElem( tfrm.getCol3() ) ); } inline const Vector3 Transform3::operator *( const Vector3 & vec ) const { return Vector3( spu_add( spu_add( spu_mul( mCol0.getX(), vec.getX() ), spu_mul( mCol1.getX(), vec.getY() ) ), spu_mul( mCol2.getX(), vec.getZ() ) ), spu_add( spu_add( spu_mul( mCol0.getY(), vec.getX() ), spu_mul( mCol1.getY(), vec.getY() ) ), spu_mul( mCol2.getY(), vec.getZ() ) ), spu_add( spu_add( spu_mul( mCol0.getZ(), vec.getX() ), spu_mul( mCol1.getZ(), vec.getY() ) ), spu_mul( mCol2.getZ(), vec.getZ() ) ) ); } inline const Point3 Transform3::operator *( const Point3 & pnt ) const { return Point3( 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() ), 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() ), 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() ) ); } inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const { return Transform3( ( *this * tfrm.mCol0 ), ( *this * tfrm.mCol1 ), ( *this * tfrm.mCol2 ), Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) ); } inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) { *this = *this * tfrm; return *this; } inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) { return Transform3( mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) ); } inline const Transform3 Transform3::identity( ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), Vector3( spu_splats(0.0f) ) ); } inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) { mCol0 = tfrm.getCol0(); mCol1 = tfrm.getCol1(); mCol2 = tfrm.getCol2(); return *this; } inline const Matrix3 Transform3::getUpper3x3( ) const { return Matrix3( mCol0, mCol1, mCol2 ); } inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) { mCol3 = translateVec; return *this; } inline const Vector3 Transform3::getTranslation( ) const { return mCol3; } inline const Transform3 Transform3::rotationX( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Transform3( Vector3::xAxis( ), Vector3( spu_splats(0.0f), c, s ), Vector3( spu_splats(0.0f), negatef4( s ), c ), Vector3( spu_splats(0.0f) ) ); } inline const Transform3 Transform3::rotationY( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Transform3( Vector3( c, spu_splats(0.0f), negatef4( s ) ), Vector3::yAxis( ), Vector3( s, spu_splats(0.0f), c ), Vector3( spu_splats(0.0f) ) ); } inline const Transform3 Transform3::rotationZ( vec_float4 radians ) { vec_float4 s, c; sincosf4( radians, &s, &c ); return Transform3( Vector3( c, s, spu_splats(0.0f) ), Vector3( negatef4( s ), c, spu_splats(0.0f) ), Vector3::zAxis( ), Vector3( spu_splats(0.0f) ) ); } inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) { vec_float4 sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; sincosf4( radiansXYZ.getX(), &sX, &cX ); sincosf4( radiansXYZ.getY(), &sY, &cY ); sincosf4( radiansXYZ.getZ(), &sZ, &cZ ); tmp0 = spu_mul( cZ, sY ); tmp1 = spu_mul( sZ, sY ); return Transform3( Vector3( spu_mul( cZ, cY ), spu_mul( sZ, cY ), negatef4( sY ) ), 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 ) ), 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 ) ), Vector3( spu_splats(0.0f) ) ); } inline const Transform3 Transform3::rotation( vec_float4 radians, const Vector3 & unitVec ) { return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( spu_splats(0.0f) ) ); } inline const Transform3 Transform3::rotation( const Quat & unitQuat ) { return Transform3( Matrix3( unitQuat ), Vector3( spu_splats(0.0f) ) ); } inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) { return Transform3( Vector3( scaleVec.getX(), spu_splats(0.0f), spu_splats(0.0f) ), Vector3( spu_splats(0.0f), scaleVec.getY(), spu_splats(0.0f) ), Vector3( spu_splats(0.0f), spu_splats(0.0f), scaleVec.getZ() ), Vector3( spu_splats(0.0f) ) ); } inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) { return Transform3( ( tfrm.getCol0() * scaleVec.getX( ) ), ( tfrm.getCol1() * scaleVec.getY( ) ), ( tfrm.getCol2() * scaleVec.getZ( ) ), tfrm.getCol3() ); } inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) { return Transform3( mulPerElem( tfrm.getCol0(), scaleVec ), mulPerElem( tfrm.getCol1(), scaleVec ), mulPerElem( tfrm.getCol2(), scaleVec ), mulPerElem( tfrm.getCol3(), scaleVec ) ); } inline const Transform3 Transform3::translation( const Vector3 & translateVec ) { return Transform3( Vector3::xAxis( ), Vector3::yAxis( ), Vector3::zAxis( ), translateVec ); } inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, vec_uint4 select1 ) { return Transform3( select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Transform3 & tfrm ) { Aos::Transform3 mat0, mat1, mat2, mat3; tfrm.get4Aos( mat0, mat1, mat2, mat3 ); printf("slot 0:\n"); print( mat0 ); printf("slot 1:\n"); print( mat1 ); printf("slot 2:\n"); print( mat2 ); printf("slot 3:\n"); print( mat3 ); } inline void print( const Transform3 & tfrm, const char * name ) { printf("%s:\n", name); print( tfrm ); } #endif inline Quat::Quat( const Matrix3 & tfrm ) { vec_float4 trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; vec_uint4 negTrace, ZgtX, ZgtY, YgtX; vec_uint4 largestXorY, largestYorZ, largestZorX; xx = tfrm.getCol0().getX(); yx = tfrm.getCol0().getY(); zx = tfrm.getCol0().getZ(); xy = tfrm.getCol1().getX(); yy = tfrm.getCol1().getY(); zy = tfrm.getCol1().getZ(); xz = tfrm.getCol2().getX(); yz = tfrm.getCol2().getY(); zz = tfrm.getCol2().getZ(); trace = spu_add( spu_add( xx, yy ), zz ); negTrace = spu_cmpgt( spu_splats(0.0f), trace ); ZgtX = spu_cmpgt( zz, xx ); ZgtY = spu_cmpgt( zz, yy ); YgtX = spu_cmpgt( yy, xx ); largestXorY = spu_and( negTrace, spu_nand( ZgtX, ZgtY ) ); largestYorZ = spu_and( negTrace, spu_or( YgtX, ZgtX ) ); largestZorX = spu_and( negTrace, spu_orc( ZgtY, YgtX ) ); zz = spu_sel( zz, negatef4(zz), largestXorY ); xy = spu_sel( xy, negatef4(xy), largestXorY ); xx = spu_sel( xx, negatef4(xx), largestYorZ ); yz = spu_sel( yz, negatef4(yz), largestYorZ ); yy = spu_sel( yy, negatef4(yy), largestZorX ); zx = spu_sel( zx, negatef4(zx), largestZorX ); radicand = spu_add( spu_add( spu_add( xx, yy ), zz ), spu_splats(1.0f) ); scale = spu_mul( spu_splats(0.5f), rsqrtf4( radicand ) ); tmpx = spu_mul( spu_sub( zy, yz ), scale ); tmpy = spu_mul( spu_sub( xz, zx ), scale ); tmpz = spu_mul( spu_sub( yx, xy ), scale ); tmpw = spu_mul( radicand, scale ); qx = tmpx; qy = tmpy; qz = tmpz; qw = tmpw; qx = spu_sel( qx, tmpw, largestXorY ); qy = spu_sel( qy, tmpz, largestXorY ); qz = spu_sel( qz, tmpy, largestXorY ); qw = spu_sel( qw, tmpx, largestXorY ); tmpx = qx; tmpz = qz; qx = spu_sel( qx, qy, largestYorZ ); qy = spu_sel( qy, tmpx, largestYorZ ); qz = spu_sel( qz, qw, largestYorZ ); qw = spu_sel( qw, tmpz, largestYorZ ); mX = qx; mY = qy; mZ = qz; mW = qw; } inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) { return Matrix3( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ) ); } inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) { return Matrix4( ( tfrm0 * tfrm1.getX( ) ), ( tfrm0 * tfrm1.getY( ) ), ( tfrm0 * tfrm1.getZ( ) ), ( tfrm0 * tfrm1.getW( ) ) ); } inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) { return Vector3( 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() ) ), 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() ) ), 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() ) ) ); } inline const Matrix3 crossMatrix( const Vector3 & vec ) { return Matrix3( Vector3( spu_splats(0.0f), vec.getZ(), negatef4( vec.getY() ) ), Vector3( negatef4( vec.getZ() ), spu_splats(0.0f), vec.getX() ), Vector3( vec.getY(), negatef4( vec.getX() ), spu_splats(0.0f) ) ); } inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) { return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); } } // namespace Soa } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/spu/cpp/quat_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_AOS_CPP_H #define _VECTORMATH_QUAT_AOS_CPP_H //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Aos { inline Quat::Quat( float _x, float _y, float _z, float _w ) { mVec128 = (vec_float4){ _x, _y, _z, _w }; } inline Quat::Quat( Vector3 xyz, float _w ) { mVec128 = spu_shuffle( xyz.get128(), spu_promote( _w, 0 ), _VECTORMATH_SHUF_XYZA ); } inline Quat::Quat( Vector4 vec ) { mVec128 = vec.get128(); } inline Quat::Quat( float scalar ) { mVec128 = spu_splats( scalar ); } inline Quat::Quat( vec_float4 vf4 ) { mVec128 = vf4; } inline const Quat Quat::identity( ) { return Quat( _VECTORMATH_UNIT_0001 ); } inline const Quat lerp( float t, Quat quat0, Quat quat1 ) { return ( quat0 + ( ( quat1 - quat0 ) * t ) ); } inline const Quat slerp( float t, Quat unitQuat0, Quat unitQuat1 ) { Quat start; vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() ); cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(0.0f), cosAngle ); cosAngle = spu_sel( cosAngle, negatef4( cosAngle ), selectMask ); start = Quat( spu_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = spu_splats(t); oneMinusT = spu_sub( spu_splats(1.0f), tttt ); angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) ); angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) ); angles = spu_mul( angles, angle ); sines = sinf4( angles ); scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) ); scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask ); scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask ); return Quat( spu_madd( start.get128(), scale0, spu_mul( unitQuat1.get128(), scale1 ) ) ); } inline const Quat squad( float t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 ) { Quat tmp0, tmp1; tmp0 = slerp( t, unitQuat0, unitQuat3 ); tmp1 = slerp( t, unitQuat1, unitQuat2 ); return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); } inline vec_float4 Quat::get128( ) const { return mVec128; } inline Quat & Quat::operator =( Quat quat ) { mVec128 = quat.mVec128; return *this; } inline Quat & Quat::setXYZ( Vector3 vec ) { mVec128 = spu_sel( vec.get128(), mVec128, (vec_uint4)spu_maskb(0x000f) ); return *this; } inline const Vector3 Quat::getXYZ( ) const { return Vector3( mVec128 ); } inline Quat & Quat::setX( float _x ) { mVec128 = spu_insert( _x, mVec128, 0 ); return *this; } inline float Quat::getX( ) const { return spu_extract( mVec128, 0 ); } inline Quat & Quat::setY( float _y ) { mVec128 = spu_insert( _y, mVec128, 1 ); return *this; } inline float Quat::getY( ) const { return spu_extract( mVec128, 1 ); } inline Quat & Quat::setZ( float _z ) { mVec128 = spu_insert( _z, mVec128, 2 ); return *this; } inline float Quat::getZ( ) const { return spu_extract( mVec128, 2 ); } inline Quat & Quat::setW( float _w ) { mVec128 = spu_insert( _w, mVec128, 3 ); return *this; } inline float Quat::getW( ) const { return spu_extract( mVec128, 3 ); } inline Quat & Quat::setElem( int idx, float value ) { mVec128 = spu_insert( value, mVec128, idx ); return *this; } inline float Quat::getElem( int idx ) const { return spu_extract( mVec128, idx ); } inline VecIdx Quat::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline float Quat::operator []( int idx ) const { return spu_extract( mVec128, idx ); } inline const Quat Quat::operator +( Quat quat ) const { return Quat( spu_add( mVec128, quat.mVec128 ) ); } inline const Quat Quat::operator -( Quat quat ) const { return Quat( spu_sub( mVec128, quat.mVec128 ) ); } inline const Quat Quat::operator *( float scalar ) const { return Quat( spu_mul( mVec128, spu_splats(scalar) ) ); } inline Quat & Quat::operator +=( Quat quat ) { *this = *this + quat; return *this; } inline Quat & Quat::operator -=( Quat quat ) { *this = *this - quat; return *this; } inline Quat & Quat::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Quat Quat::operator /( float scalar ) const { return Quat( divf4( mVec128, spu_splats(scalar) ) ); } inline Quat & Quat::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline const Quat Quat::operator -( ) const { return Quat( negatef4( mVec128 ) ); } inline const Quat operator *( float scalar, Quat quat ) { return quat * scalar; } inline float dot( Quat quat0, Quat quat1 ) { return spu_extract( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 ); } inline float norm( Quat quat ) { return spu_extract( _vmathVfDot4( quat.get128(), quat.get128() ), 0 ); } inline float length( Quat quat ) { return sqrtf( norm( quat ) ); } inline const Quat normalize( Quat quat ) { vec_float4 dot = _vmathVfDot4( quat.get128(), quat.get128() ); return Quat( spu_mul( quat.get128(), rsqrtf4( dot ) ) ); } inline const Quat Quat::rotation( Vector3 unitVec0, Vector3 unitVec1 ) { Vector3 crossVec; vec_float4 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); cosAngle = spu_shuffle( cosAngle, cosAngle, (vec_uchar16)spu_splats(0x00010203) ); cosAngleX2Plus2 = spu_madd( cosAngle, spu_splats(2.0f), spu_splats(2.0f) ); recipCosHalfAngleX2 = rsqrtf4( cosAngleX2Plus2 ); cosHalfAngleX2 = spu_mul( recipCosHalfAngleX2, cosAngleX2Plus2 ); crossVec = cross( unitVec0, unitVec1 ); res = spu_mul( crossVec.get128(), recipCosHalfAngleX2 ); res = spu_sel( res, spu_mul( cosHalfAngleX2, spu_splats(0.5f) ), (vec_uint4)spu_maskb(0x000f) ); return Quat( res ); } inline const Quat Quat::rotation( float radians, Vector3 unitVec ) { vec_float4 s, c, angle, res; angle = spu_mul( spu_splats(radians), spu_splats(0.5f) ); sincosf4( angle, &s, &c ); res = spu_sel( spu_mul( unitVec.get128(), s ), c, (vec_uint4)spu_maskb(0x000f) ); return Quat( res ); } inline const Quat Quat::rotationX( float radians ) { vec_float4 s, c, angle, res; angle = spu_mul( spu_splats(radians), spu_splats(0.5f) ); sincosf4( angle, &s, &c ); res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0xf000) ); res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) ); return Quat( res ); } inline const Quat Quat::rotationY( float radians ) { vec_float4 s, c, angle, res; angle = spu_mul( spu_splats(radians), spu_splats(0.5f) ); sincosf4( angle, &s, &c ); res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0x0f00) ); res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) ); return Quat( res ); } inline const Quat Quat::rotationZ( float radians ) { vec_float4 s, c, angle, res; angle = spu_mul( spu_splats(radians), spu_splats(0.5f) ); sincosf4( angle, &s, &c ); res = spu_sel( spu_splats(0.0f), s, (vec_uint4)spu_maskb(0x00f0) ); res = spu_sel( res, c, (vec_uint4)spu_maskb(0x000f) ); return Quat( res ); } inline const Quat Quat::operator *( Quat quat ) const { vec_float4 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; vec_float4 product, l_wxyz, r_wxyz, xy, qw; ldata = mVec128; rdata = quat.mVec128; vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); tmp0 = spu_shuffle( ldata, ldata, _VECTORMATH_SHUF_YZXW ); tmp1 = spu_shuffle( rdata, rdata, _VECTORMATH_SHUF_ZXYW ); tmp2 = spu_shuffle( ldata, ldata, _VECTORMATH_SHUF_ZXYW ); tmp3 = spu_shuffle( rdata, rdata, _VECTORMATH_SHUF_YZXW ); qv = spu_mul( spu_shuffle( ldata, ldata, shuffle_wwww ), rdata ); qv = spu_madd( spu_shuffle( rdata, rdata, shuffle_wwww ), ldata, qv ); qv = spu_madd( tmp0, tmp1, qv ); qv = spu_nmsub( tmp2, tmp3, qv ); product = spu_mul( ldata, rdata ); l_wxyz = spu_rlqwbyte( ldata, 12 ); r_wxyz = spu_rlqwbyte( rdata, 12 ); qw = spu_nmsub( l_wxyz, r_wxyz, product ); xy = spu_madd( l_wxyz, r_wxyz, product ); qw = spu_sub( qw, spu_rlqwbyte( xy, 8 ) ); return Quat( spu_sel( qv, qw, (vec_uint4)spu_maskb( 0x000f ) ) ); } inline Quat & Quat::operator *=( Quat quat ) { *this = *this * quat; return *this; } inline const Vector3 rotate( Quat quat, Vector3 vec ) { vec_float4 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; qdata = quat.get128(); vdata = vec.get128(); vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); tmp0 = spu_shuffle( qdata, qdata, _VECTORMATH_SHUF_YZXW ); tmp1 = spu_shuffle( vdata, vdata, _VECTORMATH_SHUF_ZXYW ); tmp2 = spu_shuffle( qdata, qdata, _VECTORMATH_SHUF_ZXYW ); tmp3 = spu_shuffle( vdata, vdata, _VECTORMATH_SHUF_YZXW ); wwww = spu_shuffle( qdata, qdata, shuffle_wwww ); qv = spu_mul( wwww, vdata ); qv = spu_madd( tmp0, tmp1, qv ); qv = spu_nmsub( tmp2, tmp3, qv ); product = spu_mul( qdata, vdata ); qw = spu_madd( spu_rlqwbyte( qdata, 4 ), spu_rlqwbyte( vdata, 4 ), product ); qw = spu_add( spu_rlqwbyte( product, 8 ), qw ); tmp1 = spu_shuffle( qv, qv, _VECTORMATH_SHUF_ZXYW ); tmp3 = spu_shuffle( qv, qv, _VECTORMATH_SHUF_YZXW ); res = spu_mul( spu_shuffle( qw, qw, shuffle_xxxx ), qdata ); res = spu_madd( wwww, qv, res ); res = spu_madd( tmp0, tmp1, res ); res = spu_nmsub( tmp2, tmp3, res ); return Vector3( res ); } inline const Quat conj( Quat quat ) { return Quat( spu_xor( quat.get128(), ((vec_float4)(vec_int4){0x80000000,0x80000000,0x80000000,0}) ) ); } inline const Quat select( Quat quat0, Quat quat1, bool select1 ) { return Quat( spu_sel( quat0.get128(), quat1.get128(), spu_splats( (unsigned int)-(select1 > 0) ) ) ); } #ifdef _VECTORMATH_DEBUG inline void print( Quat quat ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = quat.get128(); printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } inline void print( Quat quat, const char * name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = quat.get128(); printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/spu/cpp/quat_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_QUAT_SOA_CPP_H #define _VECTORMATH_QUAT_SOA_CPP_H //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Soa { inline Quat::Quat( const Quat & quat ) { mX = quat.mX; mY = quat.mY; mZ = quat.mZ; mW = quat.mW; } inline Quat::Quat( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { mX = _x; mY = _y; mZ = _z; mW = _w; } inline Quat::Quat( const Vector3 & xyz, vec_float4 _w ) { this->setXYZ( xyz ); this->setW( _w ); } inline Quat::Quat( const Vector4 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); mW = vec.getW(); } inline Quat::Quat( vec_float4 scalar ) { mX = scalar; mY = scalar; mZ = scalar; mW = scalar; } inline Quat::Quat( Aos::Quat quat ) { vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); vec_float4 vec128 = quat.get128(); mX = spu_shuffle( vec128, vec128, shuffle_xxxx ); mY = spu_shuffle( vec128, vec128, shuffle_yyyy ); mZ = spu_shuffle( vec128, vec128, shuffle_zzzz ); mW = spu_shuffle( vec128, vec128, shuffle_wwww ); } inline Quat::Quat( Aos::Quat quat0, Aos::Quat quat1, Aos::Quat quat2, Aos::Quat quat3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( quat0.get128(), quat2.get128(), _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( quat1.get128(), quat3.get128(), _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( quat0.get128(), quat2.get128(), _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( quat1.get128(), quat3.get128(), _VECTORMATH_SHUF_ZCWD ); mX = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); mY = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); mZ = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); mW = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ); } inline const Quat Quat::identity( ) { return Quat( spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) ); } inline const Quat lerp( vec_float4 t, const Quat & quat0, const Quat & quat1 ) { return ( quat0 + ( ( quat1 - quat0 ) * t ) ); } inline const Quat slerp( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1 ) { Quat start; vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = dot( unitQuat0, unitQuat1 ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(0.0f), cosAngle ); cosAngle = spu_sel( cosAngle, negatef4( cosAngle ), selectMask ); start.setX( spu_sel( unitQuat0.getX(), negatef4( unitQuat0.getX() ), selectMask ) ); start.setY( spu_sel( unitQuat0.getY(), negatef4( unitQuat0.getY() ), selectMask ) ); start.setZ( spu_sel( unitQuat0.getZ(), negatef4( unitQuat0.getZ() ), selectMask ) ); start.setW( spu_sel( unitQuat0.getW(), negatef4( unitQuat0.getW() ), selectMask ) ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = recipf4( sinf4( angle ) ); 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 ); scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask ); return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); } inline const Quat squad( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) { Quat tmp0, tmp1; tmp0 = slerp( t, unitQuat0, unitQuat3 ); tmp1 = slerp( t, unitQuat1, unitQuat2 ); return slerp( spu_mul( spu_mul( spu_splats(2.0f), t ), spu_sub( spu_splats(1.0f), t ) ), tmp0, tmp1 ); } inline void Quat::get4Aos( Aos::Quat & result0, Aos::Quat & result1, Aos::Quat & result2, Aos::Quat & result3 ) const { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mY, mW, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( mY, mW, _VECTORMATH_SHUF_ZCWD ); result0 = Aos::Quat( spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ) ); result1 = Aos::Quat( spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ) ); result2 = Aos::Quat( spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ) ); result3 = Aos::Quat( spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ) ); } inline Quat & Quat::operator =( const Quat & quat ) { mX = quat.mX; mY = quat.mY; mZ = quat.mZ; mW = quat.mW; return *this; } inline Quat & Quat::setXYZ( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); return *this; } inline const Vector3 Quat::getXYZ( ) const { return Vector3( mX, mY, mZ ); } inline Quat & Quat::setX( vec_float4 _x ) { mX = _x; return *this; } inline vec_float4 Quat::getX( ) const { return mX; } inline Quat & Quat::setY( vec_float4 _y ) { mY = _y; return *this; } inline vec_float4 Quat::getY( ) const { return mY; } inline Quat & Quat::setZ( vec_float4 _z ) { mZ = _z; return *this; } inline vec_float4 Quat::getZ( ) const { return mZ; } inline Quat & Quat::setW( vec_float4 _w ) { mW = _w; return *this; } inline vec_float4 Quat::getW( ) const { return mW; } inline Quat & Quat::setElem( int idx, vec_float4 value ) { *(&mX + idx) = value; return *this; } inline vec_float4 Quat::getElem( int idx ) const { return *(&mX + idx); } inline Quat::vec_float4_t & Quat::operator []( int idx ) { return *(&mX + idx); } inline vec_float4 Quat::operator []( int idx ) const { return *(&mX + idx); } inline const Quat Quat::operator +( const Quat & quat ) const { return Quat( spu_add( mX, quat.mX ), spu_add( mY, quat.mY ), spu_add( mZ, quat.mZ ), spu_add( mW, quat.mW ) ); } inline const Quat Quat::operator -( const Quat & quat ) const { return Quat( spu_sub( mX, quat.mX ), spu_sub( mY, quat.mY ), spu_sub( mZ, quat.mZ ), spu_sub( mW, quat.mW ) ); } inline const Quat Quat::operator *( vec_float4 scalar ) const { return Quat( spu_mul( mX, scalar ), spu_mul( mY, scalar ), spu_mul( mZ, scalar ), spu_mul( mW, scalar ) ); } inline Quat & Quat::operator +=( const Quat & quat ) { *this = *this + quat; return *this; } inline Quat & Quat::operator -=( const Quat & quat ) { *this = *this - quat; return *this; } inline Quat & Quat::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Quat Quat::operator /( vec_float4 scalar ) const { return Quat( divf4( mX, scalar ), divf4( mY, scalar ), divf4( mZ, scalar ), divf4( mW, scalar ) ); } inline Quat & Quat::operator /=( vec_float4 scalar ) { *this = *this / scalar; return *this; } inline const Quat Quat::operator -( ) const { return Quat( negatef4( mX ), negatef4( mY ), negatef4( mZ ), negatef4( mW ) ); } inline const Quat operator *( vec_float4 scalar, const Quat & quat ) { return quat * scalar; } inline vec_float4 dot( const Quat & quat0, const Quat & quat1 ) { vec_float4 result; result = spu_mul( quat0.getX(), quat1.getX() ); result = spu_add( result, spu_mul( quat0.getY(), quat1.getY() ) ); result = spu_add( result, spu_mul( quat0.getZ(), quat1.getZ() ) ); result = spu_add( result, spu_mul( quat0.getW(), quat1.getW() ) ); return result; } inline vec_float4 norm( const Quat & quat ) { vec_float4 result; result = spu_mul( quat.getX(), quat.getX() ); result = spu_add( result, spu_mul( quat.getY(), quat.getY() ) ); result = spu_add( result, spu_mul( quat.getZ(), quat.getZ() ) ); result = spu_add( result, spu_mul( quat.getW(), quat.getW() ) ); return result; } inline vec_float4 length( const Quat & quat ) { return sqrtf4( norm( quat ) ); } inline const Quat normalize( const Quat & quat ) { vec_float4 lenSqr, lenInv; lenSqr = norm( quat ); lenInv = rsqrtf4( lenSqr ); return Quat( spu_mul( quat.getX(), lenInv ), spu_mul( quat.getY(), lenInv ), spu_mul( quat.getZ(), lenInv ), spu_mul( quat.getW(), lenInv ) ); } inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) { vec_float4 cosHalfAngleX2, recipCosHalfAngleX2; cosHalfAngleX2 = sqrtf4( spu_mul( spu_splats(2.0f), spu_add( spu_splats(1.0f), dot( unitVec0, unitVec1 ) ) ) ); recipCosHalfAngleX2 = recipf4( cosHalfAngleX2 ); return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), spu_mul( cosHalfAngleX2, spu_splats(0.5f) ) ); } inline const Quat Quat::rotation( vec_float4 radians, const Vector3 & unitVec ) { vec_float4 s, c, angle; angle = spu_mul( radians, spu_splats(0.5f) ); sincosf4( angle, &s, &c ); return Quat( ( unitVec * s ), c ); } inline const Quat Quat::rotationX( vec_float4 radians ) { vec_float4 s, c, angle; angle = spu_mul( radians, spu_splats(0.5f) ); sincosf4( angle, &s, &c ); return Quat( s, spu_splats(0.0f), spu_splats(0.0f), c ); } inline const Quat Quat::rotationY( vec_float4 radians ) { vec_float4 s, c, angle; angle = spu_mul( radians, spu_splats(0.5f) ); sincosf4( angle, &s, &c ); return Quat( spu_splats(0.0f), s, spu_splats(0.0f), c ); } inline const Quat Quat::rotationZ( vec_float4 radians ) { vec_float4 s, c, angle; angle = spu_mul( radians, spu_splats(0.5f) ); sincosf4( angle, &s, &c ); return Quat( spu_splats(0.0f), spu_splats(0.0f), s, c ); } inline const Quat Quat::operator *( const Quat & quat ) const { return Quat( 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 ) ), 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 ) ), 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 ) ), 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 ) ) ); } inline Quat & Quat::operator *=( const Quat & quat ) { *this = *this * quat; return *this; } inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) { vec_float4 tmpX, tmpY, tmpZ, tmpW; tmpX = spu_sub( spu_add( spu_mul( quat.getW(), vec.getX() ), spu_mul( quat.getY(), vec.getZ() ) ), spu_mul( quat.getZ(), vec.getY() ) ); tmpY = spu_sub( spu_add( spu_mul( quat.getW(), vec.getY() ), spu_mul( quat.getZ(), vec.getX() ) ), spu_mul( quat.getX(), vec.getZ() ) ); tmpZ = spu_sub( spu_add( spu_mul( quat.getW(), vec.getZ() ), spu_mul( quat.getX(), vec.getY() ) ), spu_mul( quat.getY(), vec.getX() ) ); tmpW = spu_add( spu_add( spu_mul( quat.getX(), vec.getX() ), spu_mul( quat.getY(), vec.getY() ) ), spu_mul( quat.getZ(), vec.getZ() ) ); return Vector3( 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() ) ), 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() ) ), 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() ) ) ); } inline const Quat conj( const Quat & quat ) { return Quat( negatef4( quat.getX() ), negatef4( quat.getY() ), negatef4( quat.getZ() ), quat.getW() ); } inline const Quat select( const Quat & quat0, const Quat & quat1, vec_uint4 select1 ) { return Quat( spu_sel( quat0.getX(), quat1.getX(), select1 ), spu_sel( quat0.getY(), quat1.getY(), select1 ), spu_sel( quat0.getZ(), quat1.getZ(), select1 ), spu_sel( quat0.getW(), quat1.getW(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Quat & quat ) { Aos::Quat vec0, vec1, vec2, vec3; quat.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } inline void print( const Quat & quat, const char * name ) { Aos::Quat vec0, vec1, vec2, vec3; printf( "%s:\n", name ); quat.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } #endif } // namespace Soa } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/spu/cpp/vec_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_AOS_CPP_H #define _VECTORMATH_VEC_AOS_CPP_H //----------------------------------------------------------------------------- // Constants // for shuffles, words are labeled [x,y,z,w] [a,b,c,d] #define _VECTORMATH_SHUF_X 0x00010203 #define _VECTORMATH_SHUF_Y 0x04050607 #define _VECTORMATH_SHUF_Z 0x08090a0b #define _VECTORMATH_SHUF_W 0x0c0d0e0f #define _VECTORMATH_SHUF_A 0x10111213 #define _VECTORMATH_SHUF_B 0x14151617 #define _VECTORMATH_SHUF_C 0x18191a1b #define _VECTORMATH_SHUF_D 0x1c1d1e1f #define _VECTORMATH_SHUF_0 0x80808080 #define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A } #define _VECTORMATH_SHUF_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_W } #define _VECTORMATH_SHUF_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_W } #define _VECTORMATH_SHUF_WABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C } #define _VECTORMATH_SHUF_ZWAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B } #define _VECTORMATH_SHUF_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A } #define _VECTORMATH_SHUF_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B } #define _VECTORMATH_SHUF_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_C } #define _VECTORMATH_UNIT_1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f } #define _VECTORMATH_UNIT_0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f } #define _VECTORMATH_UNIT_0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f } #define _VECTORMATH_SLERP_TOL 0.999f //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS static inline vec_float4 _vmathVfDot3( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 result; result = spu_mul( vec0, vec1 ); result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result ); return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result ); } static inline vec_float4 _vmathVfDot4( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 result; result = spu_mul( vec0, vec1 ); result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result ); return spu_add( spu_rlqwbyte( result, 8 ), result ); } static inline vec_float4 _vmathVfCross( vec_float4 vec0, vec_float4 vec1 ) { vec_float4 tmp0, tmp1, tmp2, tmp3, result; tmp0 = spu_shuffle( vec0, vec0, _VECTORMATH_SHUF_YZXW ); tmp1 = spu_shuffle( vec1, vec1, _VECTORMATH_SHUF_ZXYW ); tmp2 = spu_shuffle( vec0, vec0, _VECTORMATH_SHUF_ZXYW ); tmp3 = spu_shuffle( vec1, vec1, _VECTORMATH_SHUF_YZXW ); result = spu_mul( tmp0, tmp1 ); result = spu_nmsub( tmp2, tmp3, result ); return result; } static inline vec_uint4 _vmathVfToHalfFloatsUnpacked(vec_float4 v) { vec_int4 bexp; vec_uint4 mant, sign, hfloat; vec_uint4 notZero, isInf; const vec_uint4 hfloatInf = spu_splats(0x00007c00u); const vec_uint4 mergeMant = spu_splats(0x000003ffu); const vec_uint4 mergeSign = spu_splats(0x00008000u); sign = spu_rlmask((vec_uint4)v, -16); mant = spu_rlmask((vec_uint4)v, -13); bexp = spu_and(spu_rlmask((vec_int4)v, -23), 0xff); notZero = spu_cmpgt(bexp, 112); isInf = spu_cmpgt(bexp, 142); bexp = spu_add(bexp, -112); bexp = spu_sl(bexp, 10); hfloat = spu_sel((vec_uint4)bexp, mant, mergeMant); hfloat = spu_sel(spu_splats(0u), hfloat, notZero); hfloat = spu_sel(hfloat, hfloatInf, isInf); hfloat = spu_sel(hfloat, sign, mergeSign); return hfloat; } static inline vec_ushort8 _vmath2VfToHalfFloats(vec_float4 u, vec_float4 v) { vec_uint4 hfloat_u, hfloat_v; const vec_uchar16 pack = (vec_uchar16){2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31}; hfloat_u = _vmathVfToHalfFloatsUnpacked(u); hfloat_v = _vmathVfToHalfFloatsUnpacked(v); return (vec_ushort8)spu_shuffle(hfloat_u, hfloat_v, pack); } #endif namespace Vectormath { namespace Aos { inline VecIdx::operator float() const { return spu_extract( ref, i ); } inline float VecIdx::operator =( float scalar ) { ref = spu_insert( scalar, ref, i ); return scalar; } inline float VecIdx::operator =( const VecIdx& scalar ) { return *this = float(scalar); } inline float VecIdx::operator *=( float scalar ) { float tmp = spu_extract( ref, i ) * scalar; ref = spu_insert( tmp, ref, i ); return tmp; } inline float VecIdx::operator /=( float scalar ) { float tmp = spu_extract( ref, i ) / scalar; ref = spu_insert( tmp, ref, i ); return tmp; } inline float VecIdx::operator +=( float scalar ) { float tmp = spu_extract( ref, i ) + scalar; ref = spu_insert( tmp, ref, i ); return tmp; } inline float VecIdx::operator -=( float scalar ) { float tmp = spu_extract( ref, i ) - scalar; ref = spu_insert( tmp, ref, i ); return tmp; } inline Vector3::Vector3( float _x, float _y, float _z ) { mVec128 = (vec_float4){ _x, _y, _z, 0.0f }; } inline Vector3::Vector3( Point3 pnt ) { mVec128 = pnt.get128(); } inline Vector3::Vector3( float scalar ) { mVec128 = spu_splats( scalar ); } inline Vector3::Vector3( vec_float4 vf4 ) { mVec128 = vf4; } inline const Vector3 Vector3::xAxis( ) { return Vector3( _VECTORMATH_UNIT_1000 ); } inline const Vector3 Vector3::yAxis( ) { return Vector3( _VECTORMATH_UNIT_0100 ); } inline const Vector3 Vector3::zAxis( ) { return Vector3( _VECTORMATH_UNIT_0010 ); } inline const Vector3 lerp( float t, Vector3 vec0, Vector3 vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector3 slerp( float t, Vector3 unitVec0, Vector3 unitVec1 ) { vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = spu_splats(t); oneMinusT = spu_sub( spu_splats(1.0f), tttt ); angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) ); angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) ); angles = spu_mul( angles, angle ); sines = sinf4( angles ); scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) ); scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask ); scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask ); return Vector3( spu_madd( unitVec0.get128(), scale0, spu_mul( unitVec1.get128(), scale1 ) ) ); } inline vec_float4 Vector3::get128( ) const { return mVec128; } inline void storeXYZ( Vector3 vec, vec_float4 * quad ) { vec_float4 dstVec = *quad; vec_uint4 mask = (vec_uint4)spu_maskb(0x000f); dstVec = spu_sel(vec.get128(), dstVec, mask); *quad = dstVec; } inline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyz1 = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_WABC ); xyz2 = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_ZWAB ); xyz3 = spu_rlqwbyte( zxyz, 4 ); vec0 = Vector3( xyzx ); vec1 = Vector3( xyz1 ); vec2 = Vector3( xyz2 ); vec3 = Vector3( xyz3 ); } inline void storeXYZArray( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz; xyzx = spu_shuffle( vec0.get128(), vec1.get128(), _VECTORMATH_SHUF_XYZA ); yzxy = spu_shuffle( vec1.get128(), vec2.get128(), _VECTORMATH_SHUF_YZAB ); zxyz = spu_shuffle( vec2.get128(), vec3.get128(), _VECTORMATH_SHUF_ZABC ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } inline void storeHalfFloats( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4, Vector3 vec5, Vector3 vec6, Vector3 vec7, vec_ushort8 * threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; storeXYZArray( vec0, vec1, vec2, vec3, xyz0 ); storeXYZArray( vec4, vec5, vec6, vec7, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } inline Vector3 & Vector3::operator =( Vector3 vec ) { mVec128 = vec.mVec128; return *this; } inline Vector3 & Vector3::setX( float _x ) { mVec128 = spu_insert( _x, mVec128, 0 ); return *this; } inline float Vector3::getX( ) const { return spu_extract( mVec128, 0 ); } inline Vector3 & Vector3::setY( float _y ) { mVec128 = spu_insert( _y, mVec128, 1 ); return *this; } inline float Vector3::getY( ) const { return spu_extract( mVec128, 1 ); } inline Vector3 & Vector3::setZ( float _z ) { mVec128 = spu_insert( _z, mVec128, 2 ); return *this; } inline float Vector3::getZ( ) const { return spu_extract( mVec128, 2 ); } inline Vector3 & Vector3::setElem( int idx, float value ) { mVec128 = spu_insert( value, mVec128, idx ); return *this; } inline float Vector3::getElem( int idx ) const { return spu_extract( mVec128, idx ); } inline VecIdx Vector3::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline float Vector3::operator []( int idx ) const { return spu_extract( mVec128, idx ); } inline const Vector3 Vector3::operator +( Vector3 vec ) const { return Vector3( spu_add( mVec128, vec.mVec128 ) ); } inline const Vector3 Vector3::operator -( Vector3 vec ) const { return Vector3( spu_sub( mVec128, vec.mVec128 ) ); } inline const Point3 Vector3::operator +( Point3 pnt ) const { return Point3( spu_add( mVec128, pnt.get128() ) ); } inline const Vector3 Vector3::operator *( float scalar ) const { return Vector3( spu_mul( mVec128, spu_splats(scalar) ) ); } inline Vector3 & Vector3::operator +=( Vector3 vec ) { *this = *this + vec; return *this; } inline Vector3 & Vector3::operator -=( Vector3 vec ) { *this = *this - vec; return *this; } inline Vector3 & Vector3::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Vector3 Vector3::operator /( float scalar ) const { return Vector3( divf4( mVec128, spu_splats(scalar) ) ); } inline Vector3 & Vector3::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline const Vector3 Vector3::operator -( ) const { return Vector3( negatef4( mVec128 ) ); } inline const Vector3 operator *( float scalar, Vector3 vec ) { return vec * scalar; } inline const Vector3 mulPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( spu_mul( vec0.get128(), vec1.get128() ) ); } inline const Vector3 divPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( divf4( vec0.get128(), vec1.get128() ) ); } inline const Vector3 recipPerElem( Vector3 vec ) { return Vector3( recipf4( vec.get128() ) ); } inline const Vector3 sqrtPerElem( Vector3 vec ) { return Vector3( sqrtf4( vec.get128() ) ); } inline const Vector3 rsqrtPerElem( Vector3 vec ) { return Vector3( rsqrtf4( vec.get128() ) ); } inline const Vector3 absPerElem( Vector3 vec ) { return Vector3( fabsf4( vec.get128() ) ); } inline const Vector3 copySignPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( copysignf4( vec0.get128(), vec1.get128() ) ); } inline const Vector3 maxPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( fmaxf4( vec0.get128(), vec1.get128() ) ); } inline float maxElem( Vector3 vec ) { vec_float4 result; result = fmaxf4( spu_promote( spu_extract( vec.get128(), 1 ), 0 ), vec.get128() ); result = fmaxf4( spu_promote( spu_extract( vec.get128(), 2 ), 0 ), result ); return spu_extract( result, 0 ); } inline const Vector3 minPerElem( Vector3 vec0, Vector3 vec1 ) { return Vector3( fminf4( vec0.get128(), vec1.get128() ) ); } inline float minElem( Vector3 vec ) { vec_float4 result; result = fminf4( spu_promote( spu_extract( vec.get128(), 1 ), 0 ), vec.get128() ); result = fminf4( spu_promote( spu_extract( vec.get128(), 2 ), 0 ), result ); return spu_extract( result, 0 ); } inline float sum( Vector3 vec ) { return spu_extract( vec.get128(), 0 ) + spu_extract( vec.get128(), 1 ) + spu_extract( vec.get128(), 2 ); } inline float dot( Vector3 vec0, Vector3 vec1 ) { return spu_extract( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 ); } inline float lengthSqr( Vector3 vec ) { return spu_extract( _vmathVfDot3( vec.get128(), vec.get128() ), 0 ); } inline float length( Vector3 vec ) { return sqrtf( lengthSqr( vec ) ); } inline const Vector3 normalize( Vector3 vec ) { vec_float4 dot = _vmathVfDot3( vec.get128(), vec.get128() ); dot = spu_shuffle( dot, dot, (vec_uchar16)spu_splats(0x00010203) ); return Vector3( spu_mul( vec.get128(), rsqrtf4( dot ) ) ); } inline const Vector3 cross( Vector3 vec0, Vector3 vec1 ) { return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) ); } inline const Vector3 select( Vector3 vec0, Vector3 vec1, bool select1 ) { return Vector3( spu_sel( vec0.get128(), vec1.get128(), spu_splats( (unsigned int)-(select1 > 0) ) ) ); } #ifdef _VECTORMATH_DEBUG inline void print( Vector3 vec ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } inline void print( Vector3 vec, const char * name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif inline Vector4::Vector4( float _x, float _y, float _z, float _w ) { mVec128 = (vec_float4){ _x, _y, _z, _w }; } inline Vector4::Vector4( Vector3 xyz, float _w ) { mVec128 = spu_shuffle( xyz.get128(), spu_promote( _w, 0 ), _VECTORMATH_SHUF_XYZA ); } inline Vector4::Vector4( Vector3 vec ) { mVec128 = spu_sel( vec.get128(), spu_splats(0.0f), (vec_uint4)spu_maskb(0x000f) ); } inline Vector4::Vector4( Point3 pnt ) { mVec128 = spu_sel( pnt.get128(), spu_splats(1.0f), (vec_uint4)spu_maskb(0x000f) ); } inline Vector4::Vector4( Quat quat ) { mVec128 = quat.get128(); } inline Vector4::Vector4( float scalar ) { mVec128 = spu_splats( scalar ); } inline Vector4::Vector4( vec_float4 vf4 ) { mVec128 = vf4; } inline const Vector4 Vector4::xAxis( ) { return Vector4( _VECTORMATH_UNIT_1000 ); } inline const Vector4 Vector4::yAxis( ) { return Vector4( _VECTORMATH_UNIT_0100 ); } inline const Vector4 Vector4::zAxis( ) { return Vector4( _VECTORMATH_UNIT_0010 ); } inline const Vector4 Vector4::wAxis( ) { return Vector4( _VECTORMATH_UNIT_0001 ); } inline const Vector4 lerp( float t, Vector4 vec0, Vector4 vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector4 slerp( float t, Vector4 unitVec0, Vector4 unitVec1 ) { vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; vec_uint4 selectMask; vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() ); cosAngle = spu_shuffle( cosAngle, cosAngle, shuffle_xxxx ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); tttt = spu_splats(t); oneMinusT = spu_sub( spu_splats(1.0f), tttt ); angles = spu_sel( spu_splats(1.0f), oneMinusT, (vec_uint4)spu_maskb(0x0f00) ); angles = spu_sel( angles, tttt, (vec_uint4)spu_maskb(0x00f0) ); angles = spu_mul( angles, angle ); sines = sinf4( angles ); scales = divf4( sines, spu_shuffle( sines, sines, shuffle_xxxx ) ); scale0 = spu_sel( oneMinusT, spu_shuffle( scales, scales, shuffle_yyyy ), selectMask ); scale1 = spu_sel( tttt, spu_shuffle( scales, scales, shuffle_zzzz ), selectMask ); return Vector4( spu_madd( unitVec0.get128(), scale0, spu_mul( unitVec1.get128(), scale1 ) ) ); } inline vec_float4 Vector4::get128( ) const { return mVec128; } inline void storeHalfFloats( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3, vec_ushort8 * twoQuads ) { twoQuads[0] = _vmath2VfToHalfFloats(vec0.get128(), vec1.get128()); twoQuads[1] = _vmath2VfToHalfFloats(vec2.get128(), vec3.get128()); } inline Vector4 & Vector4::operator =( Vector4 vec ) { mVec128 = vec.mVec128; return *this; } inline Vector4 & Vector4::setXYZ( Vector3 vec ) { mVec128 = spu_sel( vec.get128(), mVec128, (vec_uint4)spu_maskb(0x000f) ); return *this; } inline const Vector3 Vector4::getXYZ( ) const { return Vector3( mVec128 ); } inline Vector4 & Vector4::setX( float _x ) { mVec128 = spu_insert( _x, mVec128, 0 ); return *this; } inline float Vector4::getX( ) const { return spu_extract( mVec128, 0 ); } inline Vector4 & Vector4::setY( float _y ) { mVec128 = spu_insert( _y, mVec128, 1 ); return *this; } inline float Vector4::getY( ) const { return spu_extract( mVec128, 1 ); } inline Vector4 & Vector4::setZ( float _z ) { mVec128 = spu_insert( _z, mVec128, 2 ); return *this; } inline float Vector4::getZ( ) const { return spu_extract( mVec128, 2 ); } inline Vector4 & Vector4::setW( float _w ) { mVec128 = spu_insert( _w, mVec128, 3 ); return *this; } inline float Vector4::getW( ) const { return spu_extract( mVec128, 3 ); } inline Vector4 & Vector4::setElem( int idx, float value ) { mVec128 = spu_insert( value, mVec128, idx ); return *this; } inline float Vector4::getElem( int idx ) const { return spu_extract( mVec128, idx ); } inline VecIdx Vector4::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline float Vector4::operator []( int idx ) const { return spu_extract( mVec128, idx ); } inline const Vector4 Vector4::operator +( Vector4 vec ) const { return Vector4( spu_add( mVec128, vec.mVec128 ) ); } inline const Vector4 Vector4::operator -( Vector4 vec ) const { return Vector4( spu_sub( mVec128, vec.mVec128 ) ); } inline const Vector4 Vector4::operator *( float scalar ) const { return Vector4( spu_mul( mVec128, spu_splats(scalar) ) ); } inline Vector4 & Vector4::operator +=( Vector4 vec ) { *this = *this + vec; return *this; } inline Vector4 & Vector4::operator -=( Vector4 vec ) { *this = *this - vec; return *this; } inline Vector4 & Vector4::operator *=( float scalar ) { *this = *this * scalar; return *this; } inline const Vector4 Vector4::operator /( float scalar ) const { return Vector4( divf4( mVec128, spu_splats(scalar) ) ); } inline Vector4 & Vector4::operator /=( float scalar ) { *this = *this / scalar; return *this; } inline const Vector4 Vector4::operator -( ) const { return Vector4( negatef4( mVec128 ) ); } inline const Vector4 operator *( float scalar, Vector4 vec ) { return vec * scalar; } inline const Vector4 mulPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( spu_mul( vec0.get128(), vec1.get128() ) ); } inline const Vector4 divPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( divf4( vec0.get128(), vec1.get128() ) ); } inline const Vector4 recipPerElem( Vector4 vec ) { return Vector4( recipf4( vec.get128() ) ); } inline const Vector4 sqrtPerElem( Vector4 vec ) { return Vector4( sqrtf4( vec.get128() ) ); } inline const Vector4 rsqrtPerElem( Vector4 vec ) { return Vector4( rsqrtf4( vec.get128() ) ); } inline const Vector4 absPerElem( Vector4 vec ) { return Vector4( fabsf4( vec.get128() ) ); } inline const Vector4 copySignPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( copysignf4( vec0.get128(), vec1.get128() ) ); } inline const Vector4 maxPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( fmaxf4( vec0.get128(), vec1.get128() ) ); } inline float maxElem( Vector4 vec ) { vec_float4 result; result = fmaxf4( spu_promote( spu_extract( vec.get128(), 1 ), 0 ), vec.get128() ); result = fmaxf4( spu_promote( spu_extract( vec.get128(), 2 ), 0 ), result ); result = fmaxf4( spu_promote( spu_extract( vec.get128(), 3 ), 0 ), result ); return spu_extract( result, 0 ); } inline const Vector4 minPerElem( Vector4 vec0, Vector4 vec1 ) { return Vector4( fminf4( vec0.get128(), vec1.get128() ) ); } inline float minElem( Vector4 vec ) { vec_float4 result; result = fminf4( spu_promote( spu_extract( vec.get128(), 1 ), 0 ), vec.get128() ); result = fminf4( spu_promote( spu_extract( vec.get128(), 2 ), 0 ), result ); result = fminf4( spu_promote( spu_extract( vec.get128(), 3 ), 0 ), result ); return spu_extract( result, 0 ); } inline float sum( Vector4 vec ) { return spu_extract( vec.get128(), 0 ) + spu_extract( vec.get128(), 1 ) + spu_extract( vec.get128(), 2 ) + spu_extract( vec.get128(), 3 ); } inline float dot( Vector4 vec0, Vector4 vec1 ) { return spu_extract( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 ); } inline float lengthSqr( Vector4 vec ) { return spu_extract( _vmathVfDot4( vec.get128(), vec.get128() ), 0 ); } inline float length( Vector4 vec ) { return sqrtf( lengthSqr( vec ) ); } inline const Vector4 normalize( Vector4 vec ) { vec_float4 dot = _vmathVfDot4( vec.get128(), vec.get128() ); return Vector4( spu_mul( vec.get128(), rsqrtf4( dot ) ) ); } inline const Vector4 select( Vector4 vec0, Vector4 vec1, bool select1 ) { return Vector4( spu_sel( vec0.get128(), vec1.get128(), spu_splats( (unsigned int)-(select1 > 0) ) ) ); } #ifdef _VECTORMATH_DEBUG inline void print( Vector4 vec ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } inline void print( Vector4 vec, const char * name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = vec.get128(); printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); } #endif inline Point3::Point3( float _x, float _y, float _z ) { mVec128 = (vec_float4){ _x, _y, _z, 0.0f }; } inline Point3::Point3( Vector3 vec ) { mVec128 = vec.get128(); } inline Point3::Point3( float scalar ) { mVec128 = spu_splats( scalar ); } inline Point3::Point3( vec_float4 vf4 ) { mVec128 = vf4; } inline const Point3 lerp( float t, Point3 pnt0, Point3 pnt1 ) { return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); } inline vec_float4 Point3::get128( ) const { return mVec128; } inline void storeXYZ( Point3 pnt, vec_float4 * quad ) { vec_float4 dstVec = *quad; vec_uint4 mask = (vec_uint4)spu_maskb(0x000f); dstVec = spu_sel(pnt.get128(), dstVec, mask); *quad = dstVec; } inline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyz1, xyz2, xyz3; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyz1 = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_WABC ); xyz2 = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_ZWAB ); xyz3 = spu_rlqwbyte( zxyz, 4 ); pnt0 = Point3( xyzx ); pnt1 = Point3( xyz1 ); pnt2 = Point3( xyz2 ); pnt3 = Point3( xyz3 ); } inline void storeXYZArray( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz; xyzx = spu_shuffle( pnt0.get128(), pnt1.get128(), _VECTORMATH_SHUF_XYZA ); yzxy = spu_shuffle( pnt1.get128(), pnt2.get128(), _VECTORMATH_SHUF_YZAB ); zxyz = spu_shuffle( pnt2.get128(), pnt3.get128(), _VECTORMATH_SHUF_ZABC ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } inline void storeHalfFloats( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, Point3 pnt4, Point3 pnt5, Point3 pnt6, Point3 pnt7, vec_ushort8 * threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; storeXYZArray( pnt0, pnt1, pnt2, pnt3, xyz0 ); storeXYZArray( pnt4, pnt5, pnt6, pnt7, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } inline Point3 & Point3::operator =( Point3 pnt ) { mVec128 = pnt.mVec128; return *this; } inline Point3 & Point3::setX( float _x ) { mVec128 = spu_insert( _x, mVec128, 0 ); return *this; } inline float Point3::getX( ) const { return spu_extract( mVec128, 0 ); } inline Point3 & Point3::setY( float _y ) { mVec128 = spu_insert( _y, mVec128, 1 ); return *this; } inline float Point3::getY( ) const { return spu_extract( mVec128, 1 ); } inline Point3 & Point3::setZ( float _z ) { mVec128 = spu_insert( _z, mVec128, 2 ); return *this; } inline float Point3::getZ( ) const { return spu_extract( mVec128, 2 ); } inline Point3 & Point3::setElem( int idx, float value ) { mVec128 = spu_insert( value, mVec128, idx ); return *this; } inline float Point3::getElem( int idx ) const { return spu_extract( mVec128, idx ); } inline VecIdx Point3::operator []( int idx ) { return VecIdx( mVec128, idx ); } inline float Point3::operator []( int idx ) const { return spu_extract( mVec128, idx ); } inline const Vector3 Point3::operator -( Point3 pnt ) const { return Vector3( spu_sub( mVec128, pnt.mVec128 ) ); } inline const Point3 Point3::operator +( Vector3 vec ) const { return Point3( spu_add( mVec128, vec.get128() ) ); } inline const Point3 Point3::operator -( Vector3 vec ) const { return Point3( spu_sub( mVec128, vec.get128() ) ); } inline Point3 & Point3::operator +=( Vector3 vec ) { *this = *this + vec; return *this; } inline Point3 & Point3::operator -=( Vector3 vec ) { *this = *this - vec; return *this; } inline const Point3 mulPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( spu_mul( pnt0.get128(), pnt1.get128() ) ); } inline const Point3 divPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( divf4( pnt0.get128(), pnt1.get128() ) ); } inline const Point3 recipPerElem( Point3 pnt ) { return Point3( recipf4( pnt.get128() ) ); } inline const Point3 sqrtPerElem( Point3 pnt ) { return Point3( sqrtf4( pnt.get128() ) ); } inline const Point3 rsqrtPerElem( Point3 pnt ) { return Point3( rsqrtf4( pnt.get128() ) ); } inline const Point3 absPerElem( Point3 pnt ) { return Point3( fabsf4( pnt.get128() ) ); } inline const Point3 copySignPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( copysignf4( pnt0.get128(), pnt1.get128() ) ); } inline const Point3 maxPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( fmaxf4( pnt0.get128(), pnt1.get128() ) ); } inline float maxElem( Point3 pnt ) { vec_float4 result; result = fmaxf4( spu_promote( spu_extract( pnt.get128(), 1 ), 0 ), pnt.get128() ); result = fmaxf4( spu_promote( spu_extract( pnt.get128(), 2 ), 0 ), result ); return spu_extract( result, 0 ); } inline const Point3 minPerElem( Point3 pnt0, Point3 pnt1 ) { return Point3( fminf4( pnt0.get128(), pnt1.get128() ) ); } inline float minElem( Point3 pnt ) { vec_float4 result; result = fminf4( spu_promote( spu_extract( pnt.get128(), 1 ), 0 ), pnt.get128() ); result = fminf4( spu_promote( spu_extract( pnt.get128(), 2 ), 0 ), result ); return spu_extract( result, 0 ); } inline float sum( Point3 pnt ) { return spu_extract( pnt.get128(), 0 ) + spu_extract( pnt.get128(), 1 ) + spu_extract( pnt.get128(), 2 ); } inline const Point3 scale( Point3 pnt, float scaleVal ) { return mulPerElem( pnt, Point3( scaleVal ) ); } inline const Point3 scale( Point3 pnt, Vector3 scaleVec ) { return mulPerElem( pnt, Point3( scaleVec ) ); } inline float projection( Point3 pnt, Vector3 unitVec ) { return spu_extract( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 ); } inline float distSqrFromOrigin( Point3 pnt ) { return lengthSqr( Vector3( pnt ) ); } inline float distFromOrigin( Point3 pnt ) { return length( Vector3( pnt ) ); } inline float distSqr( Point3 pnt0, Point3 pnt1 ) { return lengthSqr( ( pnt1 - pnt0 ) ); } inline float dist( Point3 pnt0, Point3 pnt1 ) { return length( ( pnt1 - pnt0 ) ); } inline const Point3 select( Point3 pnt0, Point3 pnt1, bool select1 ) { return Point3( spu_sel( pnt0.get128(), pnt1.get128(), spu_splats( (unsigned int)-(select1 > 0) ) ) ); } #ifdef _VECTORMATH_DEBUG inline void print( Point3 pnt ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = pnt.get128(); printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); } inline void print( Point3 pnt, const char * name ) { union { vec_float4 v; float s[4]; } tmp; tmp.v = pnt.get128(); printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); } #endif } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/spu/cpp/vec_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VEC_SOA_CPP_H #define _VECTORMATH_VEC_SOA_CPP_H //----------------------------------------------------------------------------- // Constants // for shuffles, words are labeled [x,y,z,w] [a,b,c,d] #define _VECTORMATH_SHUF_X 0x00010203 #define _VECTORMATH_SHUF_Y 0x04050607 #define _VECTORMATH_SHUF_Z 0x08090a0b #define _VECTORMATH_SHUF_W 0x0c0d0e0f #define _VECTORMATH_SHUF_A 0x10111213 #define _VECTORMATH_SHUF_B 0x14151617 #define _VECTORMATH_SHUF_C 0x18191a1b #define _VECTORMATH_SHUF_D 0x1c1d1e1f #define _VECTORMATH_SHUF_0 0x80808080 #define _VECTORMATH_SHUF_XAYB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_ZCWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_ZBW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XCY0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_ZDW0 ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_0 }) #define _VECTORMATH_SHUF_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZDXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XDZB ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D, _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B }) #define _VECTORMATH_SHUF_YAWC ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_A, _VECTORMATH_SHUF_W, _VECTORMATH_SHUF_C }) #define _VECTORMATH_SHUF_ZBXD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_Z, _VECTORMATH_SHUF_B, _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SHUF_XYCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_SHUF_X, _VECTORMATH_SHUF_Y, _VECTORMATH_SHUF_C, _VECTORMATH_SHUF_D }) #define _VECTORMATH_SLERP_TOL 0.999f //----------------------------------------------------------------------------- // Definitions #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS #endif namespace Vectormath { namespace Soa { inline Vector3::Vector3( const Vector3 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; } inline Vector3::Vector3( vec_float4 _x, vec_float4 _y, vec_float4 _z ) { mX = _x; mY = _y; mZ = _z; } inline Vector3::Vector3( const Point3 & pnt ) { mX = pnt.getX(); mY = pnt.getY(); mZ = pnt.getZ(); } inline Vector3::Vector3( vec_float4 scalar ) { mX = scalar; mY = scalar; mZ = scalar; } inline Vector3::Vector3( Aos::Vector3 vec ) { vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_float4 vec128 = vec.get128(); mX = spu_shuffle( vec128, vec128, shuffle_xxxx ); mY = spu_shuffle( vec128, vec128, shuffle_yyyy ); mZ = spu_shuffle( vec128, vec128, shuffle_zzzz ); } inline Vector3::Vector3( Aos::Vector3 vec0, Aos::Vector3 vec1, Aos::Vector3 vec2, Aos::Vector3 vec3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( vec0.get128(), vec2.get128(), _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( vec1.get128(), vec3.get128(), _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( vec0.get128(), vec2.get128(), _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( vec1.get128(), vec3.get128(), _VECTORMATH_SHUF_ZCWD ); mX = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); mY = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); mZ = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); } inline const Vector3 Vector3::xAxis( ) { return Vector3( spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f) ); } inline const Vector3 Vector3::yAxis( ) { return Vector3( spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f) ); } inline const Vector3 Vector3::zAxis( ) { return Vector3( spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) ); } inline const Vector3 lerp( vec_float4 t, const Vector3 & vec0, const Vector3 & vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector3 slerp( vec_float4 t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) { vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = dot( unitVec0, unitVec1 ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = recipf4( sinf4( angle ) ); 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 ); scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask ); return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); } inline void Vector3::get4Aos( Aos::Vector3 & result0, Aos::Vector3 & result1, Aos::Vector3 & result2, Aos::Vector3 & result3 ) const { vec_float4 tmp0, tmp1; tmp0 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_ZCWD ); result0 = Aos::Vector3( spu_shuffle( tmp0, mY, _VECTORMATH_SHUF_XAYB ) ); result1 = Aos::Vector3( spu_shuffle( tmp0, mY, _VECTORMATH_SHUF_ZBW0 ) ); result2 = Aos::Vector3( spu_shuffle( tmp1, mY, _VECTORMATH_SHUF_XCY0 ) ); result3 = Aos::Vector3( spu_shuffle( tmp1, mY, _VECTORMATH_SHUF_ZDW0 ) ); } inline void loadXYZArray( Vector3 & vec, const vec_float4 * threeQuads ) { vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyxy = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_XYCD ); zxzx = spu_shuffle( zxyz, xyzx, _VECTORMATH_SHUF_XYCD ); yzyz = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_XYCD ); vec.setX( spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XDZB ) ); vec.setY( spu_shuffle( xyxy, yzyz, _VECTORMATH_SHUF_YAWC ) ); vec.setZ( spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_ZBXD ) ); } inline void storeXYZArray( const Vector3 & vec, vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz; xyxy = spu_shuffle( vec.getX(), vec.getY(), _VECTORMATH_SHUF_XAZC ); zxzx = spu_shuffle( vec.getZ(), vec.getX(), _VECTORMATH_SHUF_ZDXB ); yzyz = spu_shuffle( vec.getY(), vec.getZ(), _VECTORMATH_SHUF_YBWD ); xyzx = spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XYCD ); yzxy = spu_shuffle( yzyz, xyxy, _VECTORMATH_SHUF_XYCD ); zxyz = spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_XYCD ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } inline void storeHalfFloats( const Vector3 & vec0, const Vector3 & vec1, vec_ushort8 * threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; storeXYZArray( vec0, xyz0 ); storeXYZArray( vec1, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } inline Vector3 & Vector3::operator =( const Vector3 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; return *this; } inline Vector3 & Vector3::setX( vec_float4 _x ) { mX = _x; return *this; } inline vec_float4 Vector3::getX( ) const { return mX; } inline Vector3 & Vector3::setY( vec_float4 _y ) { mY = _y; return *this; } inline vec_float4 Vector3::getY( ) const { return mY; } inline Vector3 & Vector3::setZ( vec_float4 _z ) { mZ = _z; return *this; } inline vec_float4 Vector3::getZ( ) const { return mZ; } inline Vector3 & Vector3::setElem( int idx, vec_float4 value ) { *(&mX + idx) = value; return *this; } inline vec_float4 Vector3::getElem( int idx ) const { return *(&mX + idx); } inline Vector3::vec_float4_t & Vector3::operator []( int idx ) { return *(&mX + idx); } inline vec_float4 Vector3::operator []( int idx ) const { return *(&mX + idx); } inline const Vector3 Vector3::operator +( const Vector3 & vec ) const { return Vector3( spu_add( mX, vec.mX ), spu_add( mY, vec.mY ), spu_add( mZ, vec.mZ ) ); } inline const Vector3 Vector3::operator -( const Vector3 & vec ) const { return Vector3( spu_sub( mX, vec.mX ), spu_sub( mY, vec.mY ), spu_sub( mZ, vec.mZ ) ); } inline const Point3 Vector3::operator +( const Point3 & pnt ) const { return Point3( spu_add( mX, pnt.getX() ), spu_add( mY, pnt.getY() ), spu_add( mZ, pnt.getZ() ) ); } inline const Vector3 Vector3::operator *( vec_float4 scalar ) const { return Vector3( spu_mul( mX, scalar ), spu_mul( mY, scalar ), spu_mul( mZ, scalar ) ); } inline Vector3 & Vector3::operator +=( const Vector3 & vec ) { *this = *this + vec; return *this; } inline Vector3 & Vector3::operator -=( const Vector3 & vec ) { *this = *this - vec; return *this; } inline Vector3 & Vector3::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Vector3 Vector3::operator /( vec_float4 scalar ) const { return Vector3( divf4( mX, scalar ), divf4( mY, scalar ), divf4( mZ, scalar ) ); } inline Vector3 & Vector3::operator /=( vec_float4 scalar ) { *this = *this / scalar; return *this; } inline const Vector3 Vector3::operator -( ) const { return Vector3( negatef4( mX ), negatef4( mY ), negatef4( mZ ) ); } inline const Vector3 operator *( vec_float4 scalar, const Vector3 & vec ) { return vec * scalar; } inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( spu_mul( vec0.getX(), vec1.getX() ), spu_mul( vec0.getY(), vec1.getY() ), spu_mul( vec0.getZ(), vec1.getZ() ) ); } inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( divf4( vec0.getX(), vec1.getX() ), divf4( vec0.getY(), vec1.getY() ), divf4( vec0.getZ(), vec1.getZ() ) ); } inline const Vector3 recipPerElem( const Vector3 & vec ) { return Vector3( recipf4( vec.getX() ), recipf4( vec.getY() ), recipf4( vec.getZ() ) ); } inline const Vector3 sqrtPerElem( const Vector3 & vec ) { return Vector3( sqrtf4( vec.getX() ), sqrtf4( vec.getY() ), sqrtf4( vec.getZ() ) ); } inline const Vector3 rsqrtPerElem( const Vector3 & vec ) { return Vector3( rsqrtf4( vec.getX() ), rsqrtf4( vec.getY() ), rsqrtf4( vec.getZ() ) ); } inline const Vector3 absPerElem( const Vector3 & vec ) { return Vector3( fabsf4( vec.getX() ), fabsf4( vec.getY() ), fabsf4( vec.getZ() ) ); } inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( copysignf4( vec0.getX(), vec1.getX() ), copysignf4( vec0.getY(), vec1.getY() ), copysignf4( vec0.getZ(), vec1.getZ() ) ); } inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( fmaxf4( vec0.getX(), vec1.getX() ), fmaxf4( vec0.getY(), vec1.getY() ), fmaxf4( vec0.getZ(), vec1.getZ() ) ); } inline vec_float4 maxElem( const Vector3 & vec ) { vec_float4 result; result = fmaxf4( vec.getX(), vec.getY() ); result = fmaxf4( vec.getZ(), result ); return result; } inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( fminf4( vec0.getX(), vec1.getX() ), fminf4( vec0.getY(), vec1.getY() ), fminf4( vec0.getZ(), vec1.getZ() ) ); } inline vec_float4 minElem( const Vector3 & vec ) { vec_float4 result; result = fminf4( vec.getX(), vec.getY() ); result = fminf4( vec.getZ(), result ); return result; } inline vec_float4 sum( const Vector3 & vec ) { vec_float4 result; result = spu_add( vec.getX(), vec.getY() ); result = spu_add( result, vec.getZ() ); return result; } inline vec_float4 dot( const Vector3 & vec0, const Vector3 & vec1 ) { vec_float4 result; result = spu_mul( vec0.getX(), vec1.getX() ); result = spu_add( result, spu_mul( vec0.getY(), vec1.getY() ) ); result = spu_add( result, spu_mul( vec0.getZ(), vec1.getZ() ) ); return result; } inline vec_float4 lengthSqr( const Vector3 & vec ) { vec_float4 result; result = spu_mul( vec.getX(), vec.getX() ); result = spu_add( result, spu_mul( vec.getY(), vec.getY() ) ); result = spu_add( result, spu_mul( vec.getZ(), vec.getZ() ) ); return result; } inline vec_float4 length( const Vector3 & vec ) { return sqrtf4( lengthSqr( vec ) ); } inline const Vector3 normalize( const Vector3 & vec ) { vec_float4 lenSqr, lenInv; lenSqr = lengthSqr( vec ); lenInv = rsqrtf4( lenSqr ); return Vector3( spu_mul( vec.getX(), lenInv ), spu_mul( vec.getY(), lenInv ), spu_mul( vec.getZ(), lenInv ) ); } inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ) { return Vector3( spu_sub( spu_mul( vec0.getY(), vec1.getZ() ), spu_mul( vec0.getZ(), vec1.getY() ) ), spu_sub( spu_mul( vec0.getZ(), vec1.getX() ), spu_mul( vec0.getX(), vec1.getZ() ) ), spu_sub( spu_mul( vec0.getX(), vec1.getY() ), spu_mul( vec0.getY(), vec1.getX() ) ) ); } inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, vec_uint4 select1 ) { return Vector3( spu_sel( vec0.getX(), vec1.getX(), select1 ), spu_sel( vec0.getY(), vec1.getY(), select1 ), spu_sel( vec0.getZ(), vec1.getZ(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Vector3 & vec ) { Aos::Vector3 vec0, vec1, vec2, vec3; vec.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } inline void print( const Vector3 & vec, const char * name ) { Aos::Vector3 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vec.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } #endif inline Vector4::Vector4( const Vector4 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; mW = vec.mW; } inline Vector4::Vector4( vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w ) { mX = _x; mY = _y; mZ = _z; mW = _w; } inline Vector4::Vector4( const Vector3 & xyz, vec_float4 _w ) { this->setXYZ( xyz ); this->setW( _w ); } inline Vector4::Vector4( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); mW = spu_splats(0.0f); } inline Vector4::Vector4( const Point3 & pnt ) { mX = pnt.getX(); mY = pnt.getY(); mZ = pnt.getZ(); mW = spu_splats(1.0f); } inline Vector4::Vector4( const Quat & quat ) { mX = quat.getX(); mY = quat.getY(); mZ = quat.getZ(); mW = quat.getW(); } inline Vector4::Vector4( vec_float4 scalar ) { mX = scalar; mY = scalar; mZ = scalar; mW = scalar; } inline Vector4::Vector4( Aos::Vector4 vec ) { vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_uchar16 shuffle_wwww = (vec_uchar16)spu_splats((int)0x0c0d0e0f); vec_float4 vec128 = vec.get128(); mX = spu_shuffle( vec128, vec128, shuffle_xxxx ); mY = spu_shuffle( vec128, vec128, shuffle_yyyy ); mZ = spu_shuffle( vec128, vec128, shuffle_zzzz ); mW = spu_shuffle( vec128, vec128, shuffle_wwww ); } inline Vector4::Vector4( Aos::Vector4 vec0, Aos::Vector4 vec1, Aos::Vector4 vec2, Aos::Vector4 vec3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( vec0.get128(), vec2.get128(), _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( vec1.get128(), vec3.get128(), _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( vec0.get128(), vec2.get128(), _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( vec1.get128(), vec3.get128(), _VECTORMATH_SHUF_ZCWD ); mX = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); mY = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); mZ = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); mW = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ); } inline const Vector4 Vector4::xAxis( ) { return Vector4( spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f) ); } inline const Vector4 Vector4::yAxis( ) { return Vector4( spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f), spu_splats(0.0f) ); } inline const Vector4 Vector4::zAxis( ) { return Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f), spu_splats(0.0f) ); } inline const Vector4 Vector4::wAxis( ) { return Vector4( spu_splats(0.0f), spu_splats(0.0f), spu_splats(0.0f), spu_splats(1.0f) ); } inline const Vector4 lerp( vec_float4 t, const Vector4 & vec0, const Vector4 & vec1 ) { return ( vec0 + ( ( vec1 - vec0 ) * t ) ); } inline const Vector4 slerp( vec_float4 t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) { vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle; vec_uint4 selectMask; cosAngle = dot( unitVec0, unitVec1 ); selectMask = (vec_uint4)spu_cmpgt( spu_splats(_VECTORMATH_SLERP_TOL), cosAngle ); angle = acosf4( cosAngle ); recipSinAngle = recipf4( sinf4( angle ) ); 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 ); scale1 = spu_sel( t, spu_mul( sinf4( spu_mul( t, angle ) ), recipSinAngle ), selectMask ); return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); } inline void Vector4::get4Aos( Aos::Vector4 & result0, Aos::Vector4 & result1, Aos::Vector4 & result2, Aos::Vector4 & result3 ) const { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mY, mW, _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( mY, mW, _VECTORMATH_SHUF_ZCWD ); result0 = Aos::Vector4( spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ) ); result1 = Aos::Vector4( spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ) ); result2 = Aos::Vector4( spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ) ); result3 = Aos::Vector4( spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_ZCWD ) ); } inline void storeHalfFloats( const Vector4 & vec, vec_ushort8 * twoQuads ) { Aos::Vector4 v0, v1, v2, v3; vec.get4Aos( v0, v1, v2, v3 ); twoQuads[0] = _vmath2VfToHalfFloats(v0.get128(), v1.get128()); twoQuads[1] = _vmath2VfToHalfFloats(v2.get128(), v3.get128()); } inline Vector4 & Vector4::operator =( const Vector4 & vec ) { mX = vec.mX; mY = vec.mY; mZ = vec.mZ; mW = vec.mW; return *this; } inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); return *this; } inline const Vector3 Vector4::getXYZ( ) const { return Vector3( mX, mY, mZ ); } inline Vector4 & Vector4::setX( vec_float4 _x ) { mX = _x; return *this; } inline vec_float4 Vector4::getX( ) const { return mX; } inline Vector4 & Vector4::setY( vec_float4 _y ) { mY = _y; return *this; } inline vec_float4 Vector4::getY( ) const { return mY; } inline Vector4 & Vector4::setZ( vec_float4 _z ) { mZ = _z; return *this; } inline vec_float4 Vector4::getZ( ) const { return mZ; } inline Vector4 & Vector4::setW( vec_float4 _w ) { mW = _w; return *this; } inline vec_float4 Vector4::getW( ) const { return mW; } inline Vector4 & Vector4::setElem( int idx, vec_float4 value ) { *(&mX + idx) = value; return *this; } inline vec_float4 Vector4::getElem( int idx ) const { return *(&mX + idx); } inline Vector4::vec_float4_t & Vector4::operator []( int idx ) { return *(&mX + idx); } inline vec_float4 Vector4::operator []( int idx ) const { return *(&mX + idx); } inline const Vector4 Vector4::operator +( const Vector4 & vec ) const { return Vector4( spu_add( mX, vec.mX ), spu_add( mY, vec.mY ), spu_add( mZ, vec.mZ ), spu_add( mW, vec.mW ) ); } inline const Vector4 Vector4::operator -( const Vector4 & vec ) const { return Vector4( spu_sub( mX, vec.mX ), spu_sub( mY, vec.mY ), spu_sub( mZ, vec.mZ ), spu_sub( mW, vec.mW ) ); } inline const Vector4 Vector4::operator *( vec_float4 scalar ) const { return Vector4( spu_mul( mX, scalar ), spu_mul( mY, scalar ), spu_mul( mZ, scalar ), spu_mul( mW, scalar ) ); } inline Vector4 & Vector4::operator +=( const Vector4 & vec ) { *this = *this + vec; return *this; } inline Vector4 & Vector4::operator -=( const Vector4 & vec ) { *this = *this - vec; return *this; } inline Vector4 & Vector4::operator *=( vec_float4 scalar ) { *this = *this * scalar; return *this; } inline const Vector4 Vector4::operator /( vec_float4 scalar ) const { return Vector4( divf4( mX, scalar ), divf4( mY, scalar ), divf4( mZ, scalar ), divf4( mW, scalar ) ); } inline Vector4 & Vector4::operator /=( vec_float4 scalar ) { *this = *this / scalar; return *this; } inline const Vector4 Vector4::operator -( ) const { return Vector4( negatef4( mX ), negatef4( mY ), negatef4( mZ ), negatef4( mW ) ); } inline const Vector4 operator *( vec_float4 scalar, const Vector4 & vec ) { return vec * scalar; } inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( spu_mul( vec0.getX(), vec1.getX() ), spu_mul( vec0.getY(), vec1.getY() ), spu_mul( vec0.getZ(), vec1.getZ() ), spu_mul( vec0.getW(), vec1.getW() ) ); } inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( divf4( vec0.getX(), vec1.getX() ), divf4( vec0.getY(), vec1.getY() ), divf4( vec0.getZ(), vec1.getZ() ), divf4( vec0.getW(), vec1.getW() ) ); } inline const Vector4 recipPerElem( const Vector4 & vec ) { return Vector4( recipf4( vec.getX() ), recipf4( vec.getY() ), recipf4( vec.getZ() ), recipf4( vec.getW() ) ); } inline const Vector4 sqrtPerElem( const Vector4 & vec ) { return Vector4( sqrtf4( vec.getX() ), sqrtf4( vec.getY() ), sqrtf4( vec.getZ() ), sqrtf4( vec.getW() ) ); } inline const Vector4 rsqrtPerElem( const Vector4 & vec ) { return Vector4( rsqrtf4( vec.getX() ), rsqrtf4( vec.getY() ), rsqrtf4( vec.getZ() ), rsqrtf4( vec.getW() ) ); } inline const Vector4 absPerElem( const Vector4 & vec ) { return Vector4( fabsf4( vec.getX() ), fabsf4( vec.getY() ), fabsf4( vec.getZ() ), fabsf4( vec.getW() ) ); } inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( copysignf4( vec0.getX(), vec1.getX() ), copysignf4( vec0.getY(), vec1.getY() ), copysignf4( vec0.getZ(), vec1.getZ() ), copysignf4( vec0.getW(), vec1.getW() ) ); } inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( fmaxf4( vec0.getX(), vec1.getX() ), fmaxf4( vec0.getY(), vec1.getY() ), fmaxf4( vec0.getZ(), vec1.getZ() ), fmaxf4( vec0.getW(), vec1.getW() ) ); } inline vec_float4 maxElem( const Vector4 & vec ) { vec_float4 result; result = fmaxf4( vec.getX(), vec.getY() ); result = fmaxf4( vec.getZ(), result ); result = fmaxf4( vec.getW(), result ); return result; } inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) { return Vector4( fminf4( vec0.getX(), vec1.getX() ), fminf4( vec0.getY(), vec1.getY() ), fminf4( vec0.getZ(), vec1.getZ() ), fminf4( vec0.getW(), vec1.getW() ) ); } inline vec_float4 minElem( const Vector4 & vec ) { vec_float4 result; result = fminf4( vec.getX(), vec.getY() ); result = fminf4( vec.getZ(), result ); result = fminf4( vec.getW(), result ); return result; } inline vec_float4 sum( const Vector4 & vec ) { vec_float4 result; result = spu_add( vec.getX(), vec.getY() ); result = spu_add( result, vec.getZ() ); result = spu_add( result, vec.getW() ); return result; } inline vec_float4 dot( const Vector4 & vec0, const Vector4 & vec1 ) { vec_float4 result; result = spu_mul( vec0.getX(), vec1.getX() ); result = spu_add( result, spu_mul( vec0.getY(), vec1.getY() ) ); result = spu_add( result, spu_mul( vec0.getZ(), vec1.getZ() ) ); result = spu_add( result, spu_mul( vec0.getW(), vec1.getW() ) ); return result; } inline vec_float4 lengthSqr( const Vector4 & vec ) { vec_float4 result; result = spu_mul( vec.getX(), vec.getX() ); result = spu_add( result, spu_mul( vec.getY(), vec.getY() ) ); result = spu_add( result, spu_mul( vec.getZ(), vec.getZ() ) ); result = spu_add( result, spu_mul( vec.getW(), vec.getW() ) ); return result; } inline vec_float4 length( const Vector4 & vec ) { return sqrtf4( lengthSqr( vec ) ); } inline const Vector4 normalize( const Vector4 & vec ) { vec_float4 lenSqr, lenInv; lenSqr = lengthSqr( vec ); lenInv = rsqrtf4( lenSqr ); return Vector4( spu_mul( vec.getX(), lenInv ), spu_mul( vec.getY(), lenInv ), spu_mul( vec.getZ(), lenInv ), spu_mul( vec.getW(), lenInv ) ); } inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, vec_uint4 select1 ) { return Vector4( spu_sel( vec0.getX(), vec1.getX(), select1 ), spu_sel( vec0.getY(), vec1.getY(), select1 ), spu_sel( vec0.getZ(), vec1.getZ(), select1 ), spu_sel( vec0.getW(), vec1.getW(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Vector4 & vec ) { Aos::Vector4 vec0, vec1, vec2, vec3; vec.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } inline void print( const Vector4 & vec, const char * name ) { Aos::Vector4 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); vec.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } #endif inline Point3::Point3( const Point3 & pnt ) { mX = pnt.mX; mY = pnt.mY; mZ = pnt.mZ; } inline Point3::Point3( vec_float4 _x, vec_float4 _y, vec_float4 _z ) { mX = _x; mY = _y; mZ = _z; } inline Point3::Point3( const Vector3 & vec ) { mX = vec.getX(); mY = vec.getY(); mZ = vec.getZ(); } inline Point3::Point3( vec_float4 scalar ) { mX = scalar; mY = scalar; mZ = scalar; } inline Point3::Point3( Aos::Point3 pnt ) { vec_uchar16 shuffle_xxxx = (vec_uchar16)spu_splats((int)0x00010203); vec_uchar16 shuffle_yyyy = (vec_uchar16)spu_splats((int)0x04050607); vec_uchar16 shuffle_zzzz = (vec_uchar16)spu_splats((int)0x08090a0b); vec_float4 vec128 = pnt.get128(); mX = spu_shuffle( vec128, vec128, shuffle_xxxx ); mY = spu_shuffle( vec128, vec128, shuffle_yyyy ); mZ = spu_shuffle( vec128, vec128, shuffle_zzzz ); } inline Point3::Point3( Aos::Point3 pnt0, Aos::Point3 pnt1, Aos::Point3 pnt2, Aos::Point3 pnt3 ) { vec_float4 tmp0, tmp1, tmp2, tmp3; tmp0 = spu_shuffle( pnt0.get128(), pnt2.get128(), _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( pnt1.get128(), pnt3.get128(), _VECTORMATH_SHUF_XAYB ); tmp2 = spu_shuffle( pnt0.get128(), pnt2.get128(), _VECTORMATH_SHUF_ZCWD ); tmp3 = spu_shuffle( pnt1.get128(), pnt3.get128(), _VECTORMATH_SHUF_ZCWD ); mX = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_XAYB ); mY = spu_shuffle( tmp0, tmp1, _VECTORMATH_SHUF_ZCWD ); mZ = spu_shuffle( tmp2, tmp3, _VECTORMATH_SHUF_XAYB ); } inline const Point3 lerp( vec_float4 t, const Point3 & pnt0, const Point3 & pnt1 ) { return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); } inline void Point3::get4Aos( Aos::Point3 & result0, Aos::Point3 & result1, Aos::Point3 & result2, Aos::Point3 & result3 ) const { vec_float4 tmp0, tmp1; tmp0 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_XAYB ); tmp1 = spu_shuffle( mX, mZ, _VECTORMATH_SHUF_ZCWD ); result0 = Aos::Point3( spu_shuffle( tmp0, mY, _VECTORMATH_SHUF_XAYB ) ); result1 = Aos::Point3( spu_shuffle( tmp0, mY, _VECTORMATH_SHUF_ZBW0 ) ); result2 = Aos::Point3( spu_shuffle( tmp1, mY, _VECTORMATH_SHUF_XCY0 ) ); result3 = Aos::Point3( spu_shuffle( tmp1, mY, _VECTORMATH_SHUF_ZDW0 ) ); } inline void loadXYZArray( Point3 & vec, const vec_float4 * threeQuads ) { vec_float4 xyxy, yzyz, zxzx, xyzx, yzxy, zxyz; xyzx = threeQuads[0]; yzxy = threeQuads[1]; zxyz = threeQuads[2]; xyxy = spu_shuffle( xyzx, yzxy, _VECTORMATH_SHUF_XYCD ); zxzx = spu_shuffle( zxyz, xyzx, _VECTORMATH_SHUF_XYCD ); yzyz = spu_shuffle( yzxy, zxyz, _VECTORMATH_SHUF_XYCD ); vec.setX( spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XDZB ) ); vec.setY( spu_shuffle( xyxy, yzyz, _VECTORMATH_SHUF_YAWC ) ); vec.setZ( spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_ZBXD ) ); } inline void storeXYZArray( const Point3 & vec, vec_float4 * threeQuads ) { vec_float4 xyzx, yzxy, zxyz, xyxy, zxzx, yzyz; xyxy = spu_shuffle( vec.getX(), vec.getY(), _VECTORMATH_SHUF_XAZC ); zxzx = spu_shuffle( vec.getZ(), vec.getX(), _VECTORMATH_SHUF_ZDXB ); yzyz = spu_shuffle( vec.getY(), vec.getZ(), _VECTORMATH_SHUF_YBWD ); xyzx = spu_shuffle( xyxy, zxzx, _VECTORMATH_SHUF_XYCD ); yzxy = spu_shuffle( yzyz, xyxy, _VECTORMATH_SHUF_XYCD ); zxyz = spu_shuffle( zxzx, yzyz, _VECTORMATH_SHUF_XYCD ); threeQuads[0] = xyzx; threeQuads[1] = yzxy; threeQuads[2] = zxyz; } inline void storeHalfFloats( const Point3 & pnt0, const Point3 & pnt1, vec_ushort8 * threeQuads ) { vec_float4 xyz0[3]; vec_float4 xyz1[3]; storeXYZArray( pnt0, xyz0 ); storeXYZArray( pnt1, xyz1 ); threeQuads[0] = _vmath2VfToHalfFloats(xyz0[0], xyz0[1]); threeQuads[1] = _vmath2VfToHalfFloats(xyz0[2], xyz1[0]); threeQuads[2] = _vmath2VfToHalfFloats(xyz1[1], xyz1[2]); } inline Point3 & Point3::operator =( const Point3 & pnt ) { mX = pnt.mX; mY = pnt.mY; mZ = pnt.mZ; return *this; } inline Point3 & Point3::setX( vec_float4 _x ) { mX = _x; return *this; } inline vec_float4 Point3::getX( ) const { return mX; } inline Point3 & Point3::setY( vec_float4 _y ) { mY = _y; return *this; } inline vec_float4 Point3::getY( ) const { return mY; } inline Point3 & Point3::setZ( vec_float4 _z ) { mZ = _z; return *this; } inline vec_float4 Point3::getZ( ) const { return mZ; } inline Point3 & Point3::setElem( int idx, vec_float4 value ) { *(&mX + idx) = value; return *this; } inline vec_float4 Point3::getElem( int idx ) const { return *(&mX + idx); } inline Point3::vec_float4_t & Point3::operator []( int idx ) { return *(&mX + idx); } inline vec_float4 Point3::operator []( int idx ) const { return *(&mX + idx); } inline const Vector3 Point3::operator -( const Point3 & pnt ) const { return Vector3( spu_sub( mX, pnt.mX ), spu_sub( mY, pnt.mY ), spu_sub( mZ, pnt.mZ ) ); } inline const Point3 Point3::operator +( const Vector3 & vec ) const { return Point3( spu_add( mX, vec.getX() ), spu_add( mY, vec.getY() ), spu_add( mZ, vec.getZ() ) ); } inline const Point3 Point3::operator -( const Vector3 & vec ) const { return Point3( spu_sub( mX, vec.getX() ), spu_sub( mY, vec.getY() ), spu_sub( mZ, vec.getZ() ) ); } inline Point3 & Point3::operator +=( const Vector3 & vec ) { *this = *this + vec; return *this; } inline Point3 & Point3::operator -=( const Vector3 & vec ) { *this = *this - vec; return *this; } inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( spu_mul( pnt0.getX(), pnt1.getX() ), spu_mul( pnt0.getY(), pnt1.getY() ), spu_mul( pnt0.getZ(), pnt1.getZ() ) ); } inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( divf4( pnt0.getX(), pnt1.getX() ), divf4( pnt0.getY(), pnt1.getY() ), divf4( pnt0.getZ(), pnt1.getZ() ) ); } inline const Point3 recipPerElem( const Point3 & pnt ) { return Point3( recipf4( pnt.getX() ), recipf4( pnt.getY() ), recipf4( pnt.getZ() ) ); } inline const Point3 sqrtPerElem( const Point3 & pnt ) { return Point3( sqrtf4( pnt.getX() ), sqrtf4( pnt.getY() ), sqrtf4( pnt.getZ() ) ); } inline const Point3 rsqrtPerElem( const Point3 & pnt ) { return Point3( rsqrtf4( pnt.getX() ), rsqrtf4( pnt.getY() ), rsqrtf4( pnt.getZ() ) ); } inline const Point3 absPerElem( const Point3 & pnt ) { return Point3( fabsf4( pnt.getX() ), fabsf4( pnt.getY() ), fabsf4( pnt.getZ() ) ); } inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( copysignf4( pnt0.getX(), pnt1.getX() ), copysignf4( pnt0.getY(), pnt1.getY() ), copysignf4( pnt0.getZ(), pnt1.getZ() ) ); } inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( fmaxf4( pnt0.getX(), pnt1.getX() ), fmaxf4( pnt0.getY(), pnt1.getY() ), fmaxf4( pnt0.getZ(), pnt1.getZ() ) ); } inline vec_float4 maxElem( const Point3 & pnt ) { vec_float4 result; result = fmaxf4( pnt.getX(), pnt.getY() ); result = fmaxf4( pnt.getZ(), result ); return result; } inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) { return Point3( fminf4( pnt0.getX(), pnt1.getX() ), fminf4( pnt0.getY(), pnt1.getY() ), fminf4( pnt0.getZ(), pnt1.getZ() ) ); } inline vec_float4 minElem( const Point3 & pnt ) { vec_float4 result; result = fminf4( pnt.getX(), pnt.getY() ); result = fminf4( pnt.getZ(), result ); return result; } inline vec_float4 sum( const Point3 & pnt ) { vec_float4 result; result = spu_add( pnt.getX(), pnt.getY() ); result = spu_add( result, pnt.getZ() ); return result; } inline const Point3 scale( const Point3 & pnt, vec_float4 scaleVal ) { return mulPerElem( pnt, Point3( scaleVal ) ); } inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) { return mulPerElem( pnt, Point3( scaleVec ) ); } inline vec_float4 projection( const Point3 & pnt, const Vector3 & unitVec ) { vec_float4 result; result = spu_mul( pnt.getX(), unitVec.getX() ); result = spu_add( result, spu_mul( pnt.getY(), unitVec.getY() ) ); result = spu_add( result, spu_mul( pnt.getZ(), unitVec.getZ() ) ); return result; } inline vec_float4 distSqrFromOrigin( const Point3 & pnt ) { return lengthSqr( Vector3( pnt ) ); } inline vec_float4 distFromOrigin( const Point3 & pnt ) { return length( Vector3( pnt ) ); } inline vec_float4 distSqr( const Point3 & pnt0, const Point3 & pnt1 ) { return lengthSqr( ( pnt1 - pnt0 ) ); } inline vec_float4 dist( const Point3 & pnt0, const Point3 & pnt1 ) { return length( ( pnt1 - pnt0 ) ); } inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, vec_uint4 select1 ) { return Point3( spu_sel( pnt0.getX(), pnt1.getX(), select1 ), spu_sel( pnt0.getY(), pnt1.getY(), select1 ), spu_sel( pnt0.getZ(), pnt1.getZ(), select1 ) ); } #ifdef _VECTORMATH_DEBUG inline void print( const Point3 & pnt ) { Aos::Point3 vec0, vec1, vec2, vec3; pnt.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } inline void print( const Point3 & pnt, const char * name ) { Aos::Point3 vec0, vec1, vec2, vec3; printf( "%s:\n", name ); pnt.get4Aos( vec0, vec1, vec2, vec3 ); printf("slot 0:\n"); print( vec0 ); printf("slot 1:\n"); print( vec1 ); printf("slot 2:\n"); print( vec2 ); printf("slot 3:\n"); print( vec3 ); } #endif } // namespace Soa } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/spu/cpp/vecidx_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_VECIDX_AOS_H #define _VECTORMATH_VECIDX_AOS_H #include namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // VecIdx // Used in setting elements of Vector3, Vector4, Point3, or Quat with the // subscripting operator. // class VecIdx { private: typedef vec_float4 vec_float4_t; vec_float4_t &ref __attribute__ ((aligned(16))); int i __attribute__ ((aligned(16))); public: inline VecIdx( vec_float4& vec, int idx ): ref(vec) { i = idx; } inline operator float() const; inline float operator =( float scalar ); inline float operator =( const VecIdx& scalar ); inline float operator *=( float scalar ); inline float operator /=( float scalar ); inline float operator +=( float scalar ); inline float operator -=( float scalar ); }; } // namespace Aos } // namespace Vectormath #endif ================================================ FILE: samples/vectormath/spu/cpp/vectormath_aos.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_AOS_CPP_SPU_H #define _VECTORMATH_AOS_CPP_SPU_H #include #include #include "floatInVec.h" #include "boolInVec.h" #include "vecidx_aos.h" #include #ifdef _VECTORMATH_DEBUG #endif namespace Vectormath { namespace Aos { //----------------------------------------------------------------------------- // Forward Declarations // class Vector3; class Vector4; class Point3; class Quat; class Matrix3; class Matrix4; class Transform3; // A 3-D vector in array-of-structures format // class Vector3 { vec_float4 mVec128; public: // Default constructor; does no initialization // inline Vector3( ) { }; // Construct a 3-D vector from x, y, and z elements // inline Vector3( float x, float y, float z ); // Copy elements from a 3-D point into a 3-D vector // explicit inline Vector3( Point3 pnt ); // Set all elements of a 3-D vector to the same scalar value // explicit inline Vector3( float scalar ); // Set vector float data in a 3-D vector // explicit inline Vector3( vec_float4 vf4 ); // Get vector float data from a 3-D vector // inline vec_float4 get128( ) const; // Assign one 3-D vector to another // inline Vector3 & operator =( Vector3 vec ); // Set the x element of a 3-D vector // inline Vector3 & setX( float x ); // Set the y element of a 3-D vector // inline Vector3 & setY( float y ); // Set the z element of a 3-D vector // inline Vector3 & setZ( float z ); // Get the x element of a 3-D vector // inline float getX( ) const; // Get the y element of a 3-D vector // inline float getY( ) const; // Get the z element of a 3-D vector // inline float getZ( ) const; // Set an x, y, or z element of a 3-D vector by index // inline Vector3 & setElem( int idx, float value ); // Get an x, y, or z element of a 3-D vector by index // inline float getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline float operator []( int idx ) const; // Add two 3-D vectors // inline const Vector3 operator +( Vector3 vec ) const; // Subtract a 3-D vector from another 3-D vector // inline const Vector3 operator -( Vector3 vec ) const; // Add a 3-D vector to a 3-D point // inline const Point3 operator +( Point3 pnt ) const; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( float scalar ) const; // Divide a 3-D vector by a scalar // inline const Vector3 operator /( float scalar ) const; // Perform compound assignment and addition with a 3-D vector // inline Vector3 & operator +=( Vector3 vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Vector3 & operator -=( Vector3 vec ); // Perform compound assignment and multiplication by a scalar // inline Vector3 & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Vector3 & operator /=( float scalar ); // Negate all elements of a 3-D vector // inline const Vector3 operator -( ) const; // Construct x axis // static inline const Vector3 xAxis( ); // Construct y axis // static inline const Vector3 yAxis( ); // Construct z axis // static inline const Vector3 zAxis( ); }; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( float scalar, Vector3 vec ); // Multiply two 3-D vectors per element // inline const Vector3 mulPerElem( Vector3 vec0, Vector3 vec1 ); // Divide two 3-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector3 divPerElem( Vector3 vec0, Vector3 vec1 ); // Compute the reciprocal of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector3 recipPerElem( Vector3 vec ); // Compute the square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector3 sqrtPerElem( Vector3 vec ); // Compute the reciprocal square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector3 rsqrtPerElem( Vector3 vec ); // Compute the absolute value of a 3-D vector per element // inline const Vector3 absPerElem( Vector3 vec ); // Copy sign from one 3-D vector to another, per element // inline const Vector3 copySignPerElem( Vector3 vec0, Vector3 vec1 ); // Maximum of two 3-D vectors per element // inline const Vector3 maxPerElem( Vector3 vec0, Vector3 vec1 ); // Minimum of two 3-D vectors per element // inline const Vector3 minPerElem( Vector3 vec0, Vector3 vec1 ); // Maximum element of a 3-D vector // inline float maxElem( Vector3 vec ); // Minimum element of a 3-D vector // inline float minElem( Vector3 vec ); // Compute the sum of all elements of a 3-D vector // inline float sum( Vector3 vec ); // Compute the dot product of two 3-D vectors // inline float dot( Vector3 vec0, Vector3 vec1 ); // Compute the square of the length of a 3-D vector // inline float lengthSqr( Vector3 vec ); // Compute the length of a 3-D vector // inline float length( Vector3 vec ); // Normalize a 3-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector3 normalize( Vector3 vec ); // Compute cross product of two 3-D vectors // inline const Vector3 cross( Vector3 vec0, Vector3 vec1 ); // Outer product of two 3-D vectors // inline const Matrix3 outer( Vector3 vec0, Vector3 vec1 ); // Pre-multiply a row vector by a 3x3 matrix // NOTE: // Slower than column post-multiply. // inline const Vector3 rowMul( Vector3 vec, const Matrix3 & mat ); // Cross-product matrix of a 3-D vector // inline const Matrix3 crossMatrix( Vector3 vec ); // Create cross-product matrix and multiply // NOTE: // Faster than separately creating a cross-product matrix and multiplying. // inline const Matrix3 crossMatrixMul( Vector3 vec, const Matrix3 & mat ); // Linear interpolation between two 3-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector3 lerp( float t, Vector3 vec0, Vector3 vec1 ); // Spherical linear interpolation between two 3-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector3 slerp( float t, Vector3 unitVec0, Vector3 unitVec1 ); // Conditionally select between two 3-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector3 select( Vector3 vec0, Vector3 vec1, bool select1 ); // Store x, y, and z elements of a 3-D vector in the first three words of a quadword. // The value of the fourth word (the word with the highest address) remains unchanged // inline void storeXYZ( Vector3 vec, vec_float4 * quad ); // Load four three-float 3-D vectors, stored in three quadwords // inline void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const vec_float4 * threeQuads ); // Store four 3-D vectors in three quadwords // inline void storeXYZArray( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, vec_float4 * threeQuads ); // Store eight 3-D vectors as half-floats // inline void storeHalfFloats( Vector3 vec0, Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4, Vector3 vec5, Vector3 vec6, Vector3 vec7, vec_ushort8 * threeQuads ); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Vector3 vec ); // Print a 3-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Vector3 vec, const char * name ); #endif // A 4-D vector in array-of-structures format // class Vector4 { vec_float4 mVec128; public: // Default constructor; does no initialization // inline Vector4( ) { }; // Construct a 4-D vector from x, y, z, and w elements // inline Vector4( float x, float y, float z, float w ); // Construct a 4-D vector from a 3-D vector and a scalar // inline Vector4( Vector3 xyz, float w ); // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 // explicit inline Vector4( Vector3 vec ); // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 // explicit inline Vector4( Point3 pnt ); // Copy elements from a quaternion into a 4-D vector // explicit inline Vector4( Quat quat ); // Set all elements of a 4-D vector to the same scalar value // explicit inline Vector4( float scalar ); // Set vector float data in a 4-D vector // explicit inline Vector4( vec_float4 vf4 ); // Get vector float data from a 4-D vector // inline vec_float4 get128( ) const; // Assign one 4-D vector to another // inline Vector4 & operator =( Vector4 vec ); // Set the x, y, and z elements of a 4-D vector // NOTE: // This function does not change the w element. // inline Vector4 & setXYZ( Vector3 vec ); // Get the x, y, and z elements of a 4-D vector // inline const Vector3 getXYZ( ) const; // Set the x element of a 4-D vector // inline Vector4 & setX( float x ); // Set the y element of a 4-D vector // inline Vector4 & setY( float y ); // Set the z element of a 4-D vector // inline Vector4 & setZ( float z ); // Set the w element of a 4-D vector // inline Vector4 & setW( float w ); // Get the x element of a 4-D vector // inline float getX( ) const; // Get the y element of a 4-D vector // inline float getY( ) const; // Get the z element of a 4-D vector // inline float getZ( ) const; // Get the w element of a 4-D vector // inline float getW( ) const; // Set an x, y, z, or w element of a 4-D vector by index // inline Vector4 & setElem( int idx, float value ); // Get an x, y, z, or w element of a 4-D vector by index // inline float getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline float operator []( int idx ) const; // Add two 4-D vectors // inline const Vector4 operator +( Vector4 vec ) const; // Subtract a 4-D vector from another 4-D vector // inline const Vector4 operator -( Vector4 vec ) const; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( float scalar ) const; // Divide a 4-D vector by a scalar // inline const Vector4 operator /( float scalar ) const; // Perform compound assignment and addition with a 4-D vector // inline Vector4 & operator +=( Vector4 vec ); // Perform compound assignment and subtraction by a 4-D vector // inline Vector4 & operator -=( Vector4 vec ); // Perform compound assignment and multiplication by a scalar // inline Vector4 & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Vector4 & operator /=( float scalar ); // Negate all elements of a 4-D vector // inline const Vector4 operator -( ) const; // Construct x axis // static inline const Vector4 xAxis( ); // Construct y axis // static inline const Vector4 yAxis( ); // Construct z axis // static inline const Vector4 zAxis( ); // Construct w axis // static inline const Vector4 wAxis( ); }; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( float scalar, Vector4 vec ); // Multiply two 4-D vectors per element // inline const Vector4 mulPerElem( Vector4 vec0, Vector4 vec1 ); // Divide two 4-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector4 divPerElem( Vector4 vec0, Vector4 vec1 ); // Compute the reciprocal of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector4 recipPerElem( Vector4 vec ); // Compute the square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector4 sqrtPerElem( Vector4 vec ); // Compute the reciprocal square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector4 rsqrtPerElem( Vector4 vec ); // Compute the absolute value of a 4-D vector per element // inline const Vector4 absPerElem( Vector4 vec ); // Copy sign from one 4-D vector to another, per element // inline const Vector4 copySignPerElem( Vector4 vec0, Vector4 vec1 ); // Maximum of two 4-D vectors per element // inline const Vector4 maxPerElem( Vector4 vec0, Vector4 vec1 ); // Minimum of two 4-D vectors per element // inline const Vector4 minPerElem( Vector4 vec0, Vector4 vec1 ); // Maximum element of a 4-D vector // inline float maxElem( Vector4 vec ); // Minimum element of a 4-D vector // inline float minElem( Vector4 vec ); // Compute the sum of all elements of a 4-D vector // inline float sum( Vector4 vec ); // Compute the dot product of two 4-D vectors // inline float dot( Vector4 vec0, Vector4 vec1 ); // Compute the square of the length of a 4-D vector // inline float lengthSqr( Vector4 vec ); // Compute the length of a 4-D vector // inline float length( Vector4 vec ); // Normalize a 4-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector4 normalize( Vector4 vec ); // Outer product of two 4-D vectors // inline const Matrix4 outer( Vector4 vec0, Vector4 vec1 ); // Linear interpolation between two 4-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector4 lerp( float t, Vector4 vec0, Vector4 vec1 ); // Spherical linear interpolation between two 4-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector4 slerp( float t, Vector4 unitVec0, Vector4 unitVec1 ); // Conditionally select between two 4-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector4 select( Vector4 vec0, Vector4 vec1, bool select1 ); // Store four 4-D vectors as half-floats // inline void storeHalfFloats( Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3, vec_ushort8 * twoQuads ); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Vector4 vec ); // Print a 4-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Vector4 vec, const char * name ); #endif // A 3-D point in array-of-structures format // class Point3 { vec_float4 mVec128; public: // Default constructor; does no initialization // inline Point3( ) { }; // Construct a 3-D point from x, y, and z elements // inline Point3( float x, float y, float z ); // Copy elements from a 3-D vector into a 3-D point // explicit inline Point3( Vector3 vec ); // Set all elements of a 3-D point to the same scalar value // explicit inline Point3( float scalar ); // Set vector float data in a 3-D point // explicit inline Point3( vec_float4 vf4 ); // Get vector float data from a 3-D point // inline vec_float4 get128( ) const; // Assign one 3-D point to another // inline Point3 & operator =( Point3 pnt ); // Set the x element of a 3-D point // inline Point3 & setX( float x ); // Set the y element of a 3-D point // inline Point3 & setY( float y ); // Set the z element of a 3-D point // inline Point3 & setZ( float z ); // Get the x element of a 3-D point // inline float getX( ) const; // Get the y element of a 3-D point // inline float getY( ) const; // Get the z element of a 3-D point // inline float getZ( ) const; // Set an x, y, or z element of a 3-D point by index // inline Point3 & setElem( int idx, float value ); // Get an x, y, or z element of a 3-D point by index // inline float getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline float operator []( int idx ) const; // Subtract a 3-D point from another 3-D point // inline const Vector3 operator -( Point3 pnt ) const; // Add a 3-D point to a 3-D vector // inline const Point3 operator +( Vector3 vec ) const; // Subtract a 3-D vector from a 3-D point // inline const Point3 operator -( Vector3 vec ) const; // Perform compound assignment and addition with a 3-D vector // inline Point3 & operator +=( Vector3 vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Point3 & operator -=( Vector3 vec ); }; // Multiply two 3-D points per element // inline const Point3 mulPerElem( Point3 pnt0, Point3 pnt1 ); // Divide two 3-D points per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Point3 divPerElem( Point3 pnt0, Point3 pnt1 ); // Compute the reciprocal of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Point3 recipPerElem( Point3 pnt ); // Compute the square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Point3 sqrtPerElem( Point3 pnt ); // Compute the reciprocal square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Point3 rsqrtPerElem( Point3 pnt ); // Compute the absolute value of a 3-D point per element // inline const Point3 absPerElem( Point3 pnt ); // Copy sign from one 3-D point to another, per element // inline const Point3 copySignPerElem( Point3 pnt0, Point3 pnt1 ); // Maximum of two 3-D points per element // inline const Point3 maxPerElem( Point3 pnt0, Point3 pnt1 ); // Minimum of two 3-D points per element // inline const Point3 minPerElem( Point3 pnt0, Point3 pnt1 ); // Maximum element of a 3-D point // inline float maxElem( Point3 pnt ); // Minimum element of a 3-D point // inline float minElem( Point3 pnt ); // Compute the sum of all elements of a 3-D point // inline float sum( Point3 pnt ); // Apply uniform scale to a 3-D point // inline const Point3 scale( Point3 pnt, float scaleVal ); // Apply non-uniform scale to a 3-D point // inline const Point3 scale( Point3 pnt, Vector3 scaleVec ); // Scalar projection of a 3-D point on a unit-length 3-D vector // inline float projection( Point3 pnt, Vector3 unitVec ); // Compute the square of the distance of a 3-D point from the coordinate-system origin // inline float distSqrFromOrigin( Point3 pnt ); // Compute the distance of a 3-D point from the coordinate-system origin // inline float distFromOrigin( Point3 pnt ); // Compute the square of the distance between two 3-D points // inline float distSqr( Point3 pnt0, Point3 pnt1 ); // Compute the distance between two 3-D points // inline float dist( Point3 pnt0, Point3 pnt1 ); // Linear interpolation between two 3-D points // NOTE: // Does not clamp t between 0 and 1. // inline const Point3 lerp( float t, Point3 pnt0, Point3 pnt1 ); // Conditionally select between two 3-D points // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Point3 select( Point3 pnt0, Point3 pnt1, bool select1 ); // Store x, y, and z elements of a 3-D point in the first three words of a quadword. // The value of the fourth word (the word with the highest address) remains unchanged // inline void storeXYZ( Point3 pnt, vec_float4 * quad ); // Load four three-float 3-D points, stored in three quadwords // inline void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const vec_float4 * threeQuads ); // Store four 3-D points in three quadwords // inline void storeXYZArray( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, vec_float4 * threeQuads ); // Store eight 3-D points as half-floats // inline void storeHalfFloats( Point3 pnt0, Point3 pnt1, Point3 pnt2, Point3 pnt3, Point3 pnt4, Point3 pnt5, Point3 pnt6, Point3 pnt7, vec_ushort8 * threeQuads ); #ifdef _VECTORMATH_DEBUG // Print a 3-D point // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Point3 pnt ); // Print a 3-D point and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Point3 pnt, const char * name ); #endif // A quaternion in array-of-structures format // class Quat { vec_float4 mVec128; public: // Default constructor; does no initialization // inline Quat( ) { }; // Construct a quaternion from x, y, z, and w elements // inline Quat( float x, float y, float z, float w ); // Construct a quaternion from a 3-D vector and a scalar // inline Quat( Vector3 xyz, float w ); // Copy elements from a 4-D vector into a quaternion // explicit inline Quat( Vector4 vec ); // Convert a rotation matrix to a unit-length quaternion // explicit inline Quat( const Matrix3 & rotMat ); // Set all elements of a quaternion to the same scalar value // explicit inline Quat( float scalar ); // Set vector float data in a quaternion // explicit inline Quat( vec_float4 vf4 ); // Get vector float data from a quaternion // inline vec_float4 get128( ) const; // Assign one quaternion to another // inline Quat & operator =( Quat quat ); // Set the x, y, and z elements of a quaternion // NOTE: // This function does not change the w element. // inline Quat & setXYZ( Vector3 vec ); // Get the x, y, and z elements of a quaternion // inline const Vector3 getXYZ( ) const; // Set the x element of a quaternion // inline Quat & setX( float x ); // Set the y element of a quaternion // inline Quat & setY( float y ); // Set the z element of a quaternion // inline Quat & setZ( float z ); // Set the w element of a quaternion // inline Quat & setW( float w ); // Get the x element of a quaternion // inline float getX( ) const; // Get the y element of a quaternion // inline float getY( ) const; // Get the z element of a quaternion // inline float getZ( ) const; // Get the w element of a quaternion // inline float getW( ) const; // Set an x, y, z, or w element of a quaternion by index // inline Quat & setElem( int idx, float value ); // Get an x, y, z, or w element of a quaternion by index // inline float getElem( int idx ) const; // Subscripting operator to set or get an element // inline VecIdx operator []( int idx ); // Subscripting operator to get an element // inline float operator []( int idx ) const; // Add two quaternions // inline const Quat operator +( Quat quat ) const; // Subtract a quaternion from another quaternion // inline const Quat operator -( Quat quat ) const; // Multiply two quaternions // inline const Quat operator *( Quat quat ) const; // Multiply a quaternion by a scalar // inline const Quat operator *( float scalar ) const; // Divide a quaternion by a scalar // inline const Quat operator /( float scalar ) const; // Perform compound assignment and addition with a quaternion // inline Quat & operator +=( Quat quat ); // Perform compound assignment and subtraction by a quaternion // inline Quat & operator -=( Quat quat ); // Perform compound assignment and multiplication by a quaternion // inline Quat & operator *=( Quat quat ); // Perform compound assignment and multiplication by a scalar // inline Quat & operator *=( float scalar ); // Perform compound assignment and division by a scalar // inline Quat & operator /=( float scalar ); // Negate all elements of a quaternion // inline const Quat operator -( ) const; // Construct an identity quaternion // static inline const Quat identity( ); // Construct a quaternion to rotate between two unit-length 3-D vectors // NOTE: // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. // static inline const Quat rotation( Vector3 unitVec0, Vector3 unitVec1 ); // Construct a quaternion to rotate around a unit-length 3-D vector // static inline const Quat rotation( float radians, Vector3 unitVec ); // Construct a quaternion to rotate around the x axis // static inline const Quat rotationX( float radians ); // Construct a quaternion to rotate around the y axis // static inline const Quat rotationY( float radians ); // Construct a quaternion to rotate around the z axis // static inline const Quat rotationZ( float radians ); }; // Multiply a quaternion by a scalar // inline const Quat operator *( float scalar, Quat quat ); // Compute the conjugate of a quaternion // inline const Quat conj( Quat quat ); // Use a unit-length quaternion to rotate a 3-D vector // inline const Vector3 rotate( Quat unitQuat, Vector3 vec ); // Compute the dot product of two quaternions // inline float dot( Quat quat0, Quat quat1 ); // Compute the norm of a quaternion // inline float norm( Quat quat ); // Compute the length of a quaternion // inline float length( Quat quat ); // Normalize a quaternion // NOTE: // The result is unpredictable when all elements of quat are at or near zero. // inline const Quat normalize( Quat quat ); // Linear interpolation between two quaternions // NOTE: // Does not clamp t between 0 and 1. // inline const Quat lerp( float t, Quat quat0, Quat quat1 ); // Spherical linear interpolation between two quaternions // NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. // inline const Quat slerp( float t, Quat unitQuat0, Quat unitQuat1 ); // Spherical quadrangle interpolation // inline const Quat squad( float t, Quat unitQuat0, Quat unitQuat1, Quat unitQuat2, Quat unitQuat3 ); // Conditionally select between two quaternions // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Quat select( Quat quat0, Quat quat1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a quaternion // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Quat quat ); // Print a quaternion and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( Quat quat, const char * name ); #endif // A 3x3 matrix in array-of-structures format // class Matrix3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; public: // Default constructor; does no initialization // inline Matrix3( ) { }; // Copy a 3x3 matrix // inline Matrix3( const Matrix3 & mat ); // Construct a 3x3 matrix containing the specified columns // inline Matrix3( Vector3 col0, Vector3 col1, Vector3 col2 ); // Construct a 3x3 rotation matrix from a unit-length quaternion // explicit inline Matrix3( Quat unitQuat ); // Set all elements of a 3x3 matrix to the same scalar value // explicit inline Matrix3( float scalar ); // Assign one 3x3 matrix to another // inline Matrix3 & operator =( const Matrix3 & mat ); // Set column 0 of a 3x3 matrix // inline Matrix3 & setCol0( Vector3 col0 ); // Set column 1 of a 3x3 matrix // inline Matrix3 & setCol1( Vector3 col1 ); // Set column 2 of a 3x3 matrix // inline Matrix3 & setCol2( Vector3 col2 ); // Get column 0 of a 3x3 matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x3 matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x3 matrix // inline const Vector3 getCol2( ) const; // Set the column of a 3x3 matrix referred to by the specified index // inline Matrix3 & setCol( int col, Vector3 vec ); // Set the row of a 3x3 matrix referred to by the specified index // inline Matrix3 & setRow( int row, Vector3 vec ); // Get the column of a 3x3 matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x3 matrix referred to by the specified index // inline const Vector3 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x3 matrix referred to by column and row indices // inline Matrix3 & setElem( int col, int row, float val ); // Get the element of a 3x3 matrix referred to by column and row indices // inline float getElem( int col, int row ) const; // Add two 3x3 matrices // inline const Matrix3 operator +( const Matrix3 & mat ) const; // Subtract a 3x3 matrix from another 3x3 matrix // inline const Matrix3 operator -( const Matrix3 & mat ) const; // Negate all elements of a 3x3 matrix // inline const Matrix3 operator -( ) const; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( float scalar ) const; // Multiply a 3x3 matrix by a 3-D vector // inline const Vector3 operator *( Vector3 vec ) const; // Multiply two 3x3 matrices // inline const Matrix3 operator *( const Matrix3 & mat ) const; // Perform compound assignment and addition with a 3x3 matrix // inline Matrix3 & operator +=( const Matrix3 & mat ); // Perform compound assignment and subtraction by a 3x3 matrix // inline Matrix3 & operator -=( const Matrix3 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix3 & operator *=( float scalar ); // Perform compound assignment and multiplication by a 3x3 matrix // inline Matrix3 & operator *=( const Matrix3 & mat ); // Construct an identity 3x3 matrix // static inline const Matrix3 identity( ); // Construct a 3x3 matrix to rotate around the x axis // static inline const Matrix3 rotationX( float radians ); // Construct a 3x3 matrix to rotate around the y axis // static inline const Matrix3 rotationY( float radians ); // Construct a 3x3 matrix to rotate around the z axis // static inline const Matrix3 rotationZ( float radians ); // Construct a 3x3 matrix to rotate around the x, y, and z axes // static inline const Matrix3 rotationZYX( Vector3 radiansXYZ ); // Construct a 3x3 matrix to rotate around a unit-length 3-D vector // static inline const Matrix3 rotation( float radians, Vector3 unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix3 rotation( Quat unitQuat ); // Construct a 3x3 matrix to perform scaling // static inline const Matrix3 scale( Vector3 scaleVec ); }; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); // Append (post-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 appendScale( const Matrix3 & mat, Vector3 scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 prependScale( Vector3 scaleVec, const Matrix3 & mat ); // Multiply two 3x3 matrices per element // inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); // Compute the absolute value of a 3x3 matrix per element // inline const Matrix3 absPerElem( const Matrix3 & mat ); // Transpose of a 3x3 matrix // inline const Matrix3 transpose( const Matrix3 & mat ); // Compute the inverse of a 3x3 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix3 inverse( const Matrix3 & mat ); // Determinant of a 3x3 matrix // inline float determinant( const Matrix3 & mat ); // Conditionally select between two 3x3 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat ); // Print a 3x3 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat, const char * name ); #endif // A 4x4 matrix in array-of-structures format // class Matrix4 { Vector4 mCol0; Vector4 mCol1; Vector4 mCol2; Vector4 mCol3; public: // Default constructor; does no initialization // inline Matrix4( ) { }; // Copy a 4x4 matrix // inline Matrix4( const Matrix4 & mat ); // Construct a 4x4 matrix containing the specified columns // inline Matrix4( Vector4 col0, Vector4 col1, Vector4 col2, Vector4 col3 ); // Construct a 4x4 matrix from a 3x4 transformation matrix // explicit inline Matrix4( const Transform3 & mat ); // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector // inline Matrix4( const Matrix3 & mat, Vector3 translateVec ); // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector // inline Matrix4( Quat unitQuat, Vector3 translateVec ); // Set all elements of a 4x4 matrix to the same scalar value // explicit inline Matrix4( float scalar ); // Assign one 4x4 matrix to another // inline Matrix4 & operator =( const Matrix4 & mat ); // Set the upper-left 3x3 submatrix // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 4x4 matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setTranslation( Vector3 translateVec ); // Get the translation component of a 4x4 matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 4x4 matrix // inline Matrix4 & setCol0( Vector4 col0 ); // Set column 1 of a 4x4 matrix // inline Matrix4 & setCol1( Vector4 col1 ); // Set column 2 of a 4x4 matrix // inline Matrix4 & setCol2( Vector4 col2 ); // Set column 3 of a 4x4 matrix // inline Matrix4 & setCol3( Vector4 col3 ); // Get column 0 of a 4x4 matrix // inline const Vector4 getCol0( ) const; // Get column 1 of a 4x4 matrix // inline const Vector4 getCol1( ) const; // Get column 2 of a 4x4 matrix // inline const Vector4 getCol2( ) const; // Get column 3 of a 4x4 matrix // inline const Vector4 getCol3( ) const; // Set the column of a 4x4 matrix referred to by the specified index // inline Matrix4 & setCol( int col, Vector4 vec ); // Set the row of a 4x4 matrix referred to by the specified index // inline Matrix4 & setRow( int row, Vector4 vec ); // Get the column of a 4x4 matrix referred to by the specified index // inline const Vector4 getCol( int col ) const; // Get the row of a 4x4 matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector4 & operator []( int col ); // Subscripting operator to get a column // inline const Vector4 operator []( int col ) const; // Set the element of a 4x4 matrix referred to by column and row indices // inline Matrix4 & setElem( int col, int row, float val ); // Get the element of a 4x4 matrix referred to by column and row indices // inline float getElem( int col, int row ) const; // Add two 4x4 matrices // inline const Matrix4 operator +( const Matrix4 & mat ) const; // Subtract a 4x4 matrix from another 4x4 matrix // inline const Matrix4 operator -( const Matrix4 & mat ) const; // Negate all elements of a 4x4 matrix // inline const Matrix4 operator -( ) const; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( float scalar ) const; // Multiply a 4x4 matrix by a 4-D vector // inline const Vector4 operator *( Vector4 vec ) const; // Multiply a 4x4 matrix by a 3-D vector // inline const Vector4 operator *( Vector3 vec ) const; // Multiply a 4x4 matrix by a 3-D point // inline const Vector4 operator *( Point3 pnt ) const; // Multiply two 4x4 matrices // inline const Matrix4 operator *( const Matrix4 & mat ) const; // Multiply a 4x4 matrix by a 3x4 transformation matrix // inline const Matrix4 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and addition with a 4x4 matrix // inline Matrix4 & operator +=( const Matrix4 & mat ); // Perform compound assignment and subtraction by a 4x4 matrix // inline Matrix4 & operator -=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix4 & operator *=( float scalar ); // Perform compound assignment and multiplication by a 4x4 matrix // inline Matrix4 & operator *=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Matrix4 & operator *=( const Transform3 & tfrm ); // Construct an identity 4x4 matrix // static inline const Matrix4 identity( ); // Construct a 4x4 matrix to rotate around the x axis // static inline const Matrix4 rotationX( float radians ); // Construct a 4x4 matrix to rotate around the y axis // static inline const Matrix4 rotationY( float radians ); // Construct a 4x4 matrix to rotate around the z axis // static inline const Matrix4 rotationZ( float radians ); // Construct a 4x4 matrix to rotate around the x, y, and z axes // static inline const Matrix4 rotationZYX( Vector3 radiansXYZ ); // Construct a 4x4 matrix to rotate around a unit-length 3-D vector // static inline const Matrix4 rotation( float radians, Vector3 unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix4 rotation( Quat unitQuat ); // Construct a 4x4 matrix to perform scaling // static inline const Matrix4 scale( Vector3 scaleVec ); // Construct a 4x4 matrix to perform translation // static inline const Matrix4 translation( Vector3 translateVec ); // Construct viewing matrix based on eye position, position looked at, and up direction // static inline const Matrix4 lookAt( Point3 eyePos, Point3 lookAtPos, Vector3 upVec ); // Construct a perspective projection matrix // static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); // Construct a perspective projection matrix based on frustum // static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); // Construct an orthographic projection matrix // static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); }; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); // Append (post-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 appendScale( const Matrix4 & mat, Vector3 scaleVec ); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 prependScale( Vector3 scaleVec, const Matrix4 & mat ); // Multiply two 4x4 matrices per element // inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); // Compute the absolute value of a 4x4 matrix per element // inline const Matrix4 absPerElem( const Matrix4 & mat ); // Transpose of a 4x4 matrix // inline const Matrix4 transpose( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix4 inverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix // NOTE: // 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. // inline const Matrix4 affineInverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. // inline const Matrix4 orthoInverse( const Matrix4 & mat ); // Determinant of a 4x4 matrix // inline float determinant( const Matrix4 & mat ); // Conditionally select between two 4x4 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat ); // Print a 4x4 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat, const char * name ); #endif // A 3x4 transformation matrix in array-of-structures format // class Transform3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; Vector3 mCol3; public: // Default constructor; does no initialization // inline Transform3( ) { }; // Copy a 3x4 transformation matrix // inline Transform3( const Transform3 & tfrm ); // Construct a 3x4 transformation matrix containing the specified columns // inline Transform3( Vector3 col0, Vector3 col1, Vector3 col2, Vector3 col3 ); // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector // inline Transform3( const Matrix3 & tfrm, Vector3 translateVec ); // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector // inline Transform3( Quat unitQuat, Vector3 translateVec ); // Set all elements of a 3x4 transformation matrix to the same scalar value // explicit inline Transform3( float scalar ); // Assign one 3x4 transformation matrix to another // inline Transform3 & operator =( const Transform3 & tfrm ); // Set the upper-left 3x3 submatrix // inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // inline Transform3 & setTranslation( Vector3 translateVec ); // Get the translation component of a 3x4 transformation matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 3x4 transformation matrix // inline Transform3 & setCol0( Vector3 col0 ); // Set column 1 of a 3x4 transformation matrix // inline Transform3 & setCol1( Vector3 col1 ); // Set column 2 of a 3x4 transformation matrix // inline Transform3 & setCol2( Vector3 col2 ); // Set column 3 of a 3x4 transformation matrix // inline Transform3 & setCol3( Vector3 col3 ); // Get column 0 of a 3x4 transformation matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x4 transformation matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x4 transformation matrix // inline const Vector3 getCol2( ) const; // Get column 3 of a 3x4 transformation matrix // inline const Vector3 getCol3( ) const; // Set the column of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setCol( int col, Vector3 vec ); // Set the row of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setRow( int row, Vector4 vec ); // Get the column of a 3x4 transformation matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x4 transformation matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x4 transformation matrix referred to by column and row indices // inline Transform3 & setElem( int col, int row, float val ); // Get the element of a 3x4 transformation matrix referred to by column and row indices // inline float getElem( int col, int row ) const; // Multiply a 3x4 transformation matrix by a 3-D vector // inline const Vector3 operator *( Vector3 vec ) const; // Multiply a 3x4 transformation matrix by a 3-D point // inline const Point3 operator *( Point3 pnt ) const; // Multiply two 3x4 transformation matrices // inline const Transform3 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Transform3 & operator *=( const Transform3 & tfrm ); // Construct an identity 3x4 transformation matrix // static inline const Transform3 identity( ); // Construct a 3x4 transformation matrix to rotate around the x axis // static inline const Transform3 rotationX( float radians ); // Construct a 3x4 transformation matrix to rotate around the y axis // static inline const Transform3 rotationY( float radians ); // Construct a 3x4 transformation matrix to rotate around the z axis // static inline const Transform3 rotationZ( float radians ); // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes // static inline const Transform3 rotationZYX( Vector3 radiansXYZ ); // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector // static inline const Transform3 rotation( float radians, Vector3 unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Transform3 rotation( Quat unitQuat ); // Construct a 3x4 transformation matrix to perform scaling // static inline const Transform3 scale( Vector3 scaleVec ); // Construct a 3x4 transformation matrix to perform translation // static inline const Transform3 translation( Vector3 translateVec ); }; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 appendScale( const Transform3 & tfrm, Vector3 scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 prependScale( Vector3 scaleVec, const Transform3 & tfrm ); // Multiply two 3x4 transformation matrices per element // inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); // Compute the absolute value of a 3x4 transformation matrix per element // inline const Transform3 absPerElem( const Transform3 & tfrm ); // Inverse of a 3x4 transformation matrix // NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. // inline const Transform3 inverse( const Transform3 & tfrm ); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. // inline const Transform3 orthoInverse( const Transform3 & tfrm ); // Conditionally select between two 3x4 transformation matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm ); // Print a 3x4 transformation matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm, const char * name ); #endif } // namespace Aos } // namespace Vectormath #include "vec_aos.h" #include "quat_aos.h" #include "mat_aos.h" #endif ================================================ FILE: samples/vectormath/spu/cpp/vectormath_soa.h ================================================ /* Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Sony Computer Entertainment Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _VECTORMATH_SOA_CPP_SPU_H #define _VECTORMATH_SOA_CPP_SPU_H #include #include #include "floatInVec.h" #include "boolInVec.h" #include "vectormath_aos.h" #include #ifdef _VECTORMATH_DEBUG #endif namespace Vectormath { namespace Soa { //----------------------------------------------------------------------------- // Forward Declarations // class Vector3; class Vector4; class Point3; class Quat; class Matrix3; class Matrix4; class Transform3; // A set of four 3-D vectors in structure-of-arrays format // class Vector3 { typedef vec_float4 vec_float4_t; vec_float4 mX; vec_float4 mY; vec_float4 mZ; public: // Default constructor; does no initialization // inline Vector3( ) { }; // Copy a 3-D vector // inline Vector3( const Vector3 & vec ); // Construct a 3-D vector from x, y, and z elements // inline Vector3( vec_float4 x, vec_float4 y, vec_float4 z ); // Copy elements from a 3-D point into a 3-D vector // explicit inline Vector3( const Point3 & pnt ); // Set all elements of a 3-D vector to the same scalar value // explicit inline Vector3( vec_float4 scalar ); // Replicate an AoS 3-D vector // inline Vector3( Aos::Vector3 vec ); // Insert four AoS 3-D vectors // inline Vector3( Aos::Vector3 vec0, Aos::Vector3 vec1, Aos::Vector3 vec2, Aos::Vector3 vec3 ); // Extract four AoS 3-D vectors // inline void get4Aos( Aos::Vector3 & result0, Aos::Vector3 & result1, Aos::Vector3 & result2, Aos::Vector3 & result3 ) const; // Assign one 3-D vector to another // inline Vector3 & operator =( const Vector3 & vec ); // Set the x element of a 3-D vector // inline Vector3 & setX( vec_float4 x ); // Set the y element of a 3-D vector // inline Vector3 & setY( vec_float4 y ); // Set the z element of a 3-D vector // inline Vector3 & setZ( vec_float4 z ); // Get the x element of a 3-D vector // inline vec_float4 getX( ) const; // Get the y element of a 3-D vector // inline vec_float4 getY( ) const; // Get the z element of a 3-D vector // inline vec_float4 getZ( ) const; // Set an x, y, or z element of a 3-D vector by index // inline Vector3 & setElem( int idx, vec_float4 value ); // Get an x, y, or z element of a 3-D vector by index // inline vec_float4 getElem( int idx ) const; // Subscripting operator to set or get an element // inline vec_float4_t & operator []( int idx ); // Subscripting operator to get an element // inline vec_float4 operator []( int idx ) const; // Add two 3-D vectors // inline const Vector3 operator +( const Vector3 & vec ) const; // Subtract a 3-D vector from another 3-D vector // inline const Vector3 operator -( const Vector3 & vec ) const; // Add a 3-D vector to a 3-D point // inline const Point3 operator +( const Point3 & pnt ) const; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( vec_float4 scalar ) const; // Divide a 3-D vector by a scalar // inline const Vector3 operator /( vec_float4 scalar ) const; // Perform compound assignment and addition with a 3-D vector // inline Vector3 & operator +=( const Vector3 & vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Vector3 & operator -=( const Vector3 & vec ); // Perform compound assignment and multiplication by a scalar // inline Vector3 & operator *=( vec_float4 scalar ); // Perform compound assignment and division by a scalar // inline Vector3 & operator /=( vec_float4 scalar ); // Negate all elements of a 3-D vector // inline const Vector3 operator -( ) const; // Construct x axis // static inline const Vector3 xAxis( ); // Construct y axis // static inline const Vector3 yAxis( ); // Construct z axis // static inline const Vector3 zAxis( ); }; // Multiply a 3-D vector by a scalar // inline const Vector3 operator *( vec_float4 scalar, const Vector3 & vec ); // Multiply two 3-D vectors per element // inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Divide two 3-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Compute the reciprocal of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector3 recipPerElem( const Vector3 & vec ); // Compute the square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector3 sqrtPerElem( const Vector3 & vec ); // Compute the reciprocal square root of a 3-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector3 rsqrtPerElem( const Vector3 & vec ); // Compute the absolute value of a 3-D vector per element // inline const Vector3 absPerElem( const Vector3 & vec ); // Copy sign from one 3-D vector to another, per element // inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Maximum of two 3-D vectors per element // inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Minimum of two 3-D vectors per element // inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); // Maximum element of a 3-D vector // inline vec_float4 maxElem( const Vector3 & vec ); // Minimum element of a 3-D vector // inline vec_float4 minElem( const Vector3 & vec ); // Compute the sum of all elements of a 3-D vector // inline vec_float4 sum( const Vector3 & vec ); // Compute the dot product of two 3-D vectors // inline vec_float4 dot( const Vector3 & vec0, const Vector3 & vec1 ); // Compute the square of the length of a 3-D vector // inline vec_float4 lengthSqr( const Vector3 & vec ); // Compute the length of a 3-D vector // inline vec_float4 length( const Vector3 & vec ); // Normalize a 3-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector3 normalize( const Vector3 & vec ); // Compute cross product of two 3-D vectors // inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); // Outer product of two 3-D vectors // inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); // Pre-multiply a row vector by a 3x3 matrix // inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); // Cross-product matrix of a 3-D vector // inline const Matrix3 crossMatrix( const Vector3 & vec ); // Create cross-product matrix and multiply // NOTE: // Faster than separately creating a cross-product matrix and multiplying. // inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); // Linear interpolation between two 3-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector3 lerp( vec_float4 t, const Vector3 & vec0, const Vector3 & vec1 ); // Spherical linear interpolation between two 3-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector3 slerp( vec_float4 t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); // Conditionally select between two 3-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, vec_uint4 select1 ); // Load four three-float 3-D vectors, stored in three quadwords // inline void loadXYZArray( Vector3 & vec, const vec_float4 * threeQuads ); // Store four slots of an SoA 3-D vector in three quadwords // inline void storeXYZArray( const Vector3 & vec, vec_float4 * threeQuads ); // Store eight slots of two SoA 3-D vectors as half-floats // inline void storeHalfFloats( const Vector3 & vec0, const Vector3 & vec1, vec_ushort8 * threeQuads ); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector3 & vec ); // Print a 3-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector3 & vec, const char * name ); #endif // A set of four 4-D vectors in structure-of-arrays format // class Vector4 { typedef vec_float4 vec_float4_t; vec_float4 mX; vec_float4 mY; vec_float4 mZ; vec_float4 mW; public: // Default constructor; does no initialization // inline Vector4( ) { }; // Copy a 4-D vector // inline Vector4( const Vector4 & vec ); // Construct a 4-D vector from x, y, z, and w elements // inline Vector4( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); // Construct a 4-D vector from a 3-D vector and a scalar // inline Vector4( const Vector3 & xyz, vec_float4 w ); // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 // explicit inline Vector4( const Vector3 & vec ); // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 // explicit inline Vector4( const Point3 & pnt ); // Copy elements from a quaternion into a 4-D vector // explicit inline Vector4( const Quat & quat ); // Set all elements of a 4-D vector to the same scalar value // explicit inline Vector4( vec_float4 scalar ); // Replicate an AoS 4-D vector // inline Vector4( Aos::Vector4 vec ); // Insert four AoS 4-D vectors // inline Vector4( Aos::Vector4 vec0, Aos::Vector4 vec1, Aos::Vector4 vec2, Aos::Vector4 vec3 ); // Extract four AoS 4-D vectors // inline void get4Aos( Aos::Vector4 & result0, Aos::Vector4 & result1, Aos::Vector4 & result2, Aos::Vector4 & result3 ) const; // Assign one 4-D vector to another // inline Vector4 & operator =( const Vector4 & vec ); // Set the x, y, and z elements of a 4-D vector // NOTE: // This function does not change the w element. // inline Vector4 & setXYZ( const Vector3 & vec ); // Get the x, y, and z elements of a 4-D vector // inline const Vector3 getXYZ( ) const; // Set the x element of a 4-D vector // inline Vector4 & setX( vec_float4 x ); // Set the y element of a 4-D vector // inline Vector4 & setY( vec_float4 y ); // Set the z element of a 4-D vector // inline Vector4 & setZ( vec_float4 z ); // Set the w element of a 4-D vector // inline Vector4 & setW( vec_float4 w ); // Get the x element of a 4-D vector // inline vec_float4 getX( ) const; // Get the y element of a 4-D vector // inline vec_float4 getY( ) const; // Get the z element of a 4-D vector // inline vec_float4 getZ( ) const; // Get the w element of a 4-D vector // inline vec_float4 getW( ) const; // Set an x, y, z, or w element of a 4-D vector by index // inline Vector4 & setElem( int idx, vec_float4 value ); // Get an x, y, z, or w element of a 4-D vector by index // inline vec_float4 getElem( int idx ) const; // Subscripting operator to set or get an element // inline vec_float4_t & operator []( int idx ); // Subscripting operator to get an element // inline vec_float4 operator []( int idx ) const; // Add two 4-D vectors // inline const Vector4 operator +( const Vector4 & vec ) const; // Subtract a 4-D vector from another 4-D vector // inline const Vector4 operator -( const Vector4 & vec ) const; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( vec_float4 scalar ) const; // Divide a 4-D vector by a scalar // inline const Vector4 operator /( vec_float4 scalar ) const; // Perform compound assignment and addition with a 4-D vector // inline Vector4 & operator +=( const Vector4 & vec ); // Perform compound assignment and subtraction by a 4-D vector // inline Vector4 & operator -=( const Vector4 & vec ); // Perform compound assignment and multiplication by a scalar // inline Vector4 & operator *=( vec_float4 scalar ); // Perform compound assignment and division by a scalar // inline Vector4 & operator /=( vec_float4 scalar ); // Negate all elements of a 4-D vector // inline const Vector4 operator -( ) const; // Construct x axis // static inline const Vector4 xAxis( ); // Construct y axis // static inline const Vector4 yAxis( ); // Construct z axis // static inline const Vector4 zAxis( ); // Construct w axis // static inline const Vector4 wAxis( ); }; // Multiply a 4-D vector by a scalar // inline const Vector4 operator *( vec_float4 scalar, const Vector4 & vec ); // Multiply two 4-D vectors per element // inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Divide two 4-D vectors per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Compute the reciprocal of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Vector4 recipPerElem( const Vector4 & vec ); // Compute the square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Vector4 sqrtPerElem( const Vector4 & vec ); // Compute the reciprocal square root of a 4-D vector per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Vector4 rsqrtPerElem( const Vector4 & vec ); // Compute the absolute value of a 4-D vector per element // inline const Vector4 absPerElem( const Vector4 & vec ); // Copy sign from one 4-D vector to another, per element // inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Maximum of two 4-D vectors per element // inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Minimum of two 4-D vectors per element // inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); // Maximum element of a 4-D vector // inline vec_float4 maxElem( const Vector4 & vec ); // Minimum element of a 4-D vector // inline vec_float4 minElem( const Vector4 & vec ); // Compute the sum of all elements of a 4-D vector // inline vec_float4 sum( const Vector4 & vec ); // Compute the dot product of two 4-D vectors // inline vec_float4 dot( const Vector4 & vec0, const Vector4 & vec1 ); // Compute the square of the length of a 4-D vector // inline vec_float4 lengthSqr( const Vector4 & vec ); // Compute the length of a 4-D vector // inline vec_float4 length( const Vector4 & vec ); // Normalize a 4-D vector // NOTE: // The result is unpredictable when all elements of vec are at or near zero. // inline const Vector4 normalize( const Vector4 & vec ); // Outer product of two 4-D vectors // inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); // Linear interpolation between two 4-D vectors // NOTE: // Does not clamp t between 0 and 1. // inline const Vector4 lerp( vec_float4 t, const Vector4 & vec0, const Vector4 & vec1 ); // Spherical linear interpolation between two 4-D vectors // NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. // inline const Vector4 slerp( vec_float4 t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); // Conditionally select between two 4-D vectors // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, vec_uint4 select1 ); // Store four slots of an SoA 4-D vector as half-floats // inline void storeHalfFloats( const Vector4 & vec, vec_ushort8 * twoQuads ); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector4 & vec ); // Print a 4-D vector and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Vector4 & vec, const char * name ); #endif // A set of four 3-D points in structure-of-arrays format // class Point3 { typedef vec_float4 vec_float4_t; vec_float4 mX; vec_float4 mY; vec_float4 mZ; public: // Default constructor; does no initialization // inline Point3( ) { }; // Copy a 3-D point // inline Point3( const Point3 & pnt ); // Construct a 3-D point from x, y, and z elements // inline Point3( vec_float4 x, vec_float4 y, vec_float4 z ); // Copy elements from a 3-D vector into a 3-D point // explicit inline Point3( const Vector3 & vec ); // Set all elements of a 3-D point to the same scalar value // explicit inline Point3( vec_float4 scalar ); // Replicate an AoS 3-D point // inline Point3( Aos::Point3 pnt ); // Insert four AoS 3-D points // inline Point3( Aos::Point3 pnt0, Aos::Point3 pnt1, Aos::Point3 pnt2, Aos::Point3 pnt3 ); // Extract four AoS 3-D points // inline void get4Aos( Aos::Point3 & result0, Aos::Point3 & result1, Aos::Point3 & result2, Aos::Point3 & result3 ) const; // Assign one 3-D point to another // inline Point3 & operator =( const Point3 & pnt ); // Set the x element of a 3-D point // inline Point3 & setX( vec_float4 x ); // Set the y element of a 3-D point // inline Point3 & setY( vec_float4 y ); // Set the z element of a 3-D point // inline Point3 & setZ( vec_float4 z ); // Get the x element of a 3-D point // inline vec_float4 getX( ) const; // Get the y element of a 3-D point // inline vec_float4 getY( ) const; // Get the z element of a 3-D point // inline vec_float4 getZ( ) const; // Set an x, y, or z element of a 3-D point by index // inline Point3 & setElem( int idx, vec_float4 value ); // Get an x, y, or z element of a 3-D point by index // inline vec_float4 getElem( int idx ) const; // Subscripting operator to set or get an element // inline vec_float4_t & operator []( int idx ); // Subscripting operator to get an element // inline vec_float4 operator []( int idx ) const; // Subtract a 3-D point from another 3-D point // inline const Vector3 operator -( const Point3 & pnt ) const; // Add a 3-D point to a 3-D vector // inline const Point3 operator +( const Vector3 & vec ) const; // Subtract a 3-D vector from a 3-D point // inline const Point3 operator -( const Vector3 & vec ) const; // Perform compound assignment and addition with a 3-D vector // inline Point3 & operator +=( const Vector3 & vec ); // Perform compound assignment and subtraction by a 3-D vector // inline Point3 & operator -=( const Vector3 & vec ); }; // Multiply two 3-D points per element // inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Divide two 3-D points per element // NOTE: // Floating-point behavior matches standard library function divf4. // inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Compute the reciprocal of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function recipf4. // inline const Point3 recipPerElem( const Point3 & pnt ); // Compute the square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function sqrtf4. // inline const Point3 sqrtPerElem( const Point3 & pnt ); // Compute the reciprocal square root of a 3-D point per element // NOTE: // Floating-point behavior matches standard library function rsqrtf4. // inline const Point3 rsqrtPerElem( const Point3 & pnt ); // Compute the absolute value of a 3-D point per element // inline const Point3 absPerElem( const Point3 & pnt ); // Copy sign from one 3-D point to another, per element // inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Maximum of two 3-D points per element // inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Minimum of two 3-D points per element // inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); // Maximum element of a 3-D point // inline vec_float4 maxElem( const Point3 & pnt ); // Minimum element of a 3-D point // inline vec_float4 minElem( const Point3 & pnt ); // Compute the sum of all elements of a 3-D point // inline vec_float4 sum( const Point3 & pnt ); // Apply uniform scale to a 3-D point // inline const Point3 scale( const Point3 & pnt, vec_float4 scaleVal ); // Apply non-uniform scale to a 3-D point // inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); // Scalar projection of a 3-D point on a unit-length 3-D vector // inline vec_float4 projection( const Point3 & pnt, const Vector3 & unitVec ); // Compute the square of the distance of a 3-D point from the coordinate-system origin // inline vec_float4 distSqrFromOrigin( const Point3 & pnt ); // Compute the distance of a 3-D point from the coordinate-system origin // inline vec_float4 distFromOrigin( const Point3 & pnt ); // Compute the square of the distance between two 3-D points // inline vec_float4 distSqr( const Point3 & pnt0, const Point3 & pnt1 ); // Compute the distance between two 3-D points // inline vec_float4 dist( const Point3 & pnt0, const Point3 & pnt1 ); // Linear interpolation between two 3-D points // NOTE: // Does not clamp t between 0 and 1. // inline const Point3 lerp( vec_float4 t, const Point3 & pnt0, const Point3 & pnt1 ); // Conditionally select between two 3-D points // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, vec_uint4 select1 ); // Load four three-float 3-D points, stored in three quadwords // inline void loadXYZArray( Point3 & pnt, const vec_float4 * threeQuads ); // Store four slots of an SoA 3-D point in three quadwords // inline void storeXYZArray( const Point3 & pnt, vec_float4 * threeQuads ); // Store eight slots of two SoA 3-D points as half-floats // inline void storeHalfFloats( const Point3 & pnt0, const Point3 & pnt1, vec_ushort8 * threeQuads ); #ifdef _VECTORMATH_DEBUG // Print a 3-D point // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Point3 & pnt ); // Print a 3-D point and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Point3 & pnt, const char * name ); #endif // A set of four quaternions in structure-of-arrays format // class Quat { typedef vec_float4 vec_float4_t; vec_float4 mX; vec_float4 mY; vec_float4 mZ; vec_float4 mW; public: // Default constructor; does no initialization // inline Quat( ) { }; // Copy a quaternion // inline Quat( const Quat & quat ); // Construct a quaternion from x, y, z, and w elements // inline Quat( vec_float4 x, vec_float4 y, vec_float4 z, vec_float4 w ); // Construct a quaternion from a 3-D vector and a scalar // inline Quat( const Vector3 & xyz, vec_float4 w ); // Copy elements from a 4-D vector into a quaternion // explicit inline Quat( const Vector4 & vec ); // Convert a rotation matrix to a unit-length quaternion // explicit inline Quat( const Matrix3 & rotMat ); // Set all elements of a quaternion to the same scalar value // explicit inline Quat( vec_float4 scalar ); // Replicate an AoS quaternion // inline Quat( Aos::Quat quat ); // Insert four AoS quaternions // inline Quat( Aos::Quat quat0, Aos::Quat quat1, Aos::Quat quat2, Aos::Quat quat3 ); // Extract four AoS quaternions // inline void get4Aos( Aos::Quat & result0, Aos::Quat & result1, Aos::Quat & result2, Aos::Quat & result3 ) const; // Assign one quaternion to another // inline Quat & operator =( const Quat & quat ); // Set the x, y, and z elements of a quaternion // NOTE: // This function does not change the w element. // inline Quat & setXYZ( const Vector3 & vec ); // Get the x, y, and z elements of a quaternion // inline const Vector3 getXYZ( ) const; // Set the x element of a quaternion // inline Quat & setX( vec_float4 x ); // Set the y element of a quaternion // inline Quat & setY( vec_float4 y ); // Set the z element of a quaternion // inline Quat & setZ( vec_float4 z ); // Set the w element of a quaternion // inline Quat & setW( vec_float4 w ); // Get the x element of a quaternion // inline vec_float4 getX( ) const; // Get the y element of a quaternion // inline vec_float4 getY( ) const; // Get the z element of a quaternion // inline vec_float4 getZ( ) const; // Get the w element of a quaternion // inline vec_float4 getW( ) const; // Set an x, y, z, or w element of a quaternion by index // inline Quat & setElem( int idx, vec_float4 value ); // Get an x, y, z, or w element of a quaternion by index // inline vec_float4 getElem( int idx ) const; // Subscripting operator to set or get an element // inline vec_float4_t & operator []( int idx ); // Subscripting operator to get an element // inline vec_float4 operator []( int idx ) const; // Add two quaternions // inline const Quat operator +( const Quat & quat ) const; // Subtract a quaternion from another quaternion // inline const Quat operator -( const Quat & quat ) const; // Multiply two quaternions // inline const Quat operator *( const Quat & quat ) const; // Multiply a quaternion by a scalar // inline const Quat operator *( vec_float4 scalar ) const; // Divide a quaternion by a scalar // inline const Quat operator /( vec_float4 scalar ) const; // Perform compound assignment and addition with a quaternion // inline Quat & operator +=( const Quat & quat ); // Perform compound assignment and subtraction by a quaternion // inline Quat & operator -=( const Quat & quat ); // Perform compound assignment and multiplication by a quaternion // inline Quat & operator *=( const Quat & quat ); // Perform compound assignment and multiplication by a scalar // inline Quat & operator *=( vec_float4 scalar ); // Perform compound assignment and division by a scalar // inline Quat & operator /=( vec_float4 scalar ); // Negate all elements of a quaternion // inline const Quat operator -( ) const; // Construct an identity quaternion // static inline const Quat identity( ); // Construct a quaternion to rotate between two unit-length 3-D vectors // NOTE: // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. // static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); // Construct a quaternion to rotate around a unit-length 3-D vector // static inline const Quat rotation( vec_float4 radians, const Vector3 & unitVec ); // Construct a quaternion to rotate around the x axis // static inline const Quat rotationX( vec_float4 radians ); // Construct a quaternion to rotate around the y axis // static inline const Quat rotationY( vec_float4 radians ); // Construct a quaternion to rotate around the z axis // static inline const Quat rotationZ( vec_float4 radians ); }; // Multiply a quaternion by a scalar // inline const Quat operator *( vec_float4 scalar, const Quat & quat ); // Compute the conjugate of a quaternion // inline const Quat conj( const Quat & quat ); // Use a unit-length quaternion to rotate a 3-D vector // inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); // Compute the dot product of two quaternions // inline vec_float4 dot( const Quat & quat0, const Quat & quat1 ); // Compute the norm of a quaternion // inline vec_float4 norm( const Quat & quat ); // Compute the length of a quaternion // inline vec_float4 length( const Quat & quat ); // Normalize a quaternion // NOTE: // The result is unpredictable when all elements of quat are at or near zero. // inline const Quat normalize( const Quat & quat ); // Linear interpolation between two quaternions // NOTE: // Does not clamp t between 0 and 1. // inline const Quat lerp( vec_float4 t, const Quat & quat0, const Quat & quat1 ); // Spherical linear interpolation between two quaternions // NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. // inline const Quat slerp( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1 ); // Spherical quadrangle interpolation // inline const Quat squad( vec_float4 t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); // Conditionally select between two quaternions // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Quat select( const Quat & quat0, const Quat & quat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG // Print a quaternion // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Quat & quat ); // Print a quaternion and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Quat & quat, const char * name ); #endif // A set of four 3x3 matrices in structure-of-arrays format // class Matrix3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; public: // Default constructor; does no initialization // inline Matrix3( ) { }; // Copy a 3x3 matrix // inline Matrix3( const Matrix3 & mat ); // Construct a 3x3 matrix containing the specified columns // inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); // Construct a 3x3 rotation matrix from a unit-length quaternion // explicit inline Matrix3( const Quat & unitQuat ); // Set all elements of a 3x3 matrix to the same scalar value // explicit inline Matrix3( vec_float4 scalar ); // Replicate an AoS 3x3 matrix // inline Matrix3( const Aos::Matrix3 & mat ); // Insert four AoS 3x3 matrices // inline Matrix3( const Aos::Matrix3 & mat0, const Aos::Matrix3 & mat1, const Aos::Matrix3 & mat2, const Aos::Matrix3 & mat3 ); // Extract four AoS 3x3 matrices // inline void get4Aos( Aos::Matrix3 & result0, Aos::Matrix3 & result1, Aos::Matrix3 & result2, Aos::Matrix3 & result3 ) const; // Assign one 3x3 matrix to another // inline Matrix3 & operator =( const Matrix3 & mat ); // Set column 0 of a 3x3 matrix // inline Matrix3 & setCol0( const Vector3 & col0 ); // Set column 1 of a 3x3 matrix // inline Matrix3 & setCol1( const Vector3 & col1 ); // Set column 2 of a 3x3 matrix // inline Matrix3 & setCol2( const Vector3 & col2 ); // Get column 0 of a 3x3 matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x3 matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x3 matrix // inline const Vector3 getCol2( ) const; // Set the column of a 3x3 matrix referred to by the specified index // inline Matrix3 & setCol( int col, const Vector3 & vec ); // Set the row of a 3x3 matrix referred to by the specified index // inline Matrix3 & setRow( int row, const Vector3 & vec ); // Get the column of a 3x3 matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x3 matrix referred to by the specified index // inline const Vector3 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x3 matrix referred to by column and row indices // inline Matrix3 & setElem( int col, int row, vec_float4 val ); // Get the element of a 3x3 matrix referred to by column and row indices // inline vec_float4 getElem( int col, int row ) const; // Add two 3x3 matrices // inline const Matrix3 operator +( const Matrix3 & mat ) const; // Subtract a 3x3 matrix from another 3x3 matrix // inline const Matrix3 operator -( const Matrix3 & mat ) const; // Negate all elements of a 3x3 matrix // inline const Matrix3 operator -( ) const; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( vec_float4 scalar ) const; // Multiply a 3x3 matrix by a 3-D vector // inline const Vector3 operator *( const Vector3 & vec ) const; // Multiply two 3x3 matrices // inline const Matrix3 operator *( const Matrix3 & mat ) const; // Perform compound assignment and addition with a 3x3 matrix // inline Matrix3 & operator +=( const Matrix3 & mat ); // Perform compound assignment and subtraction by a 3x3 matrix // inline Matrix3 & operator -=( const Matrix3 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix3 & operator *=( vec_float4 scalar ); // Perform compound assignment and multiplication by a 3x3 matrix // inline Matrix3 & operator *=( const Matrix3 & mat ); // Construct an identity 3x3 matrix // static inline const Matrix3 identity( ); // Construct a 3x3 matrix to rotate around the x axis // static inline const Matrix3 rotationX( vec_float4 radians ); // Construct a 3x3 matrix to rotate around the y axis // static inline const Matrix3 rotationY( vec_float4 radians ); // Construct a 3x3 matrix to rotate around the z axis // static inline const Matrix3 rotationZ( vec_float4 radians ); // Construct a 3x3 matrix to rotate around the x, y, and z axes // static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 3x3 matrix to rotate around a unit-length 3-D vector // static inline const Matrix3 rotation( vec_float4 radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix3 rotation( const Quat & unitQuat ); // Construct a 3x3 matrix to perform scaling // static inline const Matrix3 scale( const Vector3 & scaleVec ); }; // Multiply a 3x3 matrix by a scalar // inline const Matrix3 operator *( vec_float4 scalar, const Matrix3 & mat ); // Append (post-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); // Multiply two 3x3 matrices per element // inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); // Compute the absolute value of a 3x3 matrix per element // inline const Matrix3 absPerElem( const Matrix3 & mat ); // Transpose of a 3x3 matrix // inline const Matrix3 transpose( const Matrix3 & mat ); // Compute the inverse of a 3x3 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix3 inverse( const Matrix3 & mat ); // Determinant of a 3x3 matrix // inline vec_float4 determinant( const Matrix3 & mat ); // Conditionally select between two 3x3 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat ); // Print a 3x3 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix3 & mat, const char * name ); #endif // A set of four 4x4 matrices in structure-of-arrays format // class Matrix4 { Vector4 mCol0; Vector4 mCol1; Vector4 mCol2; Vector4 mCol3; public: // Default constructor; does no initialization // inline Matrix4( ) { }; // Copy a 4x4 matrix // inline Matrix4( const Matrix4 & mat ); // Construct a 4x4 matrix containing the specified columns // inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); // Construct a 4x4 matrix from a 3x4 transformation matrix // explicit inline Matrix4( const Transform3 & mat ); // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector // inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector // inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); // Set all elements of a 4x4 matrix to the same scalar value // explicit inline Matrix4( vec_float4 scalar ); // Replicate an AoS 4x4 matrix // inline Matrix4( const Aos::Matrix4 & mat ); // Insert four AoS 4x4 matrices // inline Matrix4( const Aos::Matrix4 & mat0, const Aos::Matrix4 & mat1, const Aos::Matrix4 & mat2, const Aos::Matrix4 & mat3 ); // Extract four AoS 4x4 matrices // inline void get4Aos( Aos::Matrix4 & result0, Aos::Matrix4 & result1, Aos::Matrix4 & result2, Aos::Matrix4 & result3 ) const; // Assign one 4x4 matrix to another // inline Matrix4 & operator =( const Matrix4 & mat ); // Set the upper-left 3x3 submatrix // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 4x4 matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // NOTE: // This function does not change the bottom row elements. // inline Matrix4 & setTranslation( const Vector3 & translateVec ); // Get the translation component of a 4x4 matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 4x4 matrix // inline Matrix4 & setCol0( const Vector4 & col0 ); // Set column 1 of a 4x4 matrix // inline Matrix4 & setCol1( const Vector4 & col1 ); // Set column 2 of a 4x4 matrix // inline Matrix4 & setCol2( const Vector4 & col2 ); // Set column 3 of a 4x4 matrix // inline Matrix4 & setCol3( const Vector4 & col3 ); // Get column 0 of a 4x4 matrix // inline const Vector4 getCol0( ) const; // Get column 1 of a 4x4 matrix // inline const Vector4 getCol1( ) const; // Get column 2 of a 4x4 matrix // inline const Vector4 getCol2( ) const; // Get column 3 of a 4x4 matrix // inline const Vector4 getCol3( ) const; // Set the column of a 4x4 matrix referred to by the specified index // inline Matrix4 & setCol( int col, const Vector4 & vec ); // Set the row of a 4x4 matrix referred to by the specified index // inline Matrix4 & setRow( int row, const Vector4 & vec ); // Get the column of a 4x4 matrix referred to by the specified index // inline const Vector4 getCol( int col ) const; // Get the row of a 4x4 matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector4 & operator []( int col ); // Subscripting operator to get a column // inline const Vector4 operator []( int col ) const; // Set the element of a 4x4 matrix referred to by column and row indices // inline Matrix4 & setElem( int col, int row, vec_float4 val ); // Get the element of a 4x4 matrix referred to by column and row indices // inline vec_float4 getElem( int col, int row ) const; // Add two 4x4 matrices // inline const Matrix4 operator +( const Matrix4 & mat ) const; // Subtract a 4x4 matrix from another 4x4 matrix // inline const Matrix4 operator -( const Matrix4 & mat ) const; // Negate all elements of a 4x4 matrix // inline const Matrix4 operator -( ) const; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( vec_float4 scalar ) const; // Multiply a 4x4 matrix by a 4-D vector // inline const Vector4 operator *( const Vector4 & vec ) const; // Multiply a 4x4 matrix by a 3-D vector // inline const Vector4 operator *( const Vector3 & vec ) const; // Multiply a 4x4 matrix by a 3-D point // inline const Vector4 operator *( const Point3 & pnt ) const; // Multiply two 4x4 matrices // inline const Matrix4 operator *( const Matrix4 & mat ) const; // Multiply a 4x4 matrix by a 3x4 transformation matrix // inline const Matrix4 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and addition with a 4x4 matrix // inline Matrix4 & operator +=( const Matrix4 & mat ); // Perform compound assignment and subtraction by a 4x4 matrix // inline Matrix4 & operator -=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a scalar // inline Matrix4 & operator *=( vec_float4 scalar ); // Perform compound assignment and multiplication by a 4x4 matrix // inline Matrix4 & operator *=( const Matrix4 & mat ); // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Matrix4 & operator *=( const Transform3 & tfrm ); // Construct an identity 4x4 matrix // static inline const Matrix4 identity( ); // Construct a 4x4 matrix to rotate around the x axis // static inline const Matrix4 rotationX( vec_float4 radians ); // Construct a 4x4 matrix to rotate around the y axis // static inline const Matrix4 rotationY( vec_float4 radians ); // Construct a 4x4 matrix to rotate around the z axis // static inline const Matrix4 rotationZ( vec_float4 radians ); // Construct a 4x4 matrix to rotate around the x, y, and z axes // static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 4x4 matrix to rotate around a unit-length 3-D vector // static inline const Matrix4 rotation( vec_float4 radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Matrix4 rotation( const Quat & unitQuat ); // Construct a 4x4 matrix to perform scaling // static inline const Matrix4 scale( const Vector3 & scaleVec ); // Construct a 4x4 matrix to perform translation // static inline const Matrix4 translation( const Vector3 & translateVec ); // Construct viewing matrix based on eye position, position looked at, and up direction // static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); // Construct a perspective projection matrix // static inline const Matrix4 perspective( vec_float4 fovyRadians, vec_float4 aspect, vec_float4 zNear, vec_float4 zFar ); // Construct a perspective projection matrix based on frustum // static inline const Matrix4 frustum( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); // Construct an orthographic projection matrix // static inline const Matrix4 orthographic( vec_float4 left, vec_float4 right, vec_float4 bottom, vec_float4 top, vec_float4 zNear, vec_float4 zFar ); }; // Multiply a 4x4 matrix by a scalar // inline const Matrix4 operator *( vec_float4 scalar, const Matrix4 & mat ); // Append (post-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); // Multiply two 4x4 matrices per element // inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); // Compute the absolute value of a 4x4 matrix per element // inline const Matrix4 absPerElem( const Matrix4 & mat ); // Transpose of a 4x4 matrix // inline const Matrix4 transpose( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix // NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. // inline const Matrix4 inverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix // NOTE: // 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. // inline const Matrix4 affineInverse( const Matrix4 & mat ); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. // inline const Matrix4 orthoInverse( const Matrix4 & mat ); // Determinant of a 4x4 matrix // inline vec_float4 determinant( const Matrix4 & mat ); // Conditionally select between two 4x4 matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat ); // Print a 4x4 matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Matrix4 & mat, const char * name ); #endif // A set of four 3x4 transformation matrices in structure-of-arrays format // class Transform3 { Vector3 mCol0; Vector3 mCol1; Vector3 mCol2; Vector3 mCol3; public: // Default constructor; does no initialization // inline Transform3( ) { }; // Copy a 3x4 transformation matrix // inline Transform3( const Transform3 & tfrm ); // Construct a 3x4 transformation matrix containing the specified columns // inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector // inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector // inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); // Set all elements of a 3x4 transformation matrix to the same scalar value // explicit inline Transform3( vec_float4 scalar ); // Replicate an AoS 3x4 transformation matrix // inline Transform3( const Aos::Transform3 & tfrm ); // Insert four AoS 3x4 transformation matrices // inline Transform3( const Aos::Transform3 & tfrm0, const Aos::Transform3 & tfrm1, const Aos::Transform3 & tfrm2, const Aos::Transform3 & tfrm3 ); // Extract four AoS 3x4 transformation matrices // inline void get4Aos( Aos::Transform3 & result0, Aos::Transform3 & result1, Aos::Transform3 & result2, Aos::Transform3 & result3 ) const; // Assign one 3x4 transformation matrix to another // inline Transform3 & operator =( const Transform3 & tfrm ); // Set the upper-left 3x3 submatrix // inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix // inline const Matrix3 getUpper3x3( ) const; // Set translation component // inline Transform3 & setTranslation( const Vector3 & translateVec ); // Get the translation component of a 3x4 transformation matrix // inline const Vector3 getTranslation( ) const; // Set column 0 of a 3x4 transformation matrix // inline Transform3 & setCol0( const Vector3 & col0 ); // Set column 1 of a 3x4 transformation matrix // inline Transform3 & setCol1( const Vector3 & col1 ); // Set column 2 of a 3x4 transformation matrix // inline Transform3 & setCol2( const Vector3 & col2 ); // Set column 3 of a 3x4 transformation matrix // inline Transform3 & setCol3( const Vector3 & col3 ); // Get column 0 of a 3x4 transformation matrix // inline const Vector3 getCol0( ) const; // Get column 1 of a 3x4 transformation matrix // inline const Vector3 getCol1( ) const; // Get column 2 of a 3x4 transformation matrix // inline const Vector3 getCol2( ) const; // Get column 3 of a 3x4 transformation matrix // inline const Vector3 getCol3( ) const; // Set the column of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setCol( int col, const Vector3 & vec ); // Set the row of a 3x4 transformation matrix referred to by the specified index // inline Transform3 & setRow( int row, const Vector4 & vec ); // Get the column of a 3x4 transformation matrix referred to by the specified index // inline const Vector3 getCol( int col ) const; // Get the row of a 3x4 transformation matrix referred to by the specified index // inline const Vector4 getRow( int row ) const; // Subscripting operator to set or get a column // inline Vector3 & operator []( int col ); // Subscripting operator to get a column // inline const Vector3 operator []( int col ) const; // Set the element of a 3x4 transformation matrix referred to by column and row indices // inline Transform3 & setElem( int col, int row, vec_float4 val ); // Get the element of a 3x4 transformation matrix referred to by column and row indices // inline vec_float4 getElem( int col, int row ) const; // Multiply a 3x4 transformation matrix by a 3-D vector // inline const Vector3 operator *( const Vector3 & vec ) const; // Multiply a 3x4 transformation matrix by a 3-D point // inline const Point3 operator *( const Point3 & pnt ) const; // Multiply two 3x4 transformation matrices // inline const Transform3 operator *( const Transform3 & tfrm ) const; // Perform compound assignment and multiplication by a 3x4 transformation matrix // inline Transform3 & operator *=( const Transform3 & tfrm ); // Construct an identity 3x4 transformation matrix // static inline const Transform3 identity( ); // Construct a 3x4 transformation matrix to rotate around the x axis // static inline const Transform3 rotationX( vec_float4 radians ); // Construct a 3x4 transformation matrix to rotate around the y axis // static inline const Transform3 rotationY( vec_float4 radians ); // Construct a 3x4 transformation matrix to rotate around the z axis // static inline const Transform3 rotationZ( vec_float4 radians ); // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes // static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector // static inline const Transform3 rotation( vec_float4 radians, const Vector3 & unitVec ); // Construct a rotation matrix from a unit-length quaternion // static inline const Transform3 rotation( const Quat & unitQuat ); // Construct a 3x4 transformation matrix to perform scaling // static inline const Transform3 scale( const Vector3 & scaleVec ); // Construct a 3x4 transformation matrix to perform translation // static inline const Transform3 translation( const Vector3 & translateVec ); }; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix // NOTE: // Faster than creating and multiplying a scale transformation matrix. // inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); // Multiply two 3x4 transformation matrices per element // inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); // Compute the absolute value of a 3x4 transformation matrix per element // inline const Transform3 absPerElem( const Transform3 & tfrm ); // Inverse of a 3x4 transformation matrix // NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. // inline const Transform3 inverse( const Transform3 & tfrm ); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix // NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. // inline const Transform3 orthoInverse( const Transform3 & tfrm ); // Conditionally select between two 3x4 transformation matrices // NOTE: // This function uses a conditional select instruction to avoid a branch. // inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, vec_uint4 select1 ); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm ); // Print a 3x4 transformation matrix and an associated string identifier // NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. // inline void print( const Transform3 & tfrm, const char * name ); #endif } // namespace Soa } // namespace Vectormath #include "vec_soa.h" #include "quat_soa.h" #include "mat_soa.h" #endif ================================================ FILE: samples/vectormath/vectormath.h ================================================ // ================================================================================================ // -*- C++ -*- // File: vectormath.h // Author: Guilherme R. Lampert // Brief: This header exposes the Sony Vector Math library types into the global scope. // ================================================================================================ #ifndef VECTORMATH_H_ #define VECTORMATH_H_ // We're using the generic Array of Structures (AoS) format. #include "cpp/vectormath_aos.h" using namespace Vectormath::Aos; inline float * toFloatPtr(Point3 & p) { return reinterpret_cast(&p); } inline float * toFloatPtr(Vector3 & v) { return reinterpret_cast(&v); } inline float * toFloatPtr(Vector4 & v) { return reinterpret_cast(&v); } inline float * toFloatPtr(Quat & q) { return reinterpret_cast(&q); } inline float * toFloatPtr(Matrix3 & m) { return reinterpret_cast(&m); } inline float * toFloatPtr(Matrix4 & m) { return reinterpret_cast(&m); } inline const float * toFloatPtr(const Point3 & p) { return reinterpret_cast(&p); } inline const float * toFloatPtr(const Vector3 & v) { return reinterpret_cast(&v); } inline const float * toFloatPtr(const Vector4 & v) { return reinterpret_cast(&v); } inline const float * toFloatPtr(const Quat & q) { return reinterpret_cast(&q); } inline const float * toFloatPtr(const Matrix3 & m) { return reinterpret_cast(&m); } inline const float * toFloatPtr(const Matrix4 & m) { return reinterpret_cast(&m); } // Shorthand to discard the last element of a Vector4 and get a Point3. inline Point3 toPoint3(const Vector4 & v4) { return Point3(v4[0], v4[1], v4[2]); } // Convert from world (global) coordinates to local model coordinates. // Input matrix must be the inverse of the model matrix, e.g.: 'inverse(modelMatrix)'. inline Point3 worldPointToModel(const Matrix4 & invModelToWorldMatrix, const Point3 & point) { return toPoint3(invModelToWorldMatrix * point); } #endif // VECTORMATH_H_ ================================================ FILE: samples/vs2015/ddSampleD3D11/ddSampleD3D11.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files ================================================ FILE: samples/vs2015/ddSampleD3D11/ddSampleD3D11.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ddSampleD3D11", "ddSampleD3D11.vcxproj", "{362616A9-7C5B-428B-B2EF-3350A7961F81}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x64.ActiveCfg = Debug|x64 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x64.Build.0 = Debug|x64 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x64.ActiveCfg = Release|x64 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: samples/vs2015/ddSampleD3D11/ddSampleD3D11.vcxproj ================================================  Debug Win32 Release Win32 Debug x64 Release x64 {362616A9-7C5B-428B-B2EF-3350A7961F81} Win32Proj ddSampleD3D11 8.1 ddSampleD3D11 Application true v140 Unicode Application false v140 true Unicode Application true v140 Unicode Application false v140 true Unicode true $(SolutionDir)..\..\..\;$(IncludePath) true $(SolutionDir)..\..\..\;$(IncludePath) false $(SolutionDir)..\..\..\;$(IncludePath) false $(SolutionDir)..\..\..\;$(IncludePath) Level4 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)../../vectormath/;%(AdditionalIncludeDirectories) Console true VS_LinePoint 4.0 PerMonitorHighDPIAware Level4 Disabled _DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)../../vectormath/;%(AdditionalIncludeDirectories) Windows true VS_LinePoint 4.0 PerMonitorHighDPIAware Level4 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)../../vectormath/;%(AdditionalIncludeDirectories) Console true true true VS_LinePoint 4.0 PerMonitorHighDPIAware Level4 MaxSpeed true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)../../vectormath/;%(AdditionalIncludeDirectories) Windows true true true VS_LinePoint 4.0 PerMonitorHighDPIAware ================================================ FILE: samples/vs2015/ddSampleD3D11/ddShader.fx ================================================ /////////////////////////////////////////////////////////////////////////////// Texture2D glyphsTexture : register(t0); SamplerState glyphsSampler : register(s0); cbuffer ConstantBufferData : register(b0) { matrix mvpMatrix; float4 screenDimensions; }; /////////////////////////////////////////////////////////////////////////////// struct VertexInput { float4 pos : POSITION; float4 uv : TEXCOORD; float4 color : COLOR; }; struct VertexOutput { float4 vpos : SV_POSITION; float4 uv : TEXCOORD; float4 color : COLOR; }; /////////////////////////////////////////////////////////////////////////////// // Line/point drawing: /////////////////////////////////////////////////////////////////////////////// VertexOutput VS_LinePoint(VertexInput input) { VertexOutput output; output.vpos = mul(input.pos, mvpMatrix); output.uv = input.uv; output.color = input.color; return output; } float4 PS_LinePoint(VertexOutput input) : SV_TARGET { return input.color; } /////////////////////////////////////////////////////////////////////////////// // Text glyphs drawing: /////////////////////////////////////////////////////////////////////////////// VertexOutput VS_TextGlyph(VertexInput input) { // Map to normalized clip coordinates: float x = ((2.0 * (input.pos.x - 0.5)) / screenDimensions.x) - 1.0; float y = 1.0 - ((2.0 * (input.pos.y - 0.5)) / screenDimensions.y); VertexOutput output; output.vpos = float4(x, y, 0.0, 1.0); output.uv = input.uv; output.color = input.color; return output; } float4 PS_TextGlyph(VertexOutput input) : SV_TARGET { float4 texColor = glyphsTexture.Sample(glyphsSampler, input.uv.xy); float4 fragColor = input.color; fragColor.a = texColor.r; return fragColor; } /////////////////////////////////////////////////////////////////////////////// ================================================ FILE: samples/vs2015/ddSampleGLCore/ddSampleGLCore.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ddSampleGLCore", "ddSampleGLCore.vcxproj", "{44AFAFA2-2597-49F5-A8FC-FB49783C8864}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x64.ActiveCfg = Debug|x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x64.Build.0 = Debug|x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x86.ActiveCfg = Debug|Win32 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x86.Build.0 = Debug|Win32 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x64.ActiveCfg = Release|x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x64.Build.0 = Release|x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x86.ActiveCfg = Release|Win32 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: samples/vs2015/ddSampleGLCore/ddSampleGLCore.vcxproj ================================================  Debug Win32 Release Win32 Debug x64 Release x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864} Win32Proj ddSampleGLCore 8.1 Application true v140 Unicode Application false v140 true Unicode Application true v140 Unicode Application false v140 true Unicode true $(SolutionDir)..\..\;$(SolutionDir)..\..\..\;$(SolutionDir)..\..\vectormath\;$(SolutionDir)..\..\gl3w\include\;$(SolutionDir)..\glfw-3.2-WIN32\include\;$(IncludePath) true $(SolutionDir)..\..\;$(SolutionDir)..\..\..\;$(SolutionDir)..\..\vectormath\;$(SolutionDir)..\..\gl3w\include\;$(SolutionDir)..\glfw-3.2-WIN64\include\;$(IncludePath) false $(SolutionDir)..\..\;$(SolutionDir)..\..\..\;$(SolutionDir)..\..\vectormath\;$(SolutionDir)..\..\gl3w\include\;$(SolutionDir)..\glfw-3.2-WIN32\include\;$(IncludePath) false $(SolutionDir)..\..\;$(SolutionDir)..\..\..\;$(SolutionDir)..\..\vectormath\;$(SolutionDir)..\..\gl3w\include\;$(SolutionDir)..\glfw-3.2-WIN64\include\;$(IncludePath) Level4 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true $(SolutionDir)..\glfw-3.2-WIN32\lib-vc2015;%(AdditionalLibraryDirectories) glfw3.lib;opengl32.lib;%(AdditionalDependencies) Level4 Disabled _DEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true $(SolutionDir)..\glfw-3.2-WIN64\lib-vc2015\;%(AdditionalLibraryDirectories) glfw3.lib;opengl32.lib;%(AdditionalDependencies) Level4 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true true true $(SolutionDir)..\glfw-3.2-WIN32\lib-vc2015;%(AdditionalLibraryDirectories) glfw3.lib;opengl32.lib;%(AdditionalDependencies) Level4 MaxSpeed true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true true true $(SolutionDir)..\glfw-3.2-WIN64\lib-vc2015\;%(AdditionalLibraryDirectories) glfw3.lib;opengl32.lib;%(AdditionalDependencies) ================================================ FILE: samples/vs2015/ddSampleGLCore/ddSampleGLCore.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Source Files ================================================ FILE: samples/vs2015/ddSampleGLLegacy/ddSampleGLCore.vcxproj ================================================  Debug Win32 Release Win32 Debug x64 Release x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864} Win32Proj ddSampleGLCore 8.1 ddSampleGLLegacy Application true v140 Unicode Application false v140 true Unicode Application true v140 Unicode Application false v140 true Unicode true $(SolutionDir)..\..\;$(SolutionDir)..\..\..\;$(SolutionDir)..\..\vectormath\;$(SolutionDir)..\..\gl3w\include\;$(SolutionDir)..\glfw-3.2-WIN32\include\;$(IncludePath) true $(SolutionDir)..\..\;$(SolutionDir)..\..\..\;$(SolutionDir)..\..\vectormath\;$(SolutionDir)..\..\gl3w\include\;$(SolutionDir)..\glfw-3.2-WIN64\include\;$(IncludePath) false $(SolutionDir)..\..\;$(SolutionDir)..\..\..\;$(SolutionDir)..\..\vectormath\;$(SolutionDir)..\..\gl3w\include\;$(SolutionDir)..\glfw-3.2-WIN32\include\;$(IncludePath) false $(SolutionDir)..\..\;$(SolutionDir)..\..\..\;$(SolutionDir)..\..\vectormath\;$(SolutionDir)..\..\gl3w\include\;$(SolutionDir)..\glfw-3.2-WIN64\include\;$(IncludePath) Level4 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true $(SolutionDir)..\glfw-3.2-WIN32\lib-vc2015;%(AdditionalLibraryDirectories) glfw3.lib;opengl32.lib;%(AdditionalDependencies) Level4 Disabled _DEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true $(SolutionDir)..\glfw-3.2-WIN64\lib-vc2015\;%(AdditionalLibraryDirectories) glfw3.lib;opengl32.lib;%(AdditionalDependencies) Level4 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true true true $(SolutionDir)..\glfw-3.2-WIN32\lib-vc2015;%(AdditionalLibraryDirectories) glfw3.lib;opengl32.lib;%(AdditionalDependencies) Level4 MaxSpeed true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true true true $(SolutionDir)..\glfw-3.2-WIN64\lib-vc2015\;%(AdditionalLibraryDirectories) glfw3.lib;opengl32.lib;%(AdditionalDependencies) ================================================ FILE: samples/vs2015/ddSampleGLLegacy/ddSampleGLCore.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files ================================================ FILE: samples/vs2015/ddSampleGLLegacy/ddSampleGLLegacy.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ddSampleGLCore", "ddSampleGLCore.vcxproj", "{44AFAFA2-2597-49F5-A8FC-FB49783C8864}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x64.ActiveCfg = Debug|x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x64.Build.0 = Debug|x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x86.ActiveCfg = Debug|Win32 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Debug|x86.Build.0 = Debug|Win32 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x64.ActiveCfg = Release|x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x64.Build.0 = Release|x64 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x86.ActiveCfg = Release|Win32 {44AFAFA2-2597-49F5-A8FC-FB49783C8864}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: samples/vs2015/ddSampleNullRenderer/ddSampleNullRenderer.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ddSampleNullRenderer", "ddSampleNullRenderer.vcxproj", "{362616A9-7C5B-428B-B2EF-3350A7961F81}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x64.ActiveCfg = Debug|x64 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x64.Build.0 = Debug|x64 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x86.ActiveCfg = Debug|Win32 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Debug|x86.Build.0 = Debug|Win32 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x64.ActiveCfg = Release|x64 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x64.Build.0 = Release|x64 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x86.ActiveCfg = Release|Win32 {362616A9-7C5B-428B-B2EF-3350A7961F81}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: samples/vs2015/ddSampleNullRenderer/ddSampleNullRenderer.vcxproj ================================================  Debug Win32 Release Win32 Debug x64 Release x64 {362616A9-7C5B-428B-B2EF-3350A7961F81} Win32Proj ddSampleNullRenderer 8.1 Application true v140 Unicode Application false v140 true Unicode Application true v140 Unicode Application false v140 true Unicode true $(SolutionDir)..\..\..\;$(IncludePath) true $(SolutionDir)..\..\..\;$(IncludePath) false $(SolutionDir)..\..\..\;$(IncludePath) false $(SolutionDir)..\..\..\;$(IncludePath) Level4 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true Level4 Disabled _DEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true Level4 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true true true Level4 MaxSpeed true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) Console true true true ================================================ FILE: samples/vs2015/ddSampleNullRenderer/ddSampleNullRenderer.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files ================================================ FILE: samples/vs2015/glfw-3.2-WIN32/COPYING.txt ================================================ Copyright (c) 2002-2006 Marcus Geelnard Copyright (c) 2006-2016 Camilla Berglund This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: samples/vs2015/glfw-3.2-WIN32/include/GLFW/glfw3.h ================================================ /************************************************************************* * GLFW 3.2 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard * Copyright (c) 2006-2016 Camilla Berglund * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would * be appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. * *************************************************************************/ #ifndef _glfw3_h_ #define _glfw3_h_ #ifdef __cplusplus extern "C" { #endif /************************************************************************* * Doxygen documentation *************************************************************************/ /*! @file glfw3.h * @brief The header of the GLFW 3 API. * * This is the header file of the GLFW 3 API. It defines all its types and * declares all its functions. * * For more information about how to use this file, see @ref build_include. */ /*! @defgroup context Context reference * * This is the reference documentation for OpenGL and OpenGL ES context related * functions. For more task-oriented information, see the @ref context_guide. */ /*! @defgroup vulkan Vulkan reference * * This is the reference documentation for Vulkan related functions and types. * For more task-oriented information, see the @ref vulkan_guide. */ /*! @defgroup init Initialization, version and error reference * * This is the reference documentation for initialization and termination of * the library, version management and error handling. For more task-oriented * information, see the @ref intro_guide. */ /*! @defgroup input Input reference * * This is the reference documentation for input related functions and types. * For more task-oriented information, see the @ref input_guide. */ /*! @defgroup monitor Monitor reference * * This is the reference documentation for monitor related functions and types. * For more task-oriented information, see the @ref monitor_guide. */ /*! @defgroup window Window reference * * This is the reference documentation for window related functions and types, * including creation, deletion and event polling. For more task-oriented * information, see the @ref window_guide. */ /************************************************************************* * Compiler- and platform-specific preprocessor work *************************************************************************/ /* If we are we on Windows, we want a single define for it. */ #if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)) #define _WIN32 #endif /* _WIN32 */ /* It is customary to use APIENTRY for OpenGL function pointer declarations on * all platforms. Additionally, the Windows OpenGL header needs APIENTRY. */ #ifndef APIENTRY #ifdef _WIN32 #define APIENTRY __stdcall #else #define APIENTRY #endif #endif /* APIENTRY */ /* Some Windows OpenGL headers need this. */ #if !defined(WINGDIAPI) && defined(_WIN32) #define WINGDIAPI __declspec(dllimport) #define GLFW_WINGDIAPI_DEFINED #endif /* WINGDIAPI */ /* Some Windows GLU headers need this. */ #if !defined(CALLBACK) && defined(_WIN32) #define CALLBACK __stdcall #define GLFW_CALLBACK_DEFINED #endif /* CALLBACK */ /* Most Windows GLU headers need wchar_t. * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h. * Include it unconditionally to avoid surprising side-effects. */ #include #include /* Include the chosen client API headers. */ #if defined(__APPLE__) #if defined(GLFW_INCLUDE_GLCOREARB) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif !defined(GLFW_INCLUDE_NONE) #if !defined(GLFW_INCLUDE_GLEXT) #define GL_GLEXT_LEGACY #endif #include #endif #if defined(GLFW_INCLUDE_GLU) #include #endif #else #if defined(GLFW_INCLUDE_GLCOREARB) #include #elif defined(GLFW_INCLUDE_ES1) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif defined(GLFW_INCLUDE_ES2) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif defined(GLFW_INCLUDE_ES3) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif defined(GLFW_INCLUDE_ES31) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif defined(GLFW_INCLUDE_VULKAN) #include #elif !defined(GLFW_INCLUDE_NONE) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #endif #if defined(GLFW_INCLUDE_GLU) #include #endif #endif #if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) /* GLFW_DLL must be defined by applications that are linking against the DLL * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW * configuration header when compiling the DLL version of the library. */ #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined" #endif /* GLFWAPI is used to declare public API functions for export * from the DLL / shared library / dynamic library. */ #if defined(_WIN32) && defined(_GLFW_BUILD_DLL) /* We are building GLFW as a Win32 DLL */ #define GLFWAPI __declspec(dllexport) #elif defined(_WIN32) && defined(GLFW_DLL) /* We are calling GLFW as a Win32 DLL */ #define GLFWAPI __declspec(dllimport) #elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) /* We are building GLFW as a shared / dynamic library */ #define GLFWAPI __attribute__((visibility("default"))) #else /* We are building or calling GLFW as a static library */ #define GLFWAPI #endif /************************************************************************* * GLFW API tokens *************************************************************************/ /*! @name GLFW version macros * @{ */ /*! @brief The major version number of the GLFW library. * * This is incremented when the API is changed in non-compatible ways. * @ingroup init */ #define GLFW_VERSION_MAJOR 3 /*! @brief The minor version number of the GLFW library. * * This is incremented when features are added to the API but it remains * backward-compatible. * @ingroup init */ #define GLFW_VERSION_MINOR 2 /*! @brief The revision number of the GLFW library. * * This is incremented when a bug fix release is made that does not contain any * API changes. * @ingroup init */ #define GLFW_VERSION_REVISION 0 /*! @} */ /*! @name Boolean values * @{ */ /*! @brief One. * * One. Seriously. You don't _need_ to use this symbol in your code. It's * just semantic sugar for the number 1. You can use `1` or `true` or `_True` * or `GL_TRUE` or whatever you want. */ #define GLFW_TRUE 1 /*! @brief Zero. * * Zero. Seriously. You don't _need_ to use this symbol in your code. It's * just just semantic sugar for the number 0. You can use `0` or `false` or * `_False` or `GL_FALSE` or whatever you want. */ #define GLFW_FALSE 0 /*! @} */ /*! @name Key and button actions * @{ */ /*! @brief The key or mouse button was released. * * The key or mouse button was released. * * @ingroup input */ #define GLFW_RELEASE 0 /*! @brief The key or mouse button was pressed. * * The key or mouse button was pressed. * * @ingroup input */ #define GLFW_PRESS 1 /*! @brief The key was held down until it repeated. * * The key was held down until it repeated. * * @ingroup input */ #define GLFW_REPEAT 2 /*! @} */ /*! @defgroup keys Keyboard keys * * See [key input](@ref input_key) for how these are used. * * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60), * but re-arranged to map to 7-bit ASCII for printable keys (function keys are * put in the 256+ range). * * The naming of the key codes follow these rules: * - The US keyboard layout is used * - Names of printable alpha-numeric characters are used (e.g. "A", "R", * "3", etc.) * - For non-alphanumeric characters, Unicode:ish names are used (e.g. * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not * correspond to the Unicode standard (usually for brevity) * - Keys that lack a clear US mapping are named "WORLD_x" * - For non-printable keys, custom names are used (e.g. "F4", * "BACKSPACE", etc.) * * @ingroup input * @{ */ /* The unknown key */ #define GLFW_KEY_UNKNOWN -1 /* Printable keys */ #define GLFW_KEY_SPACE 32 #define GLFW_KEY_APOSTROPHE 39 /* ' */ #define GLFW_KEY_COMMA 44 /* , */ #define GLFW_KEY_MINUS 45 /* - */ #define GLFW_KEY_PERIOD 46 /* . */ #define GLFW_KEY_SLASH 47 /* / */ #define GLFW_KEY_0 48 #define GLFW_KEY_1 49 #define GLFW_KEY_2 50 #define GLFW_KEY_3 51 #define GLFW_KEY_4 52 #define GLFW_KEY_5 53 #define GLFW_KEY_6 54 #define GLFW_KEY_7 55 #define GLFW_KEY_8 56 #define GLFW_KEY_9 57 #define GLFW_KEY_SEMICOLON 59 /* ; */ #define GLFW_KEY_EQUAL 61 /* = */ #define GLFW_KEY_A 65 #define GLFW_KEY_B 66 #define GLFW_KEY_C 67 #define GLFW_KEY_D 68 #define GLFW_KEY_E 69 #define GLFW_KEY_F 70 #define GLFW_KEY_G 71 #define GLFW_KEY_H 72 #define GLFW_KEY_I 73 #define GLFW_KEY_J 74 #define GLFW_KEY_K 75 #define GLFW_KEY_L 76 #define GLFW_KEY_M 77 #define GLFW_KEY_N 78 #define GLFW_KEY_O 79 #define GLFW_KEY_P 80 #define GLFW_KEY_Q 81 #define GLFW_KEY_R 82 #define GLFW_KEY_S 83 #define GLFW_KEY_T 84 #define GLFW_KEY_U 85 #define GLFW_KEY_V 86 #define GLFW_KEY_W 87 #define GLFW_KEY_X 88 #define GLFW_KEY_Y 89 #define GLFW_KEY_Z 90 #define GLFW_KEY_LEFT_BRACKET 91 /* [ */ #define GLFW_KEY_BACKSLASH 92 /* \ */ #define GLFW_KEY_RIGHT_BRACKET 93 /* ] */ #define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ #define GLFW_KEY_WORLD_1 161 /* non-US #1 */ #define GLFW_KEY_WORLD_2 162 /* non-US #2 */ /* Function keys */ #define GLFW_KEY_ESCAPE 256 #define GLFW_KEY_ENTER 257 #define GLFW_KEY_TAB 258 #define GLFW_KEY_BACKSPACE 259 #define GLFW_KEY_INSERT 260 #define GLFW_KEY_DELETE 261 #define GLFW_KEY_RIGHT 262 #define GLFW_KEY_LEFT 263 #define GLFW_KEY_DOWN 264 #define GLFW_KEY_UP 265 #define GLFW_KEY_PAGE_UP 266 #define GLFW_KEY_PAGE_DOWN 267 #define GLFW_KEY_HOME 268 #define GLFW_KEY_END 269 #define GLFW_KEY_CAPS_LOCK 280 #define GLFW_KEY_SCROLL_LOCK 281 #define GLFW_KEY_NUM_LOCK 282 #define GLFW_KEY_PRINT_SCREEN 283 #define GLFW_KEY_PAUSE 284 #define GLFW_KEY_F1 290 #define GLFW_KEY_F2 291 #define GLFW_KEY_F3 292 #define GLFW_KEY_F4 293 #define GLFW_KEY_F5 294 #define GLFW_KEY_F6 295 #define GLFW_KEY_F7 296 #define GLFW_KEY_F8 297 #define GLFW_KEY_F9 298 #define GLFW_KEY_F10 299 #define GLFW_KEY_F11 300 #define GLFW_KEY_F12 301 #define GLFW_KEY_F13 302 #define GLFW_KEY_F14 303 #define GLFW_KEY_F15 304 #define GLFW_KEY_F16 305 #define GLFW_KEY_F17 306 #define GLFW_KEY_F18 307 #define GLFW_KEY_F19 308 #define GLFW_KEY_F20 309 #define GLFW_KEY_F21 310 #define GLFW_KEY_F22 311 #define GLFW_KEY_F23 312 #define GLFW_KEY_F24 313 #define GLFW_KEY_F25 314 #define GLFW_KEY_KP_0 320 #define GLFW_KEY_KP_1 321 #define GLFW_KEY_KP_2 322 #define GLFW_KEY_KP_3 323 #define GLFW_KEY_KP_4 324 #define GLFW_KEY_KP_5 325 #define GLFW_KEY_KP_6 326 #define GLFW_KEY_KP_7 327 #define GLFW_KEY_KP_8 328 #define GLFW_KEY_KP_9 329 #define GLFW_KEY_KP_DECIMAL 330 #define GLFW_KEY_KP_DIVIDE 331 #define GLFW_KEY_KP_MULTIPLY 332 #define GLFW_KEY_KP_SUBTRACT 333 #define GLFW_KEY_KP_ADD 334 #define GLFW_KEY_KP_ENTER 335 #define GLFW_KEY_KP_EQUAL 336 #define GLFW_KEY_LEFT_SHIFT 340 #define GLFW_KEY_LEFT_CONTROL 341 #define GLFW_KEY_LEFT_ALT 342 #define GLFW_KEY_LEFT_SUPER 343 #define GLFW_KEY_RIGHT_SHIFT 344 #define GLFW_KEY_RIGHT_CONTROL 345 #define GLFW_KEY_RIGHT_ALT 346 #define GLFW_KEY_RIGHT_SUPER 347 #define GLFW_KEY_MENU 348 #define GLFW_KEY_LAST GLFW_KEY_MENU /*! @} */ /*! @defgroup mods Modifier key flags * * See [key input](@ref input_key) for how these are used. * * @ingroup input * @{ */ /*! @brief If this bit is set one or more Shift keys were held down. */ #define GLFW_MOD_SHIFT 0x0001 /*! @brief If this bit is set one or more Control keys were held down. */ #define GLFW_MOD_CONTROL 0x0002 /*! @brief If this bit is set one or more Alt keys were held down. */ #define GLFW_MOD_ALT 0x0004 /*! @brief If this bit is set one or more Super keys were held down. */ #define GLFW_MOD_SUPER 0x0008 /*! @} */ /*! @defgroup buttons Mouse buttons * * See [mouse button input](@ref input_mouse_button) for how these are used. * * @ingroup input * @{ */ #define GLFW_MOUSE_BUTTON_1 0 #define GLFW_MOUSE_BUTTON_2 1 #define GLFW_MOUSE_BUTTON_3 2 #define GLFW_MOUSE_BUTTON_4 3 #define GLFW_MOUSE_BUTTON_5 4 #define GLFW_MOUSE_BUTTON_6 5 #define GLFW_MOUSE_BUTTON_7 6 #define GLFW_MOUSE_BUTTON_8 7 #define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8 #define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1 #define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2 #define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3 /*! @} */ /*! @defgroup joysticks Joysticks * * See [joystick input](@ref joystick) for how these are used. * * @ingroup input * @{ */ #define GLFW_JOYSTICK_1 0 #define GLFW_JOYSTICK_2 1 #define GLFW_JOYSTICK_3 2 #define GLFW_JOYSTICK_4 3 #define GLFW_JOYSTICK_5 4 #define GLFW_JOYSTICK_6 5 #define GLFW_JOYSTICK_7 6 #define GLFW_JOYSTICK_8 7 #define GLFW_JOYSTICK_9 8 #define GLFW_JOYSTICK_10 9 #define GLFW_JOYSTICK_11 10 #define GLFW_JOYSTICK_12 11 #define GLFW_JOYSTICK_13 12 #define GLFW_JOYSTICK_14 13 #define GLFW_JOYSTICK_15 14 #define GLFW_JOYSTICK_16 15 #define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16 /*! @} */ /*! @defgroup errors Error codes * * See [error handling](@ref error_handling) for how these are used. * * @ingroup init * @{ */ /*! @brief GLFW has not been initialized. * * This occurs if a GLFW function was called that must not be called unless the * library is [initialized](@ref intro_init). * * @analysis Application programmer error. Initialize GLFW before calling any * function that requires initialization. */ #define GLFW_NOT_INITIALIZED 0x00010001 /*! @brief No context is current for this thread. * * This occurs if a GLFW function was called that needs and operates on the * current OpenGL or OpenGL ES context but no context is current on the calling * thread. One such function is @ref glfwSwapInterval. * * @analysis Application programmer error. Ensure a context is current before * calling functions that require a current context. */ #define GLFW_NO_CURRENT_CONTEXT 0x00010002 /*! @brief One of the arguments to the function was an invalid enum value. * * One of the arguments to the function was an invalid enum value, for example * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref * glfwGetWindowAttrib. * * @analysis Application programmer error. Fix the offending call. */ #define GLFW_INVALID_ENUM 0x00010003 /*! @brief One of the arguments to the function was an invalid value. * * One of the arguments to the function was an invalid value, for example * requesting a non-existent OpenGL or OpenGL ES version like 2.7. * * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead * result in a @ref GLFW_VERSION_UNAVAILABLE error. * * @analysis Application programmer error. Fix the offending call. */ #define GLFW_INVALID_VALUE 0x00010004 /*! @brief A memory allocation failed. * * A memory allocation failed. * * @analysis A bug in GLFW or the underlying operating system. Report the bug * to our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_OUT_OF_MEMORY 0x00010005 /*! @brief GLFW could not find support for the requested API on the system. * * GLFW could not find support for the requested API on the system. * * @analysis The installed graphics driver does not support the requested * API, or does not support it via the chosen context creation backend. * Below are a few examples. * * @par * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only * supports OpenGL ES via EGL, while Nvidia and Intel only support it via * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary * driver. Older graphics drivers do not support Vulkan. */ #define GLFW_API_UNAVAILABLE 0x00010006 /*! @brief The requested OpenGL or OpenGL ES version is not available. * * The requested OpenGL or OpenGL ES version (including any requested context * or framebuffer hints) is not available on this machine. * * @analysis The machine does not support your requirements. If your * application is sufficiently flexible, downgrade your requirements and try * again. Otherwise, inform the user that their machine does not match your * requirements. * * @par * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 * comes out before the 4.x series gets that far, also fail with this error and * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions * will exist. */ #define GLFW_VERSION_UNAVAILABLE 0x00010007 /*! @brief A platform-specific error occurred that does not match any of the * more specific categories. * * A platform-specific error occurred that does not match any of the more * specific categories. * * @analysis A bug or configuration error in GLFW, the underlying operating * system or its drivers, or a lack of required resources. Report the issue to * our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_PLATFORM_ERROR 0x00010008 /*! @brief The requested format is not supported or available. * * If emitted during window creation, the requested pixel format is not * supported. * * If emitted when querying the clipboard, the contents of the clipboard could * not be converted to the requested format. * * @analysis If emitted during window creation, one or more * [hard constraints](@ref window_hints_hard) did not match any of the * available pixel formats. If your application is sufficiently flexible, * downgrade your requirements and try again. Otherwise, inform the user that * their machine does not match your requirements. * * @par * If emitted when querying the clipboard, ignore the error or report it to * the user, as appropriate. */ #define GLFW_FORMAT_UNAVAILABLE 0x00010009 /*! @brief The specified window does not have an OpenGL or OpenGL ES context. * * A window that does not have an OpenGL or OpenGL ES context was passed to * a function that requires it to have one. * * @analysis Application programmer error. Fix the offending call. */ #define GLFW_NO_WINDOW_CONTEXT 0x0001000A /*! @} */ #define GLFW_FOCUSED 0x00020001 #define GLFW_ICONIFIED 0x00020002 #define GLFW_RESIZABLE 0x00020003 #define GLFW_VISIBLE 0x00020004 #define GLFW_DECORATED 0x00020005 #define GLFW_AUTO_ICONIFY 0x00020006 #define GLFW_FLOATING 0x00020007 #define GLFW_MAXIMIZED 0x00020008 #define GLFW_RED_BITS 0x00021001 #define GLFW_GREEN_BITS 0x00021002 #define GLFW_BLUE_BITS 0x00021003 #define GLFW_ALPHA_BITS 0x00021004 #define GLFW_DEPTH_BITS 0x00021005 #define GLFW_STENCIL_BITS 0x00021006 #define GLFW_ACCUM_RED_BITS 0x00021007 #define GLFW_ACCUM_GREEN_BITS 0x00021008 #define GLFW_ACCUM_BLUE_BITS 0x00021009 #define GLFW_ACCUM_ALPHA_BITS 0x0002100A #define GLFW_AUX_BUFFERS 0x0002100B #define GLFW_STEREO 0x0002100C #define GLFW_SAMPLES 0x0002100D #define GLFW_SRGB_CAPABLE 0x0002100E #define GLFW_REFRESH_RATE 0x0002100F #define GLFW_DOUBLEBUFFER 0x00021010 #define GLFW_CLIENT_API 0x00022001 #define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 #define GLFW_CONTEXT_VERSION_MINOR 0x00022003 #define GLFW_CONTEXT_REVISION 0x00022004 #define GLFW_CONTEXT_ROBUSTNESS 0x00022005 #define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 #define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 #define GLFW_OPENGL_PROFILE 0x00022008 #define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 #define GLFW_CONTEXT_NO_ERROR 0x0002200A #define GLFW_CONTEXT_CREATION_API 0x0002200B #define GLFW_NO_API 0 #define GLFW_OPENGL_API 0x00030001 #define GLFW_OPENGL_ES_API 0x00030002 #define GLFW_NO_ROBUSTNESS 0 #define GLFW_NO_RESET_NOTIFICATION 0x00031001 #define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002 #define GLFW_OPENGL_ANY_PROFILE 0 #define GLFW_OPENGL_CORE_PROFILE 0x00032001 #define GLFW_OPENGL_COMPAT_PROFILE 0x00032002 #define GLFW_CURSOR 0x00033001 #define GLFW_STICKY_KEYS 0x00033002 #define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 #define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_HIDDEN 0x00034002 #define GLFW_CURSOR_DISABLED 0x00034003 #define GLFW_ANY_RELEASE_BEHAVIOR 0 #define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 #define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002 #define GLFW_NATIVE_CONTEXT_API 0x00036001 #define GLFW_EGL_CONTEXT_API 0x00036002 /*! @defgroup shapes Standard cursor shapes * * See [standard cursor creation](@ref cursor_standard) for how these are used. * * @ingroup input * @{ */ /*! @brief The regular arrow cursor shape. * * The regular arrow cursor. */ #define GLFW_ARROW_CURSOR 0x00036001 /*! @brief The text input I-beam cursor shape. * * The text input I-beam cursor shape. */ #define GLFW_IBEAM_CURSOR 0x00036002 /*! @brief The crosshair shape. * * The crosshair shape. */ #define GLFW_CROSSHAIR_CURSOR 0x00036003 /*! @brief The hand shape. * * The hand shape. */ #define GLFW_HAND_CURSOR 0x00036004 /*! @brief The horizontal resize arrow shape. * * The horizontal resize arrow shape. */ #define GLFW_HRESIZE_CURSOR 0x00036005 /*! @brief The vertical resize arrow shape. * * The vertical resize arrow shape. */ #define GLFW_VRESIZE_CURSOR 0x00036006 /*! @} */ #define GLFW_CONNECTED 0x00040001 #define GLFW_DISCONNECTED 0x00040002 #define GLFW_DONT_CARE -1 /************************************************************************* * GLFW API types *************************************************************************/ /*! @brief Client API function pointer type. * * Generic function pointer used for returning client API function pointers * without forcing a cast from a regular pointer. * * @sa @ref context_glext * @sa glfwGetProcAddress * * @since Added in version 3.0. * @ingroup context */ typedef void (*GLFWglproc)(void); /*! @brief Vulkan API function pointer type. * * Generic function pointer used for returning Vulkan API function pointers * without forcing a cast from a regular pointer. * * @sa @ref vulkan_proc * @sa glfwGetInstanceProcAddress * * @since Added in version 3.2. * * @ingroup vulkan */ typedef void (*GLFWvkproc)(void); /*! @brief Opaque monitor object. * * Opaque monitor object. * * @see @ref monitor_object * * @since Added in version 3.0. * * @ingroup monitor */ typedef struct GLFWmonitor GLFWmonitor; /*! @brief Opaque window object. * * Opaque window object. * * @see @ref window_object * * @since Added in version 3.0. * * @ingroup window */ typedef struct GLFWwindow GLFWwindow; /*! @brief Opaque cursor object. * * Opaque cursor object. * * @see @ref cursor_object * * @since Added in version 3.1. * * @ingroup cursor */ typedef struct GLFWcursor GLFWcursor; /*! @brief The function signature for error callbacks. * * This is the function signature for error callback functions. * * @param[in] error An [error code](@ref errors). * @param[in] description A UTF-8 encoded string describing the error. * * @sa @ref error_handling * @sa glfwSetErrorCallback * * @since Added in version 3.0. * * @ingroup init */ typedef void (* GLFWerrorfun)(int,const char*); /*! @brief The function signature for window position callbacks. * * This is the function signature for window position callback functions. * * @param[in] window The window that was moved. * @param[in] xpos The new x-coordinate, in screen coordinates, of the * upper-left corner of the client area of the window. * @param[in] ypos The new y-coordinate, in screen coordinates, of the * upper-left corner of the client area of the window. * * @sa @ref window_pos * @sa glfwSetWindowPosCallback * * @since Added in version 3.0. * * @ingroup window */ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); /*! @brief The function signature for window resize callbacks. * * This is the function signature for window size callback functions. * * @param[in] window The window that was resized. * @param[in] width The new width, in screen coordinates, of the window. * @param[in] height The new height, in screen coordinates, of the window. * * @sa @ref window_size * @sa glfwSetWindowSizeCallback * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); /*! @brief The function signature for window close callbacks. * * This is the function signature for window close callback functions. * * @param[in] window The window that the user attempted to close. * * @sa @ref window_close * @sa glfwSetWindowCloseCallback * * @since Added in version 2.5. * @glfw3 Added window handle parameter. * * @ingroup window */ typedef void (* GLFWwindowclosefun)(GLFWwindow*); /*! @brief The function signature for window content refresh callbacks. * * This is the function signature for window refresh callback functions. * * @param[in] window The window whose content needs to be refreshed. * * @sa @ref window_refresh * @sa glfwSetWindowRefreshCallback * * @since Added in version 2.5. * @glfw3 Added window handle parameter. * * @ingroup window */ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); /*! @brief The function signature for window focus/defocus callbacks. * * This is the function signature for window focus callback functions. * * @param[in] window The window that gained or lost input focus. * @param[in] focused `GLFW_TRUE` if the window was given input focus, or * `GLFW_FALSE` if it lost it. * * @sa @ref window_focus * @sa glfwSetWindowFocusCallback * * @since Added in version 3.0. * * @ingroup window */ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); /*! @brief The function signature for window iconify/restore callbacks. * * This is the function signature for window iconify/restore callback * functions. * * @param[in] window The window that was iconified or restored. * @param[in] iconified `GLFW_TRUE` if the window was iconified, or * `GLFW_FALSE` if it was restored. * * @sa @ref window_iconify * @sa glfwSetWindowIconifyCallback * * @since Added in version 3.0. * * @ingroup window */ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); /*! @brief The function signature for framebuffer resize callbacks. * * This is the function signature for framebuffer resize callback * functions. * * @param[in] window The window whose framebuffer was resized. * @param[in] width The new width, in pixels, of the framebuffer. * @param[in] height The new height, in pixels, of the framebuffer. * * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * * @since Added in version 3.0. * * @ingroup window */ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); /*! @brief The function signature for mouse button callbacks. * * This is the function signature for mouse button callback functions. * * @param[in] window The window that received the event. * @param[in] button The [mouse button](@ref buttons) that was pressed or * released. * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * * @sa @ref input_mouse_button * @sa glfwSetMouseButtonCallback * * @since Added in version 1.0. * @glfw3 Added window handle and modifier mask parameters. * * @ingroup input */ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); /*! @brief The function signature for cursor position callbacks. * * This is the function signature for cursor position callback functions. * * @param[in] window The window that received the event. * @param[in] xpos The new cursor x-coordinate, relative to the left edge of * the client area. * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the * client area. * * @sa @ref cursor_pos * @sa glfwSetCursorPosCallback * * @since Added in version 3.0. Replaces `GLFWmouseposfun`. * * @ingroup input */ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); /*! @brief The function signature for cursor enter/leave callbacks. * * This is the function signature for cursor enter/leave callback functions. * * @param[in] window The window that received the event. * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client * area, or `GLFW_FALSE` if it left it. * * @sa @ref cursor_enter * @sa glfwSetCursorEnterCallback * * @since Added in version 3.0. * * @ingroup input */ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); /*! @brief The function signature for scroll callbacks. * * This is the function signature for scroll callback functions. * * @param[in] window The window that received the event. * @param[in] xoffset The scroll offset along the x-axis. * @param[in] yoffset The scroll offset along the y-axis. * * @sa @ref scrolling * @sa glfwSetScrollCallback * * @since Added in version 3.0. Replaces `GLFWmousewheelfun`. * * @ingroup input */ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); /*! @brief The function signature for keyboard key callbacks. * * This is the function signature for keyboard key callback functions. * * @param[in] window The window that received the event. * @param[in] key The [keyboard key](@ref keys) that was pressed or released. * @param[in] scancode The system-specific scancode of the key. * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * * @sa @ref input_key * @sa glfwSetKeyCallback * * @since Added in version 1.0. * @glfw3 Added window handle, scancode and modifier mask parameters. * * @ingroup input */ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); /*! @brief The function signature for Unicode character callbacks. * * This is the function signature for Unicode character callback functions. * * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the character. * * @sa @ref input_char * @sa glfwSetCharCallback * * @since Added in version 2.4. * @glfw3 Added window handle parameter. * * @ingroup input */ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); /*! @brief The function signature for Unicode character with modifiers * callbacks. * * This is the function signature for Unicode character with modifiers callback * functions. It is called for each input character, regardless of what * modifier keys are held down. * * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the character. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * * @sa @ref input_char * @sa glfwSetCharModsCallback * * @since Added in version 3.1. * * @ingroup input */ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); /*! @brief The function signature for file drop callbacks. * * This is the function signature for file drop callbacks. * * @param[in] window The window that received the event. * @param[in] count The number of dropped files. * @param[in] paths The UTF-8 encoded file and/or directory path names. * * @sa @ref path_drop * @sa glfwSetDropCallback * * @since Added in version 3.1. * * @ingroup input */ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); /*! @brief The function signature for monitor configuration callbacks. * * This is the function signature for monitor configuration callback functions. * * @param[in] monitor The monitor that was connected or disconnected. * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. * * @sa @ref monitor_event * @sa glfwSetMonitorCallback * * @since Added in version 3.0. * * @ingroup monitor */ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); /*! @brief The function signature for joystick configuration callbacks. * * This is the function signature for joystick configuration callback * functions. * * @param[in] joy The joystick that was connected or disconnected. * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. * * @sa @ref joystick_event * @sa glfwSetJoystickCallback * * @since Added in version 3.2. * * @ingroup input */ typedef void (* GLFWjoystickfun)(int,int); /*! @brief Video mode type. * * This describes a single video mode. * * @sa @ref monitor_modes * @sa glfwGetVideoMode glfwGetVideoModes * * @since Added in version 1.0. * @glfw3 Added refresh rate member. * * @ingroup monitor */ typedef struct GLFWvidmode { /*! The width, in screen coordinates, of the video mode. */ int width; /*! The height, in screen coordinates, of the video mode. */ int height; /*! The bit depth of the red channel of the video mode. */ int redBits; /*! The bit depth of the green channel of the video mode. */ int greenBits; /*! The bit depth of the blue channel of the video mode. */ int blueBits; /*! The refresh rate, in Hz, of the video mode. */ int refreshRate; } GLFWvidmode; /*! @brief Gamma ramp. * * This describes the gamma ramp for a monitor. * * @sa @ref monitor_gamma * @sa glfwGetGammaRamp glfwSetGammaRamp * * @since Added in version 3.0. * * @ingroup monitor */ typedef struct GLFWgammaramp { /*! An array of value describing the response of the red channel. */ unsigned short* red; /*! An array of value describing the response of the green channel. */ unsigned short* green; /*! An array of value describing the response of the blue channel. */ unsigned short* blue; /*! The number of elements in each array. */ unsigned int size; } GLFWgammaramp; /*! @brief Image data. * * @sa @ref cursor_custom * * @since Added in version 2.1. * @glfw3 Removed format and bytes-per-pixel members. */ typedef struct GLFWimage { /*! The width, in pixels, of this image. */ int width; /*! The height, in pixels, of this image. */ int height; /*! The pixel data of this image, arranged left-to-right, top-to-bottom. */ unsigned char* pixels; } GLFWimage; /************************************************************************* * GLFW API functions *************************************************************************/ /*! @brief Initializes the GLFW library. * * This function initializes the GLFW library. Before most GLFW functions can * be used, GLFW must be initialized, and before an application terminates GLFW * should be terminated in order to free any resources allocated during or * after initialization. * * If this function fails, it calls @ref glfwTerminate before returning. If it * succeeds, you should call @ref glfwTerminate before the application exits. * * Additional calls to this function after successful initialization but before * termination will return `GLFW_TRUE` immediately. * * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. * * @remark @osx This function will change the current directory of the * application to the `Contents/Resources` subdirectory of the application's * bundle, if present. This can be disabled with a * [compile-time option](@ref compile_options_osx). * * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init * @sa glfwTerminate * * @since Added in version 1.0. * * @ingroup init */ GLFWAPI int glfwInit(void); /*! @brief Terminates the GLFW library. * * This function destroys all remaining windows and cursors, restores any * modified gamma ramps and frees any other allocated resources. Once this * function is called, you must again call @ref glfwInit successfully before * you will be able to use most GLFW functions. * * If GLFW has been successfully initialized, this function should be called * before the application exits. If initialization fails, there is no need to * call this function, as it is called by @ref glfwInit before it returns * failure. * * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. * * @remark This function may be called before @ref glfwInit. * * @warning The contexts of any remaining windows must not be current on any * other thread when this function is called. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init * @sa glfwInit * * @since Added in version 1.0. * * @ingroup init */ GLFWAPI void glfwTerminate(void); /*! @brief Retrieves the version of the GLFW library. * * This function retrieves the major, minor and revision numbers of the GLFW * library. It is intended for when you are using GLFW as a shared library and * want to ensure that you are using the minimum required version. * * Any or all of the version arguments may be `NULL`. * * @param[out] major Where to store the major version number, or `NULL`. * @param[out] minor Where to store the minor version number, or `NULL`. * @param[out] rev Where to store the revision number, or `NULL`. * * @errors None. * * @remark This function may be called before @ref glfwInit. * * @thread_safety This function may be called from any thread. * * @sa @ref intro_version * @sa glfwGetVersionString * * @since Added in version 1.0. * * @ingroup init */ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); /*! @brief Returns a string describing the compile-time configuration. * * This function returns the compile-time generated * [version string](@ref intro_version_string) of the GLFW library binary. It * describes the version, platform, compiler and any platform-specific * compile-time options. It should not be confused with the OpenGL or OpenGL * ES version string, queried with `glGetString`. * * __Do not use the version string__ to parse the GLFW library version. The * @ref glfwGetVersion function provides the version of the running library * binary in numerical format. * * @return The ASCII encoded GLFW version string. * * @errors None. * * @remark This function may be called before @ref glfwInit. * * @pointer_lifetime The returned string is static and compile-time generated. * * @thread_safety This function may be called from any thread. * * @sa @ref intro_version * @sa glfwGetVersion * * @since Added in version 3.0. * * @ingroup init */ GLFWAPI const char* glfwGetVersionString(void); /*! @brief Sets the error callback. * * This function sets the error callback, which is called with an error code * and a human-readable description each time a GLFW error occurs. * * The error callback is called on the thread where the error occurred. If you * are using GLFW from multiple threads, your error callback needs to be * written accordingly. * * Because the description string may have been generated specifically for that * error, it is not guaranteed to be valid after the callback has returned. If * you wish to use it after the callback returns, you need to make a copy. * * Once set, the error callback remains set even after the library has been * terminated. * * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set. * * @errors None. * * @remark This function may be called before @ref glfwInit. * * @thread_safety This function must only be called from the main thread. * * @sa @ref error_handling * * @since Added in version 3.0. * * @ingroup init */ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); /*! @brief Returns the currently connected monitors. * * This function returns an array of handles for all currently connected * monitors. The primary monitor is always first in the returned array. If no * monitors were found, this function returns `NULL`. * * @param[out] count Where to store the number of monitors in the returned * array. This is set to zero if an error occurred. * @return An array of monitor handles, or `NULL` if no monitors were found or * if an [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is guaranteed to be valid only until the * monitor configuration changes or the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_monitors * @sa @ref monitor_event * @sa glfwGetPrimaryMonitor * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); /*! @brief Returns the primary monitor. * * This function returns the primary monitor. This is usually the monitor * where elements like the task bar or global menu bar are located. * * @return The primary monitor, or `NULL` if no monitors were found or if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @remark The primary monitor is always first in the array returned by @ref * glfwGetMonitors. * * @sa @ref monitor_monitors * @sa glfwGetMonitors * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); /*! @brief Returns the position of the monitor's viewport on the virtual screen. * * This function returns the position, in screen coordinates, of the upper-left * corner of the specified monitor. * * Any or all of the position arguments may be `NULL`. If an error occurs, all * non-`NULL` position arguments will be set to zero. * * @param[in] monitor The monitor to query. * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); /*! @brief Returns the physical size of the monitor. * * This function returns the size, in millimetres, of the display area of the * specified monitor. * * Some systems do not provide accurate monitor size information, either * because the monitor * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data) * data is incorrect or because the driver does not report it accurately. * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. * * @param[in] monitor The monitor to query. * @param[out] widthMM Where to store the width, in millimetres, of the * monitor's display area, or `NULL`. * @param[out] heightMM Where to store the height, in millimetres, of the * monitor's display area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @remark @win32 calculates the returned physical size from the * current resolution and system DPI instead of querying the monitor EDID data. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM); /*! @brief Returns the name of the specified monitor. * * This function returns a human-readable name, encoded as UTF-8, of the * specified monitor. The name typically reflects the make and model of the * monitor and is not guaranteed to be unique among the connected monitors. * * @param[in] monitor The monitor to query. * @return The UTF-8 encoded name of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected or the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); /*! @brief Sets the monitor configuration callback. * * This function sets the monitor configuration callback, or removes the * currently set callback. This is called when a monitor is connected to or * disconnected from the system. * * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_event * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); /*! @brief Returns the available video modes for the specified monitor. * * This function returns an array of all video modes supported by the specified * monitor. The returned array is sorted in ascending order, first by color * bit depth (the sum of all channel depths) and then by resolution area (the * product of width and height). * * @param[in] monitor The monitor to query. * @param[out] count Where to store the number of video modes in the returned * array. This is set to zero if an error occurred. * @return An array of video modes, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected, this function is called again for that monitor or the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_modes * @sa glfwGetVideoMode * * @since Added in version 1.0. * @glfw3 Changed to return an array of modes for a specific monitor. * * @ingroup monitor */ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); /*! @brief Returns the current mode of the specified monitor. * * This function returns the current video mode of the specified monitor. If * you have created a full screen window for that monitor, the return value * will depend on whether that window is iconified. * * @param[in] monitor The monitor to query. * @return The current mode of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected or the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_modes * @sa glfwGetVideoModes * * @since Added in version 3.0. Replaces `glfwGetDesktopMode`. * * @ingroup monitor */ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); /*! @brief Generates a gamma ramp and sets it for the specified monitor. * * This function generates a 256-element gamma ramp from the specified exponent * and then calls @ref glfwSetGammaRamp with it. The value must be a finite * number greater than zero. * * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] gamma The desired exponent. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); /*! @brief Returns the current gamma ramp for the specified monitor. * * This function returns the current gamma ramp of the specified monitor. * * @param[in] monitor The monitor to query. * @return The current gamma ramp, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned structure and its arrays are allocated and * freed by GLFW. You should not free them yourself. They are valid until the * specified monitor is disconnected, this function is called again for that * monitor or the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); /*! @brief Sets the current gamma ramp for the specified monitor. * * This function sets the current gamma ramp for the specified monitor. The * original gamma ramp for that monitor is saved by GLFW the first time this * function is called and is restored by @ref glfwTerminate. * * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] ramp The gamma ramp to use. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @remark Gamma ramp sizes other than 256 are not supported by all platforms * or graphics hardware. * * @remark @win32 The gamma ramp size must be 256. * * @pointer_lifetime The specified gamma ramp is copied before this function * returns. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); /*! @brief Resets all window hints to their default values. * * This function resets all window hints to their * [default values](@ref window_hints_values). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints * @sa glfwWindowHint * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwDefaultWindowHints(void); /*! @brief Sets the specified window hint to the desired value. * * This function sets hints for the next call to @ref glfwCreateWindow. The * hints, once set, retain their values until changed by a call to @ref * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is * terminated. * * This function does not check whether the specified hint values are valid. * If you set hints to invalid values this will instead be reported by the next * call to @ref glfwCreateWindow. * * @param[in] hint The [window hint](@ref window_hints) to set. * @param[in] value The new value of the window hint. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints * @sa glfwDefaultWindowHints * * @since Added in version 3.0. Replaces `glfwOpenWindowHint`. * * @ingroup window */ GLFWAPI void glfwWindowHint(int hint, int value); /*! @brief Creates a window and its associated context. * * This function creates a window and its associated OpenGL or OpenGL ES * context. Most of the options controlling how the window and its context * should be created are specified with [window hints](@ref window_hints). * * Successful creation does not change which context is current. Before you * can use the newly created context, you need to * [make it current](@ref context_current). For information about the `share` * parameter, see @ref context_sharing. * * The created window, framebuffer and context may differ from what you * requested, as not all parameters and hints are * [hard constraints](@ref window_hints_hard). This includes the size of the * window, especially for full screen windows. To query the actual attributes * of the created window, framebuffer and context, see @ref * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. * * To create a full screen window, you need to specify the monitor the window * will cover. If no monitor is specified, the window will be windowed mode. * Unless you have a way for the user to choose a specific monitor, it is * recommended that you pick the primary monitor. For more information on how * to query connected monitors, see @ref monitor_monitors. * * For full screen windows, the specified size becomes the resolution of the * window's _desired video mode_. As long as a full screen window is not * iconified, the supported video mode most closely matching the desired video * mode is set for the specified monitor. For more information about full * screen windows, including the creation of so called _windowed full screen_ * or _borderless full screen_ windows, see @ref window_windowed_full_screen. * * By default, newly created windows use the placement recommended by the * window system. To create the window at a specific position, make it * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window * hint, set its [position](@ref window_pos) and then [show](@ref window_hide) * it. * * As long as at least one full screen window is not iconified, the screensaver * is prohibited from starting. * * Window systems put limits on window sizes. Very large or very small window * dimensions may be overridden by the window system on creation. Check the * actual [size](@ref window_size) after creation. * * The [swap interval](@ref buffer_swap) is not set during window creation and * the initial value may vary depending on driver settings and defaults. * * @param[in] width The desired width, in screen coordinates, of the window. * This must be greater than zero. * @param[in] height The desired height, in screen coordinates, of the window. * This must be greater than zero. * @param[in] title The initial, UTF-8 encoded window title. * @param[in] monitor The monitor to use for full screen mode, or `NULL` for * windowed mode. * @param[in] share The window whose context to share resources with, or `NULL` * to not share resources. * @return The handle of the created window, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref * GLFW_PLATFORM_ERROR. * * @remark @win32 Window creation will fail if the Microsoft GDI software * OpenGL implementation is the only one available. * * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it * will be set as the initial icon for the window. If no such icon is present, * the `IDI_WINLOGO` icon will be used instead. To set a different icon, see * @ref glfwSetWindowIcon. * * @remark @win32 The context to share resources with must not be current on * any other thread. * * @remark @osx The GLFW window has no icon, as it is not a document * window, but the dock icon will be the same as the application bundle's icon. * For more information on bundles, see the * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) * in the Mac Developer Library. * * @remark @osx The first time a window is created the menu bar is populated * with common commands like Hide, Quit and About. The About entry opens * a minimal about dialog with information from the application's bundle. The * menu bar can be disabled with a * [compile-time option](@ref compile_options_osx). * * @remark @osx On OS X 10.10 and later the window frame will not be rendered * at full resolution on Retina displays unless the `NSHighResolutionCapable` * key is enabled in the application bundle's `Info.plist`. For more * information, see * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html) * in the Mac Developer Library. The GLFW test and example programs use * a custom `Info.plist` template for this, which can be found as * `CMake/MacOSXBundleInfo.plist.in` in the source tree. * * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. * * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for * a window to reach its requested state. This means you may not be able to * query the final size, position or other attributes directly after window * creation. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation * @sa glfwDestroyWindow * * @since Added in version 3.0. Replaces `glfwOpenWindow`. * * @ingroup window */ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share); /*! @brief Destroys the specified window and its context. * * This function destroys the specified window and its context. On calling * this function, no further callbacks will be called for that window. * * If the context of the specified window is current on the main thread, it is * detached before being destroyed. * * @param[in] window The window to destroy. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @note The context of the specified window must not be current on any other * thread when this function is called. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation * @sa glfwCreateWindow * * @since Added in version 3.0. Replaces `glfwCloseWindow`. * * @ingroup window */ GLFWAPI void glfwDestroyWindow(GLFWwindow* window); /*! @brief Checks the close flag of the specified window. * * This function returns the value of the close flag of the specified window. * * @param[in] window The window to query. * @return The value of the close flag. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @sa @ref window_close * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); /*! @brief Sets the close flag of the specified window. * * This function sets the value of the close flag of the specified window. * This can be used to override the user's attempt to close the window, or * to signal that it should be closed. * * @param[in] window The window whose flag to change. * @param[in] value The new value. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @sa @ref window_close * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); /*! @brief Sets the title of the specified window. * * This function sets the window title, encoded as UTF-8, of the specified * window. * * @param[in] window The window whose title to change. * @param[in] title The UTF-8 encoded window title. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @remark @osx The window title will not be updated until the next time you * process events. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_title * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); /*! @brief Sets the icon for the specified window. * * This function sets the icon of the specified window. If passed an array of * candidate images, those of or closest to the sizes desired by the system are * selected. If no images are specified, the window reverts to its default * icon. * * The desired image sizes varies depending on platform and system settings. * The selected images will be rescaled as needed. Good sizes include 16x16, * 32x32 and 48x48. * * @param[in] window The window whose icon to set. * @param[in] count The number of images in the specified array, or zero to * revert to the default window icon. * @param[in] images The images to create the icon from. This is ignored if * count is zero. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified image data is copied before this function * returns. * * @remark @osx The GLFW window has no icon, as it is not a document * window, so this function does nothing. The dock icon will be the same as * the application bundle's icon. For more information on bundles, see the * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) * in the Mac Developer Library. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_icon * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); /*! @brief Retrieves the position of the client area of the specified window. * * This function retrieves the position, in screen coordinates, of the * upper-left corner of the client area of the specified window. * * Any or all of the position arguments may be `NULL`. If an error occurs, all * non-`NULL` position arguments will be set to zero. * * @param[in] window The window to query. * @param[out] xpos Where to store the x-coordinate of the upper-left corner of * the client area, or `NULL`. * @param[out] ypos Where to store the y-coordinate of the upper-left corner of * the client area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @sa glfwSetWindowPos * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); /*! @brief Sets the position of the client area of the specified window. * * This function sets the position, in screen coordinates, of the upper-left * corner of the client area of the specified windowed mode window. If the * window is a full screen window, this function does nothing. * * __Do not use this function__ to move an already visible window unless you * have very good reasons for doing so, as it will confuse and annoy the user. * * The window manager may put limits on what positions are allowed. GLFW * cannot and should not override these limits. * * @param[in] window The window to query. * @param[in] xpos The x-coordinate of the upper-left corner of the client area. * @param[in] ypos The y-coordinate of the upper-left corner of the client area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @sa glfwGetWindowPos * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); /*! @brief Retrieves the size of the client area of the specified window. * * This function retrieves the size, in screen coordinates, of the client area * of the specified window. If you wish to retrieve the size of the * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. * * @param[in] window The window whose size to retrieve. * @param[out] width Where to store the width, in screen coordinates, of the * client area, or `NULL`. * @param[out] height Where to store the height, in screen coordinates, of the * client area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @sa glfwSetWindowSize * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); /*! @brief Sets the size limits of the specified window. * * This function sets the size limits of the client area of the specified * window. If the window is full screen, the size limits only take effect * once it is made windowed. If the window is not resizable, this function * does nothing. * * The size limits are applied immediately to a windowed mode window and may * cause it to be resized. * * The maximum dimensions must be greater than or equal to the minimum * dimensions and all must be greater than or equal to zero. * * @param[in] window The window to set limits for. * @param[in] minwidth The minimum width, in screen coordinates, of the client * area, or `GLFW_DONT_CARE`. * @param[in] minheight The minimum height, in screen coordinates, of the * client area, or `GLFW_DONT_CARE`. * @param[in] maxwidth The maximum width, in screen coordinates, of the client * area, or `GLFW_DONT_CARE`. * @param[in] maxheight The maximum height, in screen coordinates, of the * client area, or `GLFW_DONT_CARE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @remark If you set size limits and an aspect ratio that conflict, the * results are undefined. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_sizelimits * @sa glfwSetWindowAspectRatio * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); /*! @brief Sets the aspect ratio of the specified window. * * This function sets the required aspect ratio of the client area of the * specified window. If the window is full screen, the aspect ratio only takes * effect once it is made windowed. If the window is not resizable, this * function does nothing. * * The aspect ratio is specified as a numerator and a denominator and both * values must be greater than zero. For example, the common 16:9 aspect ratio * is specified as 16 and 9, respectively. * * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect * ratio limit is disabled. * * The aspect ratio is applied immediately to a windowed mode window and may * cause it to be resized. * * @param[in] window The window to set limits for. * @param[in] numer The numerator of the desired aspect ratio, or * `GLFW_DONT_CARE`. * @param[in] denom The denominator of the desired aspect ratio, or * `GLFW_DONT_CARE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @remark If you set size limits and an aspect ratio that conflict, the * results are undefined. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_sizelimits * @sa glfwSetWindowSizeLimits * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); /*! @brief Sets the size of the client area of the specified window. * * This function sets the size, in screen coordinates, of the client area of * the specified window. * * For full screen windows, this function updates the resolution of its desired * video mode and switches to the video mode closest to it, without affecting * the window's context. As the context is unaffected, the bit depths of the * framebuffer remain unchanged. * * If you wish to update the refresh rate of the desired video mode in addition * to its resolution, see @ref glfwSetWindowMonitor. * * The window manager may put limits on what sizes are allowed. GLFW cannot * and should not override these limits. * * @param[in] window The window to resize. * @param[in] width The desired width, in screen coordinates, of the window * client area. * @param[in] height The desired height, in screen coordinates, of the window * client area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @sa glfwGetWindowSize * @sa glfwSetWindowMonitor * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); /*! @brief Retrieves the size of the framebuffer of the specified window. * * This function retrieves the size, in pixels, of the framebuffer of the * specified window. If you wish to retrieve the size of the window in screen * coordinates, see @ref glfwGetWindowSize. * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. * * @param[in] window The window whose framebuffer to query. * @param[out] width Where to store the width, in pixels, of the framebuffer, * or `NULL`. * @param[out] height Where to store the height, in pixels, of the framebuffer, * or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height); /*! @brief Retrieves the size of the frame of the window. * * This function retrieves the size, in screen coordinates, of each edge of the * frame of the specified window. This size includes the title bar, if the * window has one. The size of the frame may vary depending on the * [window-related hints](@ref window_hints_wnd) used to create it. * * Because this function retrieves the size of each window frame edge and not * the offset along a particular coordinate axis, the retrieved values will * always be zero or positive. * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. * * @param[in] window The window whose frame size to query. * @param[out] left Where to store the size, in screen coordinates, of the left * edge of the window frame, or `NULL`. * @param[out] top Where to store the size, in screen coordinates, of the top * edge of the window frame, or `NULL`. * @param[out] right Where to store the size, in screen coordinates, of the * right edge of the window frame, or `NULL`. * @param[out] bottom Where to store the size, in screen coordinates, of the * bottom edge of the window frame, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * * @since Added in version 3.1. * * @ingroup window */ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom); /*! @brief Iconifies the specified window. * * This function iconifies (minimizes) the specified window if it was * previously restored. If the window is already iconified, this function does * nothing. * * If the specified window is a full screen window, the original monitor * resolution is restored until the window is restored. * * @param[in] window The window to iconify. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * @sa glfwRestoreWindow * @sa glfwMaximizeWindow * * @since Added in version 2.1. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwIconifyWindow(GLFWwindow* window); /*! @brief Restores the specified window. * * This function restores the specified window if it was previously iconified * (minimized) or maximized. If the window is already restored, this function * does nothing. * * If the specified window is a full screen window, the resolution chosen for * the window is restored on the selected monitor. * * @param[in] window The window to restore. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * @sa glfwIconifyWindow * @sa glfwMaximizeWindow * * @since Added in version 2.1. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwRestoreWindow(GLFWwindow* window); /*! @brief Maximizes the specified window. * * This function maximizes the specified window if it was previously not * maximized. If the window is already maximized, this function does nothing. * * If the specified window is a full screen window, this function does nothing. * * @param[in] window The window to maximize. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @par Thread Safety * This function may only be called from the main thread. * * @sa @ref window_iconify * @sa glfwIconifyWindow * @sa glfwRestoreWindow * * @since Added in GLFW 3.2. * * @ingroup window */ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window); /*! @brief Makes the specified window visible. * * This function makes the specified window visible if it was previously * hidden. If the window is already visible or is in full screen mode, this * function does nothing. * * @param[in] window The window to make visible. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide * @sa glfwHideWindow * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwShowWindow(GLFWwindow* window); /*! @brief Hides the specified window. * * This function hides the specified window if it was previously visible. If * the window is already hidden or is in full screen mode, this function does * nothing. * * @param[in] window The window to hide. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide * @sa glfwShowWindow * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwHideWindow(GLFWwindow* window); /*! @brief Brings the specified window to front and sets input focus. * * This function brings the specified window to front and sets input focus. * The window should already be visible and not iconified. * * By default, both windowed and full screen mode windows are focused when * initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable * this behavior. * * __Do not use this function__ to steal focus from other applications unless * you are certain that is what the user wants. Focus stealing can be * extremely disruptive. * * @param[in] window The window to give input focus. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_focus * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwFocusWindow(GLFWwindow* window); /*! @brief Returns the monitor that the window uses for full screen mode. * * This function returns the handle of the monitor that the specified window is * in full screen on. * * @param[in] window The window to query. * @return The monitor, or `NULL` if the window is in windowed mode or an error * occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor * @sa glfwSetWindowMonitor * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); /*! @brief Sets the mode, monitor, video mode and placement of a window. * * This function sets the monitor that the window uses for full screen mode or, * if the monitor is `NULL`, makes it windowed mode. * * When setting a monitor, this function updates the width, height and refresh * rate of the desired video mode and switches to the video mode closest to it. * The window position is ignored when setting a monitor. * * When the monitor is `NULL`, the position, width and height are used to * place the window client area. The refresh rate is ignored when no monitor * is specified. * * If you only wish to update the resolution of a full screen window or the * size of a windowed mode window, see @ref glfwSetWindowSize. * * When a window transitions from full screen to windowed mode, this function * restores any previous window settings such as whether it is decorated, * floating, resizable, has size or aspect ratio limits, etc.. * * @param[in] window The window whose monitor, size or video mode to set. * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. * @param[in] xpos The desired x-coordinate of the upper-left corner of the * client area. * @param[in] ypos The desired y-coordinate of the upper-left corner of the * client area. * @param[in] width The desired with, in screen coordinates, of the client area * or video mode. * @param[in] height The desired height, in screen coordinates, of the client * area or video mode. * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode, * or `GLFW_DONT_CARE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor * @sa @ref window_full_screen * @sa glfwGetWindowMonitor * @sa glfwSetWindowSize * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); /*! @brief Returns an attribute of the specified window. * * This function returns the value of an attribute of the specified window or * its OpenGL or OpenGL ES context. * * @param[in] window The window to query. * @param[in] attrib The [window attribute](@ref window_attribs) whose value to * return. * @return The value of the attribute, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @remark Framebuffer related hints are not window attributes. See @ref * window_attribs_fb for more information. * * @remark Zero is a valid value for many window and context related * attributes so you cannot use a return value of zero as an indication of * errors. However, this function should not fail as long as it is passed * valid arguments and the library has been [initialized](@ref intro_init). * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs * * @since Added in version 3.0. Replaces `glfwGetWindowParam` and * `glfwGetGLVersion`. * * @ingroup window */ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); /*! @brief Sets the user pointer of the specified window. * * This function sets the user-defined pointer of the specified window. The * current value is retained until the window is destroyed. The initial value * is `NULL`. * * @param[in] window The window whose pointer to set. * @param[in] pointer The new value. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @sa @ref window_userptr * @sa glfwGetWindowUserPointer * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); /*! @brief Returns the user pointer of the specified window. * * This function returns the current value of the user-defined pointer of the * specified window. The initial value is `NULL`. * * @param[in] window The window whose pointer to return. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @sa @ref window_userptr * @sa glfwSetWindowUserPointer * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); /*! @brief Sets the position callback for the specified window. * * This function sets the position callback of the specified window, which is * called when the window is moved. The callback is provided with the screen * position of the upper-left corner of the client area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun); /*! @brief Sets the size callback for the specified window. * * This function sets the size callback of the specified window, which is * called when the window is resized. The callback is provided with the size, * in screen coordinates, of the client area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * * @since Added in version 1.0. * @glfw3 Added window handle parameter and return value. * * @ingroup window */ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun); /*! @brief Sets the close callback for the specified window. * * This function sets the close callback of the specified window, which is * called when the user attempts to close the window, for example by clicking * the close widget in the title bar. * * The close flag is set before this callback is called, but you can modify it * at any time with @ref glfwSetWindowShouldClose. * * The close callback is not triggered by @ref glfwDestroyWindow. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @remark @osx Selecting Quit from the application menu will trigger the close * callback for all windows. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_close * * @since Added in version 2.5. * @glfw3 Added window handle parameter and return value. * * @ingroup window */ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun); /*! @brief Sets the refresh callback for the specified window. * * This function sets the refresh callback of the specified window, which is * called when the client area of the window needs to be redrawn, for example * if the window has been exposed after having been covered by another window. * * On compositing window systems such as Aero, Compiz or Aqua, where the window * contents are saved off-screen, this callback may be called only very * infrequently or never at all. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_refresh * * @since Added in version 2.5. * @glfw3 Added window handle parameter and return value. * * @ingroup window */ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun); /*! @brief Sets the focus callback for the specified window. * * This function sets the focus callback of the specified window, which is * called when the window gains or loses input focus. * * After the focus callback is called for a window that lost input focus, * synthetic key and mouse button release events will be generated for all such * that had been pressed. For more information, see @ref glfwSetKeyCallback * and @ref glfwSetMouseButtonCallback. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_focus * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun); /*! @brief Sets the iconify callback for the specified window. * * This function sets the iconification callback of the specified window, which * is called when the window is iconified or restored. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun); /*! @brief Sets the framebuffer resize callback for the specified window. * * This function sets the framebuffer resize callback of the specified window, * which is called when the framebuffer of the specified window is resized. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun); /*! @brief Processes all pending events. * * This function processes only those events that are already in the event * queue and then returns immediately. Processing events will cause the window * and input callbacks associated with those events to be called. * * On some platforms, a window move, resize or menu operation will cause event * processing to block. This is due to how event processing is designed on * those platforms. You can use the * [window refresh callback](@ref window_refresh) to redraw the contents of * your window when necessary during such operations. * * On some platforms, certain events are sent directly to the application * without going through the event queue, causing callbacks to be called * outside of a call to one of the event processing functions. * * Event processing is not required for joystick input to work. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwWaitEvents * @sa glfwWaitEventsTimeout * * @since Added in version 1.0. * * @ingroup window */ GLFWAPI void glfwPollEvents(void); /*! @brief Waits until events are queued and processes them. * * This function puts the calling thread to sleep until at least one event is * available in the event queue. Once one or more events are available, * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue * are processed and the function then returns immediately. Processing events * will cause the window and input callbacks associated with those events to be * called. * * Since not all events are associated with callbacks, this function may return * without a callback having been called even if you are monitoring all * callbacks. * * On some platforms, a window move, resize or menu operation will cause event * processing to block. This is due to how event processing is designed on * those platforms. You can use the * [window refresh callback](@ref window_refresh) to redraw the contents of * your window when necessary during such operations. * * On some platforms, certain callbacks may be called outside of a call to one * of the event processing functions. * * If no windows exist, this function returns immediately. For synchronization * of threads in applications that do not create windows, use your threading * library of choice. * * Event processing is not required for joystick input to work. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwPollEvents * @sa glfwWaitEventsTimeout * * @since Added in version 2.5. * * @ingroup window */ GLFWAPI void glfwWaitEvents(void); /*! @brief Waits with timeout until events are queued and processes them. * * This function puts the calling thread to sleep until at least one event is * available in the event queue, or until the specified timeout is reached. If * one or more events are available, it behaves exactly like @ref * glfwPollEvents, i.e. the events in the queue are processed and the function * then returns immediately. Processing events will cause the window and input * callbacks associated with those events to be called. * * The timeout value must be a positive finite number. * * Since not all events are associated with callbacks, this function may return * without a callback having been called even if you are monitoring all * callbacks. * * On some platforms, a window move, resize or menu operation will cause event * processing to block. This is due to how event processing is designed on * those platforms. You can use the * [window refresh callback](@ref window_refresh) to redraw the contents of * your window when necessary during such operations. * * On some platforms, certain callbacks may be called outside of a call to one * of the event processing functions. * * If no windows exist, this function returns immediately. For synchronization * of threads in applications that do not create windows, use your threading * library of choice. * * Event processing is not required for joystick input to work. * * @param[in] timeout The maximum amount of time, in seconds, to wait. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwPollEvents * @sa glfwWaitEvents * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwWaitEventsTimeout(double timeout); /*! @brief Posts an empty event to the event queue. * * This function posts an empty event from the current thread to the event * queue, causing @ref glfwWaitEvents to return. * * If no windows exist, this function returns immediately. For synchronization * of threads in applications that do not create windows, use your threading * library of choice. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function may be called from any thread. * * @sa @ref events * @sa glfwWaitEvents * * @since Added in version 3.1. * * @ingroup window */ GLFWAPI void glfwPostEmptyEvent(void); /*! @brief Returns the value of an input option for the specified window. * * This function returns the value of an input option for the specified window. * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * * @param[in] window The window to query. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * * @thread_safety This function must only be called from the main thread. * * @sa glfwSetInputMode * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); /*! @brief Sets an input option for the specified window. * * This function sets an input mode option for the specified window. The mode * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * modes: * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client * area of the window but does not restrict the cursor from leaving. * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual * and unlimited cursor movement. This is useful for implementing for * example 3D camera controls. * * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS` * the next time it is called even if the key had been released before the * call. This is useful when you are only interested in whether keys have been * pressed but not when or in which order. * * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it. * If sticky mouse buttons are enabled, a mouse button press will ensure that * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even * if the mouse button had been released before the call. This is useful when * you are only interested in whether mouse buttons have been pressed but not * when or in which order. * * @param[in] window The window whose input mode to set. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * @param[in] value The new value of the specified input mode. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa glfwGetInputMode * * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`. * * @ingroup input */ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); /*! @brief Returns the localized name of the specified printable key. * * This function returns the localized name of the specified printable key. * This is intended for displaying key bindings to the user. * * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise * the scancode is ignored. If a non-printable key or (if the key is * `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is * specified, this function returns `NULL`. * * This behavior allows you to pass in the arguments passed to the * [key callback](@ref input_key) without modification. * * The printable keys are: * - `GLFW_KEY_APOSTROPHE` * - `GLFW_KEY_COMMA` * - `GLFW_KEY_MINUS` * - `GLFW_KEY_PERIOD` * - `GLFW_KEY_SLASH` * - `GLFW_KEY_SEMICOLON` * - `GLFW_KEY_EQUAL` * - `GLFW_KEY_LEFT_BRACKET` * - `GLFW_KEY_RIGHT_BRACKET` * - `GLFW_KEY_BACKSLASH` * - `GLFW_KEY_WORLD_1` * - `GLFW_KEY_WORLD_2` * - `GLFW_KEY_0` to `GLFW_KEY_9` * - `GLFW_KEY_A` to `GLFW_KEY_Z` * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9` * - `GLFW_KEY_KP_DECIMAL` * - `GLFW_KEY_KP_DIVIDE` * - `GLFW_KEY_KP_MULTIPLY` * - `GLFW_KEY_KP_SUBTRACT` * - `GLFW_KEY_KP_ADD` * - `GLFW_KEY_KP_EQUAL` * * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`. * @param[in] scancode The scancode of the key to query. * @return The localized name of the key, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetKeyName, or until the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key_name * * @since Added in version 3.2. * * @ingroup input */ GLFWAPI const char* glfwGetKeyName(int key, int scancode); /*! @brief Returns the last reported state of a keyboard key for the specified * window. * * This function returns the last state reported for the specified key to the * specified window. The returned state is one of `GLFW_PRESS` or * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to * the key callback. * * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns * `GLFW_PRESS` the first time you call it for a key that was pressed, even if * that key has already been released. * * The key functions deal with physical keys, with [key tokens](@ref keys) * named after their use on the standard US keyboard layout. If you want to * input text, use the Unicode character callback instead. * * The [modifier key bit masks](@ref mods) are not key tokens and cannot be * used with this function. * * __Do not use this function__ to implement [text input](@ref input_char). * * @param[in] window The desired window. * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is * not a valid key for this function. * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup input */ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); /*! @brief Returns the last reported state of a mouse button for the specified * window. * * This function returns the last state reported for the specified mouse button * to the specified window. The returned state is one of `GLFW_PRESS` or * `GLFW_RELEASE`. * * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function * `GLFW_PRESS` the first time you call it for a mouse button that was pressed, * even if that mouse button has already been released. * * @param[in] window The desired window. * @param[in] button The desired [mouse button](@ref buttons). * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_mouse_button * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup input */ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); /*! @brief Retrieves the position of the cursor relative to the client area of * the window. * * This function returns the position of the cursor, in screen coordinates, * relative to the upper-left corner of the client area of the specified * window. * * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor * position is unbounded and limited only by the minimum and maximum values of * a `double`. * * The coordinate can be converted to their integer equivalents with the * `floor` function. Casting directly to an integer type works for positive * coordinates, but fails for negative ones. * * Any or all of the position arguments may be `NULL`. If an error occurs, all * non-`NULL` position arguments will be set to zero. * * @param[in] window The desired window. * @param[out] xpos Where to store the cursor x-coordinate, relative to the * left edge of the client area, or `NULL`. * @param[out] ypos Where to store the cursor y-coordinate, relative to the to * top edge of the client area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @sa glfwSetCursorPos * * @since Added in version 3.0. Replaces `glfwGetMousePos`. * * @ingroup input */ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); /*! @brief Sets the position of the cursor, relative to the client area of the * window. * * This function sets the position, in screen coordinates, of the cursor * relative to the upper-left corner of the client area of the specified * window. The window must have input focus. If the window does not have * input focus when this function is called, it fails silently. * * __Do not use this function__ to implement things like camera controls. GLFW * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the * cursor, transparently re-centers it and provides unconstrained cursor * motion. See @ref glfwSetInputMode for more information. * * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is * unconstrained and limited only by the minimum and maximum values of * a `double`. * * @param[in] window The desired window. * @param[in] xpos The desired x-coordinate, relative to the left edge of the * client area. * @param[in] ypos The desired y-coordinate, relative to the top edge of the * client area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @sa glfwGetCursorPos * * @since Added in version 3.0. Replaces `glfwSetMousePos`. * * @ingroup input */ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); /*! @brief Creates a custom cursor. * * Creates a new custom cursor image that can be set for a window with @ref * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor. * Any remaining cursors are destroyed by @ref glfwTerminate. * * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight * bits per channel. They are arranged canonically as packed sequential rows, * starting from the top-left corner. * * The cursor hotspot is specified in pixels, relative to the upper-left corner * of the cursor image. Like all other coordinate systems in GLFW, the X-axis * points to the right and the Y-axis points down. * * @param[in] image The desired cursor image. * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot. * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot. * @return The handle of the created cursor, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified image data is copied before this function * returns. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwDestroyCursor * @sa glfwCreateStandardCursor * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); /*! @brief Creates a cursor with a standard shape. * * Returns a cursor with a [standard shape](@ref shapes), that can be set for * a window with @ref glfwSetCursor. * * @param[in] shape One of the [standard shapes](@ref shapes). * @return A new cursor ready to use or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwCreateCursor * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); /*! @brief Destroys a cursor. * * This function destroys a cursor previously created with @ref * glfwCreateCursor. Any remaining cursors will be destroyed by @ref * glfwTerminate. * * @param[in] cursor The cursor object to destroy. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwCreateCursor * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); /*! @brief Sets the cursor for the window. * * This function sets the cursor image to be used when the cursor is over the * client area of the specified window. The set cursor will only be visible * when the [cursor mode](@ref cursor_mode) of the window is * `GLFW_CURSOR_NORMAL`. * * On some platforms, the set cursor may not be visible unless the window also * has input focus. * * @param[in] window The window to set the cursor for. * @param[in] cursor The cursor to set, or `NULL` to switch back to the default * arrow cursor. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); /*! @brief Sets the key callback. * * This function sets the key callback of the specified window, which is called * when a key is pressed, repeated or released. * * The key functions deal with physical keys, with layout independent * [key tokens](@ref keys) named after their values in the standard US keyboard * layout. If you want to input text, use the * [character callback](@ref glfwSetCharCallback) instead. * * When a window loses input focus, it will generate synthetic key release * events for all pressed keys. You can tell these events from user-generated * events by the fact that the synthetic ones are generated after the focus * loss event has been processed, i.e. after the * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * * The scancode of a key is specific to that platform or sometimes even to that * machine. Scancodes are intended to allow users to bind keys that don't have * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their * state is not saved and so it cannot be queried with @ref glfwGetKey. * * Sometimes GLFW needs to generate synthetic key events, in which case the * scancode may be zero. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new key callback, or `NULL` to remove the currently * set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key * * @since Added in version 1.0. * @glfw3 Added window handle parameter and return value. * * @ingroup input */ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); /*! @brief Sets the Unicode character callback. * * This function sets the character callback of the specified window, which is * called when a Unicode character is input. * * The character callback is intended for Unicode text input. As it deals with * characters, it is keyboard layout dependent, whereas the * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1 * to physical keys, as a key may produce zero, one or more characters. If you * want to know whether a specific physical key was pressed or released, see * the key callback instead. * * The character callback behaves as system text input normally does and will * not be called if modifier keys are held down that would prevent normal text * input on that platform, for example a Super (Command) key on OS X or Alt key * on Windows. There is a * [character with modifiers callback](@ref glfwSetCharModsCallback) that * receives these events. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char * * @since Added in version 2.4. * @glfw3 Added window handle parameter and return value. * * @ingroup input */ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); /*! @brief Sets the Unicode character with modifiers callback. * * This function sets the character with modifiers callback of the specified * window, which is called when a Unicode character is input regardless of what * modifier keys are used. * * The character with modifiers callback is intended for implementing custom * Unicode character input. For regular Unicode text input, see the * [character callback](@ref glfwSetCharCallback). Like the character * callback, the character with modifiers callback deals with characters and is * keyboard layout dependent. Characters do not map 1:1 to physical keys, as * a key may produce zero, one or more characters. If you want to know whether * a specific physical key was pressed or released, see the * [key callback](@ref glfwSetKeyCallback) instead. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or an * error occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun); /*! @brief Sets the mouse button callback. * * This function sets the mouse button callback of the specified window, which * is called when a mouse button is pressed or released. * * When a window loses input focus, it will generate synthetic mouse button * release events for all pressed mouse buttons. You can tell these events * from user-generated events by the fact that the synthetic ones are generated * after the focus loss event has been processed, i.e. after the * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_mouse_button * * @since Added in version 1.0. * @glfw3 Added window handle parameter and return value. * * @ingroup input */ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun); /*! @brief Sets the cursor position callback. * * This function sets the cursor position callback of the specified window, * which is called when the cursor is moved. The callback is provided with the * position, in screen coordinates, relative to the upper-left corner of the * client area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`. * * @ingroup input */ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun); /*! @brief Sets the cursor enter/exit callback. * * This function sets the cursor boundary crossing callback of the specified * window, which is called when the cursor enters or leaves the client area of * the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_enter * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun); /*! @brief Sets the scroll callback. * * This function sets the scroll callback of the specified window, which is * called when a scrolling device is used, such as a mouse wheel or scrolling * area of a touchpad. * * The scroll callback receives all scrolling input, like that from a mouse * wheel or a touchpad scrolling area. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently * set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref scrolling * * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`. * * @ingroup input */ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun); /*! @brief Sets the file drop callback. * * This function sets the file drop callback of the specified window, which is * called when one or more dragged files are dropped on the window. * * Because the path array and its strings may have been generated specifically * for that event, they are not guaranteed to be valid after the callback has * returned. If you wish to use them after the callback returns, you need to * make a deep copy. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new file drop callback, or `NULL` to remove the * currently set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref path_drop * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); /*! @brief Returns whether the specified joystick is present. * * This function returns whether the specified joystick is present. * * @param[in] joy The [joystick](@ref joysticks) to query. * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick * * @since Added in version 3.0. Replaces `glfwGetJoystickParam`. * * @ingroup input */ GLFWAPI int glfwJoystickPresent(int joy); /*! @brief Returns the values of all axes of the specified joystick. * * This function returns the values of all axes of the specified joystick. * Each element in the array is a value between -1.0 and 1.0. * * Querying a joystick slot with no device present is not an error, but will * cause this function to return `NULL`. Call @ref glfwJoystickPresent to * check device presence. * * @param[in] joy The [joystick](@ref joysticks) to query. * @param[out] count Where to store the number of axis values in the returned * array. This is set to zero if an error occurred. * @return An array of axis values, or `NULL` if the joystick is not present. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_axis * * @since Added in version 3.0. Replaces `glfwGetJoystickPos`. * * @ingroup input */ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); /*! @brief Returns the state of all buttons of the specified joystick. * * This function returns the state of all buttons of the specified joystick. * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`. * * Querying a joystick slot with no device present is not an error, but will * cause this function to return `NULL`. Call @ref glfwJoystickPresent to * check device presence. * * @param[in] joy The [joystick](@ref joysticks) to query. * @param[out] count Where to store the number of button states in the returned * array. This is set to zero if an error occurred. * @return An array of button states, or `NULL` if the joystick is not present. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_button * * @since Added in version 2.2. * @glfw3 Changed to return a dynamic array. * * @ingroup input */ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); /*! @brief Returns the name of the specified joystick. * * This function returns the name, encoded as UTF-8, of the specified joystick. * The returned string is allocated and freed by GLFW. You should not free it * yourself. * * Querying a joystick slot with no device present is not an error, but will * cause this function to return `NULL`. Call @ref glfwJoystickPresent to * check device presence. * * @param[in] joy The [joystick](@ref joysticks) to query. * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick * is not present. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_name * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI const char* glfwGetJoystickName(int joy); /*! @brief Sets the joystick configuration callback. * * This function sets the joystick configuration callback, or removes the * currently set callback. This is called when a joystick is connected to or * disconnected from the system. * * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_event * * @since Added in version 3.2. * * @ingroup input */ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun); /*! @brief Sets the clipboard to the specified string. * * This function sets the system clipboard to the specified, UTF-8 encoded * string. * * @param[in] window The window that will own the clipboard contents. * @param[in] string A UTF-8 encoded string. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified string is copied before this function * returns. * * @thread_safety This function must only be called from the main thread. * * @sa @ref clipboard * @sa glfwGetClipboardString * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); /*! @brief Returns the contents of the clipboard as a string. * * This function returns the contents of the system clipboard, if it contains * or is convertible to a UTF-8 encoded string. If the clipboard is empty or * if its contents cannot be converted, `NULL` is returned and a @ref * GLFW_FORMAT_UNAVAILABLE error is generated. * * @param[in] window The window that will request the clipboard contents. * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref clipboard * @sa glfwSetClipboardString * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); /*! @brief Returns the value of the GLFW timer. * * This function returns the value of the GLFW timer. Unless the timer has * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW * was initialized. * * The resolution of the timer is system dependent, but is usually on the order * of a few micro- or nanoseconds. It uses the highest-resolution monotonic * time source on each supported platform. * * @return The current value, in seconds, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Reading and * writing of the internal timer offset is not atomic, so it needs to be * externally synchronized with calls to @ref glfwSetTime. * * @sa @ref time * * @since Added in version 1.0. * * @ingroup input */ GLFWAPI double glfwGetTime(void); /*! @brief Sets the GLFW timer. * * This function sets the value of the GLFW timer. It then continues to count * up from that value. The value must be a positive finite number less than * or equal to 18446744073.0, which is approximately 584.5 years. * * @param[in] time The new value, in seconds. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_VALUE. * * @remark The upper limit of the timer is calculated as * floor((264 - 1) / 109) and is due to implementations * storing nanoseconds in 64 bits. The limit may be increased in the future. * * @thread_safety This function may be called from any thread. Reading and * writing of the internal timer offset is not atomic, so it needs to be * externally synchronized with calls to @ref glfwGetTime. * * @sa @ref time * * @since Added in version 2.2. * * @ingroup input */ GLFWAPI void glfwSetTime(double time); /*! @brief Returns the current value of the raw timer. * * This function returns the current value of the raw timer, measured in * 1 / frequency seconds. To get the frequency, call @ref * glfwGetTimerFrequency. * * @return The value of the timer, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. * * @sa @ref time * @sa glfwGetTimerFrequency * * @since Added in version 3.2. * * @ingroup input */ GLFWAPI uint64_t glfwGetTimerValue(void); /*! @brief Returns the frequency, in Hz, of the raw timer. * * This function returns the frequency, in Hz, of the raw timer. * * @return The frequency of the timer, in Hz, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. * * @sa @ref time * @sa glfwGetTimerValue * * @since Added in version 3.2. * * @ingroup input */ GLFWAPI uint64_t glfwGetTimerFrequency(void); /*! @brief Makes the context of the specified window current for the calling * thread. * * This function makes the OpenGL or OpenGL ES context of the specified window * current on the calling thread. A context can only be made current on * a single thread at a time and each thread can have only a single current * context at a time. * * By default, making a context non-current implicitly forces a pipeline flush. * On machines that support `GL_KHR_context_flush_control`, you can control * whether a context performs this flush by setting the * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint. * * The specified window must have an OpenGL or OpenGL ES context. Specifying * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT * error. * * @param[in] window The window whose context to make current, or `NULL` to * detach the current context. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function may be called from any thread. * * @sa @ref context_current * @sa glfwGetCurrentContext * * @since Added in version 3.0. * * @ingroup context */ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); /*! @brief Returns the window whose context is current on the calling thread. * * This function returns the window whose OpenGL or OpenGL ES context is * current on the calling thread. * * @return The window whose context is current, or `NULL` if no window's * context is current. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. * * @sa @ref context_current * @sa glfwMakeContextCurrent * * @since Added in version 3.0. * * @ingroup context */ GLFWAPI GLFWwindow* glfwGetCurrentContext(void); /*! @brief Swaps the front and back buffers of the specified window. * * This function swaps the front and back buffers of the specified window when * rendering with OpenGL or OpenGL ES. If the swap interval is greater than * zero, the GPU driver waits the specified number of screen updates before * swapping the buffers. * * The specified window must have an OpenGL or OpenGL ES context. Specifying * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT * error. * * This function does not apply to Vulkan. If you are rendering with Vulkan, * see `vkQueuePresentKHR` instead. * * @param[in] window The window whose buffers to swap. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark __EGL:__ The context of the specified window must be current on the * calling thread. * * @thread_safety This function may be called from any thread. * * @sa @ref buffer_swap * @sa glfwSwapInterval * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSwapBuffers(GLFWwindow* window); /*! @brief Sets the swap interval for the current context. * * This function sets the swap interval for the current OpenGL or OpenGL ES * context, i.e. the number of screen updates to wait from the time @ref * glfwSwapBuffers was called before swapping the buffers and returning. This * is sometimes called _vertical synchronization_, _vertical retrace * synchronization_ or just _vsync_. * * Contexts that support either of the `WGL_EXT_swap_control_tear` and * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals, * which allow the driver to swap even if a frame arrives a little bit late. * You can check for the presence of these extensions using @ref * glfwExtensionSupported. For more information about swap tearing, see the * extension specifications. * * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * * This function does not apply to Vulkan. If you are rendering with Vulkan, * see the present mode of your swapchain instead. * * @param[in] interval The minimum number of screen updates to wait for * until the buffers are swapped by @ref glfwSwapBuffers. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark This function is not called during context creation, leaving the * swap interval set to whatever is the default on that platform. This is done * because some swap interval extensions used by GLFW do not allow the swap * interval to be reset to zero once it has been set to a non-zero value. * * @remark Some GPU drivers do not honor the requested swap interval, either * because of a user setting that overrides the application's request or due to * bugs in the driver. * * @thread_safety This function may be called from any thread. * * @sa @ref buffer_swap * @sa glfwSwapBuffers * * @since Added in version 1.0. * * @ingroup context */ GLFWAPI void glfwSwapInterval(int interval); /*! @brief Returns whether the specified extension is available. * * This function returns whether the specified * [API extension](@ref context_glext) is supported by the current OpenGL or * OpenGL ES context. It searches both for client API extension and context * creation API extensions. * * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * * As this functions retrieves and searches one or more extension strings each * call, it is recommended that you cache its results if it is going to be used * frequently. The extension strings will not change during the lifetime of * a context, so there is no danger in doing this. * * This function does not apply to Vulkan. If you are using Vulkan, see @ref * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties` * and `vkEnumerateDeviceExtensionProperties` instead. * * @param[in] extension The ASCII encoded name of the extension. * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` * otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function may be called from any thread. * * @sa @ref context_glext * @sa glfwGetProcAddress * * @since Added in version 1.0. * * @ingroup context */ GLFWAPI int glfwExtensionSupported(const char* extension); /*! @brief Returns the address of the specified function for the current * context. * * This function returns the address of the specified OpenGL or OpenGL ES * [core or extension function](@ref context_glext), if it is supported * by the current context. * * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * * This function does not apply to Vulkan. If you are rendering with Vulkan, * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and * `vkGetDeviceProcAddr` instead. * * @param[in] procname The ASCII encoded name of the function. * @return The address of the function, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark The address of a given function is not guaranteed to be the same * between contexts. * * @remark This function may return a non-`NULL` address despite the * associated version or extension not being available. Always check the * context version or extension string first. * * @pointer_lifetime The returned function pointer is valid until the context * is destroyed or the library is terminated. * * @thread_safety This function may be called from any thread. * * @sa @ref context_glext * @sa glfwExtensionSupported * * @since Added in version 1.0. * * @ingroup context */ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); /*! @brief Returns whether the Vulkan loader has been found. * * This function returns whether the Vulkan loader has been found. This check * is performed by @ref glfwInit. * * The availability of a Vulkan loader does not by itself guarantee that window * surface creation or even device creation is possible. Call @ref * glfwGetRequiredInstanceExtensions to check whether the extensions necessary * for Vulkan surface creation are available and @ref * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of * a physical device supports image presentation. * * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. * * @sa @ref vulkan_support * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI int glfwVulkanSupported(void); /*! @brief Returns the Vulkan instance extensions required by GLFW. * * This function returns an array of names of Vulkan instance extensions required * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the * list will always contains `VK_KHR_surface`, so if you don't require any * additional extensions you can pass this list directly to the * `VkInstanceCreateInfo` struct. * * If Vulkan is not available on the machine, this function returns `NULL` and * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported * to check whether Vulkan is available. * * If Vulkan is available but no set of extensions allowing window surface * creation was found, this function returns `NULL`. You may still use Vulkan * for off-screen rendering and compute work. * * @param[out] count Where to store the number of extensions in the returned * array. This is set to zero if an error occurred. * @return An array of ASCII encoded extension names, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_API_UNAVAILABLE. * * @remarks Additional extensions may be required by future versions of GLFW. * You should check if any extensions you wish to enable are already in the * returned array, as it is an error to specify an extension more than once in * the `VkInstanceCreateInfo` struct. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is guaranteed to be valid only until the * library is terminated. * * @thread_safety This function may be called from any thread. * * @sa @ref vulkan_ext * @sa glfwCreateWindowSurface * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count); #if defined(VK_VERSION_1_0) /*! @brief Returns the address of the specified Vulkan instance function. * * This function returns the address of the specified Vulkan core or extension * function for the specified instance. If instance is set to `NULL` it can * return any function exported from the Vulkan loader, including at least the * following functions: * * - `vkEnumerateInstanceExtensionProperties` * - `vkEnumerateInstanceLayerProperties` * - `vkCreateInstance` * - `vkGetInstanceProcAddr` * * If Vulkan is not available on the machine, this function returns `NULL` and * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported * to check whether Vulkan is available. * * This function is equivalent to calling `vkGetInstanceProcAddr` with * a platform-specific query of the Vulkan loader as a fallback. * * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve * functions related to instance creation. * @param[in] procname The ASCII encoded name of the function. * @return The address of the function, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_API_UNAVAILABLE. * * @pointer_lifetime The returned function pointer is valid until the library * is terminated. * * @thread_safety This function may be called from any thread. * * @sa @ref vulkan_proc * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname); /*! @brief Returns whether the specified queue family can present images. * * This function returns whether the specified queue family of the specified * physical device supports presentation to the platform GLFW was built for. * * If Vulkan or the required window surface creation instance extensions are * not available on the machine, or if the specified instance was not created * with the required extensions, this function returns `GLFW_FALSE` and * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported * to check whether Vulkan is available and @ref * glfwGetRequiredInstanceExtensions to check what instance extensions are * required. * * @param[in] instance The instance that the physical device belongs to. * @param[in] device The physical device that the queue family belongs to. * @param[in] queuefamily The index of the queue family to query. * @return `GLFW_TRUE` if the queue family supports presentation, or * `GLFW_FALSE` otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function may be called from any thread. For * synchronization details of Vulkan objects, see the Vulkan specification. * * @sa @ref vulkan_present * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); /*! @brief Creates a Vulkan surface for the specified window. * * This function creates a Vulkan surface for the specified window. * * If the Vulkan loader was not found at initialization, this function returns * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was * found. * * If the required window surface creation instance extensions are not * available or if the specified instance was not created with these extensions * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref * glfwGetRequiredInstanceExtensions to check what instance extensions are * required. * * The window surface must be destroyed before the specified Vulkan instance. * It is the responsibility of the caller to destroy the window surface. GLFW * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the * surface. * * @param[in] instance The Vulkan instance to create the surface in. * @param[in] window The window to create the surface for. * @param[in] allocator The allocator to use, or `NULL` to use the default * allocator. * @param[out] surface Where to store the handle of the surface. This is set * to `VK_NULL_HANDLE` if an error occurred. * @return `VK_SUCCESS` if successful, or a Vulkan error code if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @remarks If an error occurs before the creation call is made, GLFW returns * the Vulkan error code most appropriate for the error. Appropriate use of * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should * eliminate almost all occurrences of these errors. * * @thread_safety This function may be called from any thread. For * synchronization details of Vulkan objects, see the Vulkan specification. * * @sa @ref vulkan_surface * @sa glfwGetRequiredInstanceExtensions * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); #endif /*VK_VERSION_1_0*/ /************************************************************************* * Global definition cleanup *************************************************************************/ /* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ #ifdef GLFW_WINGDIAPI_DEFINED #undef WINGDIAPI #undef GLFW_WINGDIAPI_DEFINED #endif #ifdef GLFW_CALLBACK_DEFINED #undef CALLBACK #undef GLFW_CALLBACK_DEFINED #endif /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ #ifdef __cplusplus } #endif #endif /* _glfw3_h_ */ ================================================ FILE: samples/vs2015/glfw-3.2-WIN32/include/GLFW/glfw3native.h ================================================ /************************************************************************* * GLFW 3.2 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard * Copyright (c) 2006-2016 Camilla Berglund * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would * be appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. * *************************************************************************/ #ifndef _glfw3_native_h_ #define _glfw3_native_h_ #ifdef __cplusplus extern "C" { #endif /************************************************************************* * Doxygen documentation *************************************************************************/ /*! @file glfw3native.h * @brief The header of the native access functions. * * This is the header file of the native access functions. See @ref native for * more information. */ /*! @defgroup native Native access * * **By using the native access functions you assert that you know what you're * doing and how to fix problems caused by using them. If you don't, you * shouldn't be using them.** * * Before the inclusion of @ref glfw3native.h, you may define exactly one * window system API macro and zero or more context creation API macros. * * The chosen backends must match those the library was compiled for. Failure * to do this will cause a link-time error. * * The available window API macros are: * * `GLFW_EXPOSE_NATIVE_WIN32` * * `GLFW_EXPOSE_NATIVE_COCOA` * * `GLFW_EXPOSE_NATIVE_X11` * * `GLFW_EXPOSE_NATIVE_WAYLAND` * * `GLFW_EXPOSE_NATIVE_MIR` * * The available context API macros are: * * `GLFW_EXPOSE_NATIVE_WGL` * * `GLFW_EXPOSE_NATIVE_NSGL` * * `GLFW_EXPOSE_NATIVE_GLX` * * `GLFW_EXPOSE_NATIVE_EGL` * * These macros select which of the native access functions that are declared * and which platform-specific headers to include. It is then up your (by * definition platform-specific) code to handle which of these should be * defined. */ /************************************************************************* * System headers and types *************************************************************************/ #if defined(GLFW_EXPOSE_NATIVE_WIN32) // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for // example to allow applications to correctly declare a GL_ARB_debug_output // callback) but windows.h assumes no one will define APIENTRY before it does #undef APIENTRY #include #elif defined(GLFW_EXPOSE_NATIVE_COCOA) #include #if defined(__OBJC__) #import #else typedef void* id; #endif #elif defined(GLFW_EXPOSE_NATIVE_X11) #include #include #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) #include #elif defined(GLFW_EXPOSE_NATIVE_MIR) #include #endif #if defined(GLFW_EXPOSE_NATIVE_WGL) /* WGL is declared by windows.h */ #endif #if defined(GLFW_EXPOSE_NATIVE_NSGL) /* NSGL is declared by Cocoa.h */ #endif #if defined(GLFW_EXPOSE_NATIVE_GLX) #include #endif #if defined(GLFW_EXPOSE_NATIVE_EGL) #include #endif /************************************************************************* * Functions *************************************************************************/ #if defined(GLFW_EXPOSE_NATIVE_WIN32) /*! @brief Returns the adapter device name of the specified monitor. * * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`) * of the specified monitor, or `NULL` if an [error](@ref error_handling) * occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); /*! @brief Returns the display device name of the specified monitor. * * @return The UTF-8 encoded display device name (for example * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); /*! @brief Returns the `HWND` of the specified window. * * @return The `HWND` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_WGL) /*! @brief Returns the `HGLRC` of the specified window. * * @return The `HGLRC` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_COCOA) /*! @brief Returns the `CGDirectDisplayID` of the specified monitor. * * @return The `CGDirectDisplayID` of the specified monitor, or * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); /*! @brief Returns the `NSWindow` of the specified window. * * @return The `NSWindow` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_NSGL) /*! @brief Returns the `NSOpenGLContext` of the specified window. * * @return The `NSOpenGLContext` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_X11) /*! @brief Returns the `Display` used by GLFW. * * @return The `Display` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI Display* glfwGetX11Display(void); /*! @brief Returns the `RRCrtc` of the specified monitor. * * @return The `RRCrtc` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); /*! @brief Returns the `RROutput` of the specified monitor. * * @return The `RROutput` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); /*! @brief Returns the `Window` of the specified window. * * @return The `Window` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI Window glfwGetX11Window(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_GLX) /*! @brief Returns the `GLXContext` of the specified window. * * @return The `GLXContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); /*! @brief Returns the `GLXWindow` of the specified window. * * @return The `GLXWindow` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) /*! @brief Returns the `struct wl_display*` used by GLFW. * * @return The `struct wl_display*` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); /*! @brief Returns the `struct wl_output*` of the specified monitor. * * @return The `struct wl_output*` of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); /*! @brief Returns the main `struct wl_surface*` of the specified window. * * @return The main `struct wl_surface*` of the specified window, or `NULL` if * an [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_MIR) /*! @brief Returns the `MirConnection*` used by GLFW. * * @return The `MirConnection*` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI MirConnection* glfwGetMirDisplay(void); /*! @brief Returns the Mir output ID of the specified monitor. * * @return The Mir output ID of the specified monitor, or zero if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor); /*! @brief Returns the `MirSurface*` of the specified window. * * @return The `MirSurface*` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_EGL) /*! @brief Returns the `EGLDisplay` used by GLFW. * * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI EGLDisplay glfwGetEGLDisplay(void); /*! @brief Returns the `EGLContext` of the specified window. * * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); /*! @brief Returns the `EGLSurface` of the specified window. * * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); #endif #ifdef __cplusplus } #endif #endif /* _glfw3_native_h_ */ ================================================ FILE: samples/vs2015/glfw-3.2-WIN64/COPYING.txt ================================================ Copyright (c) 2002-2006 Marcus Geelnard Copyright (c) 2006-2016 Camilla Berglund This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: samples/vs2015/glfw-3.2-WIN64/include/GLFW/glfw3.h ================================================ /************************************************************************* * GLFW 3.2 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard * Copyright (c) 2006-2016 Camilla Berglund * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would * be appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. * *************************************************************************/ #ifndef _glfw3_h_ #define _glfw3_h_ #ifdef __cplusplus extern "C" { #endif /************************************************************************* * Doxygen documentation *************************************************************************/ /*! @file glfw3.h * @brief The header of the GLFW 3 API. * * This is the header file of the GLFW 3 API. It defines all its types and * declares all its functions. * * For more information about how to use this file, see @ref build_include. */ /*! @defgroup context Context reference * * This is the reference documentation for OpenGL and OpenGL ES context related * functions. For more task-oriented information, see the @ref context_guide. */ /*! @defgroup vulkan Vulkan reference * * This is the reference documentation for Vulkan related functions and types. * For more task-oriented information, see the @ref vulkan_guide. */ /*! @defgroup init Initialization, version and error reference * * This is the reference documentation for initialization and termination of * the library, version management and error handling. For more task-oriented * information, see the @ref intro_guide. */ /*! @defgroup input Input reference * * This is the reference documentation for input related functions and types. * For more task-oriented information, see the @ref input_guide. */ /*! @defgroup monitor Monitor reference * * This is the reference documentation for monitor related functions and types. * For more task-oriented information, see the @ref monitor_guide. */ /*! @defgroup window Window reference * * This is the reference documentation for window related functions and types, * including creation, deletion and event polling. For more task-oriented * information, see the @ref window_guide. */ /************************************************************************* * Compiler- and platform-specific preprocessor work *************************************************************************/ /* If we are we on Windows, we want a single define for it. */ #if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)) #define _WIN32 #endif /* _WIN32 */ /* It is customary to use APIENTRY for OpenGL function pointer declarations on * all platforms. Additionally, the Windows OpenGL header needs APIENTRY. */ #ifndef APIENTRY #ifdef _WIN32 #define APIENTRY __stdcall #else #define APIENTRY #endif #endif /* APIENTRY */ /* Some Windows OpenGL headers need this. */ #if !defined(WINGDIAPI) && defined(_WIN32) #define WINGDIAPI __declspec(dllimport) #define GLFW_WINGDIAPI_DEFINED #endif /* WINGDIAPI */ /* Some Windows GLU headers need this. */ #if !defined(CALLBACK) && defined(_WIN32) #define CALLBACK __stdcall #define GLFW_CALLBACK_DEFINED #endif /* CALLBACK */ /* Most Windows GLU headers need wchar_t. * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h. * Include it unconditionally to avoid surprising side-effects. */ #include #include /* Include the chosen client API headers. */ #if defined(__APPLE__) #if defined(GLFW_INCLUDE_GLCOREARB) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif !defined(GLFW_INCLUDE_NONE) #if !defined(GLFW_INCLUDE_GLEXT) #define GL_GLEXT_LEGACY #endif #include #endif #if defined(GLFW_INCLUDE_GLU) #include #endif #else #if defined(GLFW_INCLUDE_GLCOREARB) #include #elif defined(GLFW_INCLUDE_ES1) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif defined(GLFW_INCLUDE_ES2) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif defined(GLFW_INCLUDE_ES3) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif defined(GLFW_INCLUDE_ES31) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #elif defined(GLFW_INCLUDE_VULKAN) #include #elif !defined(GLFW_INCLUDE_NONE) #include #if defined(GLFW_INCLUDE_GLEXT) #include #endif #endif #if defined(GLFW_INCLUDE_GLU) #include #endif #endif #if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) /* GLFW_DLL must be defined by applications that are linking against the DLL * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW * configuration header when compiling the DLL version of the library. */ #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined" #endif /* GLFWAPI is used to declare public API functions for export * from the DLL / shared library / dynamic library. */ #if defined(_WIN32) && defined(_GLFW_BUILD_DLL) /* We are building GLFW as a Win32 DLL */ #define GLFWAPI __declspec(dllexport) #elif defined(_WIN32) && defined(GLFW_DLL) /* We are calling GLFW as a Win32 DLL */ #define GLFWAPI __declspec(dllimport) #elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) /* We are building GLFW as a shared / dynamic library */ #define GLFWAPI __attribute__((visibility("default"))) #else /* We are building or calling GLFW as a static library */ #define GLFWAPI #endif /************************************************************************* * GLFW API tokens *************************************************************************/ /*! @name GLFW version macros * @{ */ /*! @brief The major version number of the GLFW library. * * This is incremented when the API is changed in non-compatible ways. * @ingroup init */ #define GLFW_VERSION_MAJOR 3 /*! @brief The minor version number of the GLFW library. * * This is incremented when features are added to the API but it remains * backward-compatible. * @ingroup init */ #define GLFW_VERSION_MINOR 2 /*! @brief The revision number of the GLFW library. * * This is incremented when a bug fix release is made that does not contain any * API changes. * @ingroup init */ #define GLFW_VERSION_REVISION 0 /*! @} */ /*! @name Boolean values * @{ */ /*! @brief One. * * One. Seriously. You don't _need_ to use this symbol in your code. It's * just semantic sugar for the number 1. You can use `1` or `true` or `_True` * or `GL_TRUE` or whatever you want. */ #define GLFW_TRUE 1 /*! @brief Zero. * * Zero. Seriously. You don't _need_ to use this symbol in your code. It's * just just semantic sugar for the number 0. You can use `0` or `false` or * `_False` or `GL_FALSE` or whatever you want. */ #define GLFW_FALSE 0 /*! @} */ /*! @name Key and button actions * @{ */ /*! @brief The key or mouse button was released. * * The key or mouse button was released. * * @ingroup input */ #define GLFW_RELEASE 0 /*! @brief The key or mouse button was pressed. * * The key or mouse button was pressed. * * @ingroup input */ #define GLFW_PRESS 1 /*! @brief The key was held down until it repeated. * * The key was held down until it repeated. * * @ingroup input */ #define GLFW_REPEAT 2 /*! @} */ /*! @defgroup keys Keyboard keys * * See [key input](@ref input_key) for how these are used. * * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60), * but re-arranged to map to 7-bit ASCII for printable keys (function keys are * put in the 256+ range). * * The naming of the key codes follow these rules: * - The US keyboard layout is used * - Names of printable alpha-numeric characters are used (e.g. "A", "R", * "3", etc.) * - For non-alphanumeric characters, Unicode:ish names are used (e.g. * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not * correspond to the Unicode standard (usually for brevity) * - Keys that lack a clear US mapping are named "WORLD_x" * - For non-printable keys, custom names are used (e.g. "F4", * "BACKSPACE", etc.) * * @ingroup input * @{ */ /* The unknown key */ #define GLFW_KEY_UNKNOWN -1 /* Printable keys */ #define GLFW_KEY_SPACE 32 #define GLFW_KEY_APOSTROPHE 39 /* ' */ #define GLFW_KEY_COMMA 44 /* , */ #define GLFW_KEY_MINUS 45 /* - */ #define GLFW_KEY_PERIOD 46 /* . */ #define GLFW_KEY_SLASH 47 /* / */ #define GLFW_KEY_0 48 #define GLFW_KEY_1 49 #define GLFW_KEY_2 50 #define GLFW_KEY_3 51 #define GLFW_KEY_4 52 #define GLFW_KEY_5 53 #define GLFW_KEY_6 54 #define GLFW_KEY_7 55 #define GLFW_KEY_8 56 #define GLFW_KEY_9 57 #define GLFW_KEY_SEMICOLON 59 /* ; */ #define GLFW_KEY_EQUAL 61 /* = */ #define GLFW_KEY_A 65 #define GLFW_KEY_B 66 #define GLFW_KEY_C 67 #define GLFW_KEY_D 68 #define GLFW_KEY_E 69 #define GLFW_KEY_F 70 #define GLFW_KEY_G 71 #define GLFW_KEY_H 72 #define GLFW_KEY_I 73 #define GLFW_KEY_J 74 #define GLFW_KEY_K 75 #define GLFW_KEY_L 76 #define GLFW_KEY_M 77 #define GLFW_KEY_N 78 #define GLFW_KEY_O 79 #define GLFW_KEY_P 80 #define GLFW_KEY_Q 81 #define GLFW_KEY_R 82 #define GLFW_KEY_S 83 #define GLFW_KEY_T 84 #define GLFW_KEY_U 85 #define GLFW_KEY_V 86 #define GLFW_KEY_W 87 #define GLFW_KEY_X 88 #define GLFW_KEY_Y 89 #define GLFW_KEY_Z 90 #define GLFW_KEY_LEFT_BRACKET 91 /* [ */ #define GLFW_KEY_BACKSLASH 92 /* \ */ #define GLFW_KEY_RIGHT_BRACKET 93 /* ] */ #define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ #define GLFW_KEY_WORLD_1 161 /* non-US #1 */ #define GLFW_KEY_WORLD_2 162 /* non-US #2 */ /* Function keys */ #define GLFW_KEY_ESCAPE 256 #define GLFW_KEY_ENTER 257 #define GLFW_KEY_TAB 258 #define GLFW_KEY_BACKSPACE 259 #define GLFW_KEY_INSERT 260 #define GLFW_KEY_DELETE 261 #define GLFW_KEY_RIGHT 262 #define GLFW_KEY_LEFT 263 #define GLFW_KEY_DOWN 264 #define GLFW_KEY_UP 265 #define GLFW_KEY_PAGE_UP 266 #define GLFW_KEY_PAGE_DOWN 267 #define GLFW_KEY_HOME 268 #define GLFW_KEY_END 269 #define GLFW_KEY_CAPS_LOCK 280 #define GLFW_KEY_SCROLL_LOCK 281 #define GLFW_KEY_NUM_LOCK 282 #define GLFW_KEY_PRINT_SCREEN 283 #define GLFW_KEY_PAUSE 284 #define GLFW_KEY_F1 290 #define GLFW_KEY_F2 291 #define GLFW_KEY_F3 292 #define GLFW_KEY_F4 293 #define GLFW_KEY_F5 294 #define GLFW_KEY_F6 295 #define GLFW_KEY_F7 296 #define GLFW_KEY_F8 297 #define GLFW_KEY_F9 298 #define GLFW_KEY_F10 299 #define GLFW_KEY_F11 300 #define GLFW_KEY_F12 301 #define GLFW_KEY_F13 302 #define GLFW_KEY_F14 303 #define GLFW_KEY_F15 304 #define GLFW_KEY_F16 305 #define GLFW_KEY_F17 306 #define GLFW_KEY_F18 307 #define GLFW_KEY_F19 308 #define GLFW_KEY_F20 309 #define GLFW_KEY_F21 310 #define GLFW_KEY_F22 311 #define GLFW_KEY_F23 312 #define GLFW_KEY_F24 313 #define GLFW_KEY_F25 314 #define GLFW_KEY_KP_0 320 #define GLFW_KEY_KP_1 321 #define GLFW_KEY_KP_2 322 #define GLFW_KEY_KP_3 323 #define GLFW_KEY_KP_4 324 #define GLFW_KEY_KP_5 325 #define GLFW_KEY_KP_6 326 #define GLFW_KEY_KP_7 327 #define GLFW_KEY_KP_8 328 #define GLFW_KEY_KP_9 329 #define GLFW_KEY_KP_DECIMAL 330 #define GLFW_KEY_KP_DIVIDE 331 #define GLFW_KEY_KP_MULTIPLY 332 #define GLFW_KEY_KP_SUBTRACT 333 #define GLFW_KEY_KP_ADD 334 #define GLFW_KEY_KP_ENTER 335 #define GLFW_KEY_KP_EQUAL 336 #define GLFW_KEY_LEFT_SHIFT 340 #define GLFW_KEY_LEFT_CONTROL 341 #define GLFW_KEY_LEFT_ALT 342 #define GLFW_KEY_LEFT_SUPER 343 #define GLFW_KEY_RIGHT_SHIFT 344 #define GLFW_KEY_RIGHT_CONTROL 345 #define GLFW_KEY_RIGHT_ALT 346 #define GLFW_KEY_RIGHT_SUPER 347 #define GLFW_KEY_MENU 348 #define GLFW_KEY_LAST GLFW_KEY_MENU /*! @} */ /*! @defgroup mods Modifier key flags * * See [key input](@ref input_key) for how these are used. * * @ingroup input * @{ */ /*! @brief If this bit is set one or more Shift keys were held down. */ #define GLFW_MOD_SHIFT 0x0001 /*! @brief If this bit is set one or more Control keys were held down. */ #define GLFW_MOD_CONTROL 0x0002 /*! @brief If this bit is set one or more Alt keys were held down. */ #define GLFW_MOD_ALT 0x0004 /*! @brief If this bit is set one or more Super keys were held down. */ #define GLFW_MOD_SUPER 0x0008 /*! @} */ /*! @defgroup buttons Mouse buttons * * See [mouse button input](@ref input_mouse_button) for how these are used. * * @ingroup input * @{ */ #define GLFW_MOUSE_BUTTON_1 0 #define GLFW_MOUSE_BUTTON_2 1 #define GLFW_MOUSE_BUTTON_3 2 #define GLFW_MOUSE_BUTTON_4 3 #define GLFW_MOUSE_BUTTON_5 4 #define GLFW_MOUSE_BUTTON_6 5 #define GLFW_MOUSE_BUTTON_7 6 #define GLFW_MOUSE_BUTTON_8 7 #define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8 #define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1 #define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2 #define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3 /*! @} */ /*! @defgroup joysticks Joysticks * * See [joystick input](@ref joystick) for how these are used. * * @ingroup input * @{ */ #define GLFW_JOYSTICK_1 0 #define GLFW_JOYSTICK_2 1 #define GLFW_JOYSTICK_3 2 #define GLFW_JOYSTICK_4 3 #define GLFW_JOYSTICK_5 4 #define GLFW_JOYSTICK_6 5 #define GLFW_JOYSTICK_7 6 #define GLFW_JOYSTICK_8 7 #define GLFW_JOYSTICK_9 8 #define GLFW_JOYSTICK_10 9 #define GLFW_JOYSTICK_11 10 #define GLFW_JOYSTICK_12 11 #define GLFW_JOYSTICK_13 12 #define GLFW_JOYSTICK_14 13 #define GLFW_JOYSTICK_15 14 #define GLFW_JOYSTICK_16 15 #define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16 /*! @} */ /*! @defgroup errors Error codes * * See [error handling](@ref error_handling) for how these are used. * * @ingroup init * @{ */ /*! @brief GLFW has not been initialized. * * This occurs if a GLFW function was called that must not be called unless the * library is [initialized](@ref intro_init). * * @analysis Application programmer error. Initialize GLFW before calling any * function that requires initialization. */ #define GLFW_NOT_INITIALIZED 0x00010001 /*! @brief No context is current for this thread. * * This occurs if a GLFW function was called that needs and operates on the * current OpenGL or OpenGL ES context but no context is current on the calling * thread. One such function is @ref glfwSwapInterval. * * @analysis Application programmer error. Ensure a context is current before * calling functions that require a current context. */ #define GLFW_NO_CURRENT_CONTEXT 0x00010002 /*! @brief One of the arguments to the function was an invalid enum value. * * One of the arguments to the function was an invalid enum value, for example * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref * glfwGetWindowAttrib. * * @analysis Application programmer error. Fix the offending call. */ #define GLFW_INVALID_ENUM 0x00010003 /*! @brief One of the arguments to the function was an invalid value. * * One of the arguments to the function was an invalid value, for example * requesting a non-existent OpenGL or OpenGL ES version like 2.7. * * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead * result in a @ref GLFW_VERSION_UNAVAILABLE error. * * @analysis Application programmer error. Fix the offending call. */ #define GLFW_INVALID_VALUE 0x00010004 /*! @brief A memory allocation failed. * * A memory allocation failed. * * @analysis A bug in GLFW or the underlying operating system. Report the bug * to our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_OUT_OF_MEMORY 0x00010005 /*! @brief GLFW could not find support for the requested API on the system. * * GLFW could not find support for the requested API on the system. * * @analysis The installed graphics driver does not support the requested * API, or does not support it via the chosen context creation backend. * Below are a few examples. * * @par * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only * supports OpenGL ES via EGL, while Nvidia and Intel only support it via * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary * driver. Older graphics drivers do not support Vulkan. */ #define GLFW_API_UNAVAILABLE 0x00010006 /*! @brief The requested OpenGL or OpenGL ES version is not available. * * The requested OpenGL or OpenGL ES version (including any requested context * or framebuffer hints) is not available on this machine. * * @analysis The machine does not support your requirements. If your * application is sufficiently flexible, downgrade your requirements and try * again. Otherwise, inform the user that their machine does not match your * requirements. * * @par * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 * comes out before the 4.x series gets that far, also fail with this error and * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions * will exist. */ #define GLFW_VERSION_UNAVAILABLE 0x00010007 /*! @brief A platform-specific error occurred that does not match any of the * more specific categories. * * A platform-specific error occurred that does not match any of the more * specific categories. * * @analysis A bug or configuration error in GLFW, the underlying operating * system or its drivers, or a lack of required resources. Report the issue to * our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_PLATFORM_ERROR 0x00010008 /*! @brief The requested format is not supported or available. * * If emitted during window creation, the requested pixel format is not * supported. * * If emitted when querying the clipboard, the contents of the clipboard could * not be converted to the requested format. * * @analysis If emitted during window creation, one or more * [hard constraints](@ref window_hints_hard) did not match any of the * available pixel formats. If your application is sufficiently flexible, * downgrade your requirements and try again. Otherwise, inform the user that * their machine does not match your requirements. * * @par * If emitted when querying the clipboard, ignore the error or report it to * the user, as appropriate. */ #define GLFW_FORMAT_UNAVAILABLE 0x00010009 /*! @brief The specified window does not have an OpenGL or OpenGL ES context. * * A window that does not have an OpenGL or OpenGL ES context was passed to * a function that requires it to have one. * * @analysis Application programmer error. Fix the offending call. */ #define GLFW_NO_WINDOW_CONTEXT 0x0001000A /*! @} */ #define GLFW_FOCUSED 0x00020001 #define GLFW_ICONIFIED 0x00020002 #define GLFW_RESIZABLE 0x00020003 #define GLFW_VISIBLE 0x00020004 #define GLFW_DECORATED 0x00020005 #define GLFW_AUTO_ICONIFY 0x00020006 #define GLFW_FLOATING 0x00020007 #define GLFW_MAXIMIZED 0x00020008 #define GLFW_RED_BITS 0x00021001 #define GLFW_GREEN_BITS 0x00021002 #define GLFW_BLUE_BITS 0x00021003 #define GLFW_ALPHA_BITS 0x00021004 #define GLFW_DEPTH_BITS 0x00021005 #define GLFW_STENCIL_BITS 0x00021006 #define GLFW_ACCUM_RED_BITS 0x00021007 #define GLFW_ACCUM_GREEN_BITS 0x00021008 #define GLFW_ACCUM_BLUE_BITS 0x00021009 #define GLFW_ACCUM_ALPHA_BITS 0x0002100A #define GLFW_AUX_BUFFERS 0x0002100B #define GLFW_STEREO 0x0002100C #define GLFW_SAMPLES 0x0002100D #define GLFW_SRGB_CAPABLE 0x0002100E #define GLFW_REFRESH_RATE 0x0002100F #define GLFW_DOUBLEBUFFER 0x00021010 #define GLFW_CLIENT_API 0x00022001 #define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 #define GLFW_CONTEXT_VERSION_MINOR 0x00022003 #define GLFW_CONTEXT_REVISION 0x00022004 #define GLFW_CONTEXT_ROBUSTNESS 0x00022005 #define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 #define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 #define GLFW_OPENGL_PROFILE 0x00022008 #define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 #define GLFW_CONTEXT_NO_ERROR 0x0002200A #define GLFW_CONTEXT_CREATION_API 0x0002200B #define GLFW_NO_API 0 #define GLFW_OPENGL_API 0x00030001 #define GLFW_OPENGL_ES_API 0x00030002 #define GLFW_NO_ROBUSTNESS 0 #define GLFW_NO_RESET_NOTIFICATION 0x00031001 #define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002 #define GLFW_OPENGL_ANY_PROFILE 0 #define GLFW_OPENGL_CORE_PROFILE 0x00032001 #define GLFW_OPENGL_COMPAT_PROFILE 0x00032002 #define GLFW_CURSOR 0x00033001 #define GLFW_STICKY_KEYS 0x00033002 #define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 #define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_HIDDEN 0x00034002 #define GLFW_CURSOR_DISABLED 0x00034003 #define GLFW_ANY_RELEASE_BEHAVIOR 0 #define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 #define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002 #define GLFW_NATIVE_CONTEXT_API 0x00036001 #define GLFW_EGL_CONTEXT_API 0x00036002 /*! @defgroup shapes Standard cursor shapes * * See [standard cursor creation](@ref cursor_standard) for how these are used. * * @ingroup input * @{ */ /*! @brief The regular arrow cursor shape. * * The regular arrow cursor. */ #define GLFW_ARROW_CURSOR 0x00036001 /*! @brief The text input I-beam cursor shape. * * The text input I-beam cursor shape. */ #define GLFW_IBEAM_CURSOR 0x00036002 /*! @brief The crosshair shape. * * The crosshair shape. */ #define GLFW_CROSSHAIR_CURSOR 0x00036003 /*! @brief The hand shape. * * The hand shape. */ #define GLFW_HAND_CURSOR 0x00036004 /*! @brief The horizontal resize arrow shape. * * The horizontal resize arrow shape. */ #define GLFW_HRESIZE_CURSOR 0x00036005 /*! @brief The vertical resize arrow shape. * * The vertical resize arrow shape. */ #define GLFW_VRESIZE_CURSOR 0x00036006 /*! @} */ #define GLFW_CONNECTED 0x00040001 #define GLFW_DISCONNECTED 0x00040002 #define GLFW_DONT_CARE -1 /************************************************************************* * GLFW API types *************************************************************************/ /*! @brief Client API function pointer type. * * Generic function pointer used for returning client API function pointers * without forcing a cast from a regular pointer. * * @sa @ref context_glext * @sa glfwGetProcAddress * * @since Added in version 3.0. * @ingroup context */ typedef void (*GLFWglproc)(void); /*! @brief Vulkan API function pointer type. * * Generic function pointer used for returning Vulkan API function pointers * without forcing a cast from a regular pointer. * * @sa @ref vulkan_proc * @sa glfwGetInstanceProcAddress * * @since Added in version 3.2. * * @ingroup vulkan */ typedef void (*GLFWvkproc)(void); /*! @brief Opaque monitor object. * * Opaque monitor object. * * @see @ref monitor_object * * @since Added in version 3.0. * * @ingroup monitor */ typedef struct GLFWmonitor GLFWmonitor; /*! @brief Opaque window object. * * Opaque window object. * * @see @ref window_object * * @since Added in version 3.0. * * @ingroup window */ typedef struct GLFWwindow GLFWwindow; /*! @brief Opaque cursor object. * * Opaque cursor object. * * @see @ref cursor_object * * @since Added in version 3.1. * * @ingroup cursor */ typedef struct GLFWcursor GLFWcursor; /*! @brief The function signature for error callbacks. * * This is the function signature for error callback functions. * * @param[in] error An [error code](@ref errors). * @param[in] description A UTF-8 encoded string describing the error. * * @sa @ref error_handling * @sa glfwSetErrorCallback * * @since Added in version 3.0. * * @ingroup init */ typedef void (* GLFWerrorfun)(int,const char*); /*! @brief The function signature for window position callbacks. * * This is the function signature for window position callback functions. * * @param[in] window The window that was moved. * @param[in] xpos The new x-coordinate, in screen coordinates, of the * upper-left corner of the client area of the window. * @param[in] ypos The new y-coordinate, in screen coordinates, of the * upper-left corner of the client area of the window. * * @sa @ref window_pos * @sa glfwSetWindowPosCallback * * @since Added in version 3.0. * * @ingroup window */ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); /*! @brief The function signature for window resize callbacks. * * This is the function signature for window size callback functions. * * @param[in] window The window that was resized. * @param[in] width The new width, in screen coordinates, of the window. * @param[in] height The new height, in screen coordinates, of the window. * * @sa @ref window_size * @sa glfwSetWindowSizeCallback * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); /*! @brief The function signature for window close callbacks. * * This is the function signature for window close callback functions. * * @param[in] window The window that the user attempted to close. * * @sa @ref window_close * @sa glfwSetWindowCloseCallback * * @since Added in version 2.5. * @glfw3 Added window handle parameter. * * @ingroup window */ typedef void (* GLFWwindowclosefun)(GLFWwindow*); /*! @brief The function signature for window content refresh callbacks. * * This is the function signature for window refresh callback functions. * * @param[in] window The window whose content needs to be refreshed. * * @sa @ref window_refresh * @sa glfwSetWindowRefreshCallback * * @since Added in version 2.5. * @glfw3 Added window handle parameter. * * @ingroup window */ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); /*! @brief The function signature for window focus/defocus callbacks. * * This is the function signature for window focus callback functions. * * @param[in] window The window that gained or lost input focus. * @param[in] focused `GLFW_TRUE` if the window was given input focus, or * `GLFW_FALSE` if it lost it. * * @sa @ref window_focus * @sa glfwSetWindowFocusCallback * * @since Added in version 3.0. * * @ingroup window */ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); /*! @brief The function signature for window iconify/restore callbacks. * * This is the function signature for window iconify/restore callback * functions. * * @param[in] window The window that was iconified or restored. * @param[in] iconified `GLFW_TRUE` if the window was iconified, or * `GLFW_FALSE` if it was restored. * * @sa @ref window_iconify * @sa glfwSetWindowIconifyCallback * * @since Added in version 3.0. * * @ingroup window */ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); /*! @brief The function signature for framebuffer resize callbacks. * * This is the function signature for framebuffer resize callback * functions. * * @param[in] window The window whose framebuffer was resized. * @param[in] width The new width, in pixels, of the framebuffer. * @param[in] height The new height, in pixels, of the framebuffer. * * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * * @since Added in version 3.0. * * @ingroup window */ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); /*! @brief The function signature for mouse button callbacks. * * This is the function signature for mouse button callback functions. * * @param[in] window The window that received the event. * @param[in] button The [mouse button](@ref buttons) that was pressed or * released. * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * * @sa @ref input_mouse_button * @sa glfwSetMouseButtonCallback * * @since Added in version 1.0. * @glfw3 Added window handle and modifier mask parameters. * * @ingroup input */ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); /*! @brief The function signature for cursor position callbacks. * * This is the function signature for cursor position callback functions. * * @param[in] window The window that received the event. * @param[in] xpos The new cursor x-coordinate, relative to the left edge of * the client area. * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the * client area. * * @sa @ref cursor_pos * @sa glfwSetCursorPosCallback * * @since Added in version 3.0. Replaces `GLFWmouseposfun`. * * @ingroup input */ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); /*! @brief The function signature for cursor enter/leave callbacks. * * This is the function signature for cursor enter/leave callback functions. * * @param[in] window The window that received the event. * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client * area, or `GLFW_FALSE` if it left it. * * @sa @ref cursor_enter * @sa glfwSetCursorEnterCallback * * @since Added in version 3.0. * * @ingroup input */ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); /*! @brief The function signature for scroll callbacks. * * This is the function signature for scroll callback functions. * * @param[in] window The window that received the event. * @param[in] xoffset The scroll offset along the x-axis. * @param[in] yoffset The scroll offset along the y-axis. * * @sa @ref scrolling * @sa glfwSetScrollCallback * * @since Added in version 3.0. Replaces `GLFWmousewheelfun`. * * @ingroup input */ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); /*! @brief The function signature for keyboard key callbacks. * * This is the function signature for keyboard key callback functions. * * @param[in] window The window that received the event. * @param[in] key The [keyboard key](@ref keys) that was pressed or released. * @param[in] scancode The system-specific scancode of the key. * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * * @sa @ref input_key * @sa glfwSetKeyCallback * * @since Added in version 1.0. * @glfw3 Added window handle, scancode and modifier mask parameters. * * @ingroup input */ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); /*! @brief The function signature for Unicode character callbacks. * * This is the function signature for Unicode character callback functions. * * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the character. * * @sa @ref input_char * @sa glfwSetCharCallback * * @since Added in version 2.4. * @glfw3 Added window handle parameter. * * @ingroup input */ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); /*! @brief The function signature for Unicode character with modifiers * callbacks. * * This is the function signature for Unicode character with modifiers callback * functions. It is called for each input character, regardless of what * modifier keys are held down. * * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the character. * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * * @sa @ref input_char * @sa glfwSetCharModsCallback * * @since Added in version 3.1. * * @ingroup input */ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); /*! @brief The function signature for file drop callbacks. * * This is the function signature for file drop callbacks. * * @param[in] window The window that received the event. * @param[in] count The number of dropped files. * @param[in] paths The UTF-8 encoded file and/or directory path names. * * @sa @ref path_drop * @sa glfwSetDropCallback * * @since Added in version 3.1. * * @ingroup input */ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); /*! @brief The function signature for monitor configuration callbacks. * * This is the function signature for monitor configuration callback functions. * * @param[in] monitor The monitor that was connected or disconnected. * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. * * @sa @ref monitor_event * @sa glfwSetMonitorCallback * * @since Added in version 3.0. * * @ingroup monitor */ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); /*! @brief The function signature for joystick configuration callbacks. * * This is the function signature for joystick configuration callback * functions. * * @param[in] joy The joystick that was connected or disconnected. * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. * * @sa @ref joystick_event * @sa glfwSetJoystickCallback * * @since Added in version 3.2. * * @ingroup input */ typedef void (* GLFWjoystickfun)(int,int); /*! @brief Video mode type. * * This describes a single video mode. * * @sa @ref monitor_modes * @sa glfwGetVideoMode glfwGetVideoModes * * @since Added in version 1.0. * @glfw3 Added refresh rate member. * * @ingroup monitor */ typedef struct GLFWvidmode { /*! The width, in screen coordinates, of the video mode. */ int width; /*! The height, in screen coordinates, of the video mode. */ int height; /*! The bit depth of the red channel of the video mode. */ int redBits; /*! The bit depth of the green channel of the video mode. */ int greenBits; /*! The bit depth of the blue channel of the video mode. */ int blueBits; /*! The refresh rate, in Hz, of the video mode. */ int refreshRate; } GLFWvidmode; /*! @brief Gamma ramp. * * This describes the gamma ramp for a monitor. * * @sa @ref monitor_gamma * @sa glfwGetGammaRamp glfwSetGammaRamp * * @since Added in version 3.0. * * @ingroup monitor */ typedef struct GLFWgammaramp { /*! An array of value describing the response of the red channel. */ unsigned short* red; /*! An array of value describing the response of the green channel. */ unsigned short* green; /*! An array of value describing the response of the blue channel. */ unsigned short* blue; /*! The number of elements in each array. */ unsigned int size; } GLFWgammaramp; /*! @brief Image data. * * @sa @ref cursor_custom * * @since Added in version 2.1. * @glfw3 Removed format and bytes-per-pixel members. */ typedef struct GLFWimage { /*! The width, in pixels, of this image. */ int width; /*! The height, in pixels, of this image. */ int height; /*! The pixel data of this image, arranged left-to-right, top-to-bottom. */ unsigned char* pixels; } GLFWimage; /************************************************************************* * GLFW API functions *************************************************************************/ /*! @brief Initializes the GLFW library. * * This function initializes the GLFW library. Before most GLFW functions can * be used, GLFW must be initialized, and before an application terminates GLFW * should be terminated in order to free any resources allocated during or * after initialization. * * If this function fails, it calls @ref glfwTerminate before returning. If it * succeeds, you should call @ref glfwTerminate before the application exits. * * Additional calls to this function after successful initialization but before * termination will return `GLFW_TRUE` immediately. * * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. * * @remark @osx This function will change the current directory of the * application to the `Contents/Resources` subdirectory of the application's * bundle, if present. This can be disabled with a * [compile-time option](@ref compile_options_osx). * * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init * @sa glfwTerminate * * @since Added in version 1.0. * * @ingroup init */ GLFWAPI int glfwInit(void); /*! @brief Terminates the GLFW library. * * This function destroys all remaining windows and cursors, restores any * modified gamma ramps and frees any other allocated resources. Once this * function is called, you must again call @ref glfwInit successfully before * you will be able to use most GLFW functions. * * If GLFW has been successfully initialized, this function should be called * before the application exits. If initialization fails, there is no need to * call this function, as it is called by @ref glfwInit before it returns * failure. * * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. * * @remark This function may be called before @ref glfwInit. * * @warning The contexts of any remaining windows must not be current on any * other thread when this function is called. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init * @sa glfwInit * * @since Added in version 1.0. * * @ingroup init */ GLFWAPI void glfwTerminate(void); /*! @brief Retrieves the version of the GLFW library. * * This function retrieves the major, minor and revision numbers of the GLFW * library. It is intended for when you are using GLFW as a shared library and * want to ensure that you are using the minimum required version. * * Any or all of the version arguments may be `NULL`. * * @param[out] major Where to store the major version number, or `NULL`. * @param[out] minor Where to store the minor version number, or `NULL`. * @param[out] rev Where to store the revision number, or `NULL`. * * @errors None. * * @remark This function may be called before @ref glfwInit. * * @thread_safety This function may be called from any thread. * * @sa @ref intro_version * @sa glfwGetVersionString * * @since Added in version 1.0. * * @ingroup init */ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); /*! @brief Returns a string describing the compile-time configuration. * * This function returns the compile-time generated * [version string](@ref intro_version_string) of the GLFW library binary. It * describes the version, platform, compiler and any platform-specific * compile-time options. It should not be confused with the OpenGL or OpenGL * ES version string, queried with `glGetString`. * * __Do not use the version string__ to parse the GLFW library version. The * @ref glfwGetVersion function provides the version of the running library * binary in numerical format. * * @return The ASCII encoded GLFW version string. * * @errors None. * * @remark This function may be called before @ref glfwInit. * * @pointer_lifetime The returned string is static and compile-time generated. * * @thread_safety This function may be called from any thread. * * @sa @ref intro_version * @sa glfwGetVersion * * @since Added in version 3.0. * * @ingroup init */ GLFWAPI const char* glfwGetVersionString(void); /*! @brief Sets the error callback. * * This function sets the error callback, which is called with an error code * and a human-readable description each time a GLFW error occurs. * * The error callback is called on the thread where the error occurred. If you * are using GLFW from multiple threads, your error callback needs to be * written accordingly. * * Because the description string may have been generated specifically for that * error, it is not guaranteed to be valid after the callback has returned. If * you wish to use it after the callback returns, you need to make a copy. * * Once set, the error callback remains set even after the library has been * terminated. * * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set. * * @errors None. * * @remark This function may be called before @ref glfwInit. * * @thread_safety This function must only be called from the main thread. * * @sa @ref error_handling * * @since Added in version 3.0. * * @ingroup init */ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); /*! @brief Returns the currently connected monitors. * * This function returns an array of handles for all currently connected * monitors. The primary monitor is always first in the returned array. If no * monitors were found, this function returns `NULL`. * * @param[out] count Where to store the number of monitors in the returned * array. This is set to zero if an error occurred. * @return An array of monitor handles, or `NULL` if no monitors were found or * if an [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is guaranteed to be valid only until the * monitor configuration changes or the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_monitors * @sa @ref monitor_event * @sa glfwGetPrimaryMonitor * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); /*! @brief Returns the primary monitor. * * This function returns the primary monitor. This is usually the monitor * where elements like the task bar or global menu bar are located. * * @return The primary monitor, or `NULL` if no monitors were found or if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @remark The primary monitor is always first in the array returned by @ref * glfwGetMonitors. * * @sa @ref monitor_monitors * @sa glfwGetMonitors * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); /*! @brief Returns the position of the monitor's viewport on the virtual screen. * * This function returns the position, in screen coordinates, of the upper-left * corner of the specified monitor. * * Any or all of the position arguments may be `NULL`. If an error occurs, all * non-`NULL` position arguments will be set to zero. * * @param[in] monitor The monitor to query. * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); /*! @brief Returns the physical size of the monitor. * * This function returns the size, in millimetres, of the display area of the * specified monitor. * * Some systems do not provide accurate monitor size information, either * because the monitor * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data) * data is incorrect or because the driver does not report it accurately. * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. * * @param[in] monitor The monitor to query. * @param[out] widthMM Where to store the width, in millimetres, of the * monitor's display area, or `NULL`. * @param[out] heightMM Where to store the height, in millimetres, of the * monitor's display area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @remark @win32 calculates the returned physical size from the * current resolution and system DPI instead of querying the monitor EDID data. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM); /*! @brief Returns the name of the specified monitor. * * This function returns a human-readable name, encoded as UTF-8, of the * specified monitor. The name typically reflects the make and model of the * monitor and is not guaranteed to be unique among the connected monitors. * * @param[in] monitor The monitor to query. * @return The UTF-8 encoded name of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected or the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); /*! @brief Sets the monitor configuration callback. * * This function sets the monitor configuration callback, or removes the * currently set callback. This is called when a monitor is connected to or * disconnected from the system. * * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_event * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); /*! @brief Returns the available video modes for the specified monitor. * * This function returns an array of all video modes supported by the specified * monitor. The returned array is sorted in ascending order, first by color * bit depth (the sum of all channel depths) and then by resolution area (the * product of width and height). * * @param[in] monitor The monitor to query. * @param[out] count Where to store the number of video modes in the returned * array. This is set to zero if an error occurred. * @return An array of video modes, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected, this function is called again for that monitor or the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_modes * @sa glfwGetVideoMode * * @since Added in version 1.0. * @glfw3 Changed to return an array of modes for a specific monitor. * * @ingroup monitor */ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); /*! @brief Returns the current mode of the specified monitor. * * This function returns the current video mode of the specified monitor. If * you have created a full screen window for that monitor, the return value * will depend on whether that window is iconified. * * @param[in] monitor The monitor to query. * @return The current mode of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified monitor is * disconnected or the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_modes * @sa glfwGetVideoModes * * @since Added in version 3.0. Replaces `glfwGetDesktopMode`. * * @ingroup monitor */ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); /*! @brief Generates a gamma ramp and sets it for the specified monitor. * * This function generates a 256-element gamma ramp from the specified exponent * and then calls @ref glfwSetGammaRamp with it. The value must be a finite * number greater than zero. * * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] gamma The desired exponent. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); /*! @brief Returns the current gamma ramp for the specified monitor. * * This function returns the current gamma ramp of the specified monitor. * * @param[in] monitor The monitor to query. * @return The current gamma ramp, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned structure and its arrays are allocated and * freed by GLFW. You should not free them yourself. They are valid until the * specified monitor is disconnected, this function is called again for that * monitor or the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); /*! @brief Sets the current gamma ramp for the specified monitor. * * This function sets the current gamma ramp for the specified monitor. The * original gamma ramp for that monitor is saved by GLFW the first time this * function is called and is restored by @ref glfwTerminate. * * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] ramp The gamma ramp to use. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @remark Gamma ramp sizes other than 256 are not supported by all platforms * or graphics hardware. * * @remark @win32 The gamma ramp size must be 256. * * @pointer_lifetime The specified gamma ramp is copied before this function * returns. * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * * @since Added in version 3.0. * * @ingroup monitor */ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); /*! @brief Resets all window hints to their default values. * * This function resets all window hints to their * [default values](@ref window_hints_values). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints * @sa glfwWindowHint * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwDefaultWindowHints(void); /*! @brief Sets the specified window hint to the desired value. * * This function sets hints for the next call to @ref glfwCreateWindow. The * hints, once set, retain their values until changed by a call to @ref * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is * terminated. * * This function does not check whether the specified hint values are valid. * If you set hints to invalid values this will instead be reported by the next * call to @ref glfwCreateWindow. * * @param[in] hint The [window hint](@ref window_hints) to set. * @param[in] value The new value of the window hint. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints * @sa glfwDefaultWindowHints * * @since Added in version 3.0. Replaces `glfwOpenWindowHint`. * * @ingroup window */ GLFWAPI void glfwWindowHint(int hint, int value); /*! @brief Creates a window and its associated context. * * This function creates a window and its associated OpenGL or OpenGL ES * context. Most of the options controlling how the window and its context * should be created are specified with [window hints](@ref window_hints). * * Successful creation does not change which context is current. Before you * can use the newly created context, you need to * [make it current](@ref context_current). For information about the `share` * parameter, see @ref context_sharing. * * The created window, framebuffer and context may differ from what you * requested, as not all parameters and hints are * [hard constraints](@ref window_hints_hard). This includes the size of the * window, especially for full screen windows. To query the actual attributes * of the created window, framebuffer and context, see @ref * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. * * To create a full screen window, you need to specify the monitor the window * will cover. If no monitor is specified, the window will be windowed mode. * Unless you have a way for the user to choose a specific monitor, it is * recommended that you pick the primary monitor. For more information on how * to query connected monitors, see @ref monitor_monitors. * * For full screen windows, the specified size becomes the resolution of the * window's _desired video mode_. As long as a full screen window is not * iconified, the supported video mode most closely matching the desired video * mode is set for the specified monitor. For more information about full * screen windows, including the creation of so called _windowed full screen_ * or _borderless full screen_ windows, see @ref window_windowed_full_screen. * * By default, newly created windows use the placement recommended by the * window system. To create the window at a specific position, make it * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window * hint, set its [position](@ref window_pos) and then [show](@ref window_hide) * it. * * As long as at least one full screen window is not iconified, the screensaver * is prohibited from starting. * * Window systems put limits on window sizes. Very large or very small window * dimensions may be overridden by the window system on creation. Check the * actual [size](@ref window_size) after creation. * * The [swap interval](@ref buffer_swap) is not set during window creation and * the initial value may vary depending on driver settings and defaults. * * @param[in] width The desired width, in screen coordinates, of the window. * This must be greater than zero. * @param[in] height The desired height, in screen coordinates, of the window. * This must be greater than zero. * @param[in] title The initial, UTF-8 encoded window title. * @param[in] monitor The monitor to use for full screen mode, or `NULL` for * windowed mode. * @param[in] share The window whose context to share resources with, or `NULL` * to not share resources. * @return The handle of the created window, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref * GLFW_PLATFORM_ERROR. * * @remark @win32 Window creation will fail if the Microsoft GDI software * OpenGL implementation is the only one available. * * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it * will be set as the initial icon for the window. If no such icon is present, * the `IDI_WINLOGO` icon will be used instead. To set a different icon, see * @ref glfwSetWindowIcon. * * @remark @win32 The context to share resources with must not be current on * any other thread. * * @remark @osx The GLFW window has no icon, as it is not a document * window, but the dock icon will be the same as the application bundle's icon. * For more information on bundles, see the * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) * in the Mac Developer Library. * * @remark @osx The first time a window is created the menu bar is populated * with common commands like Hide, Quit and About. The About entry opens * a minimal about dialog with information from the application's bundle. The * menu bar can be disabled with a * [compile-time option](@ref compile_options_osx). * * @remark @osx On OS X 10.10 and later the window frame will not be rendered * at full resolution on Retina displays unless the `NSHighResolutionCapable` * key is enabled in the application bundle's `Info.plist`. For more * information, see * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html) * in the Mac Developer Library. The GLFW test and example programs use * a custom `Info.plist` template for this, which can be found as * `CMake/MacOSXBundleInfo.plist.in` in the source tree. * * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. * * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for * a window to reach its requested state. This means you may not be able to * query the final size, position or other attributes directly after window * creation. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation * @sa glfwDestroyWindow * * @since Added in version 3.0. Replaces `glfwOpenWindow`. * * @ingroup window */ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share); /*! @brief Destroys the specified window and its context. * * This function destroys the specified window and its context. On calling * this function, no further callbacks will be called for that window. * * If the context of the specified window is current on the main thread, it is * detached before being destroyed. * * @param[in] window The window to destroy. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @note The context of the specified window must not be current on any other * thread when this function is called. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation * @sa glfwCreateWindow * * @since Added in version 3.0. Replaces `glfwCloseWindow`. * * @ingroup window */ GLFWAPI void glfwDestroyWindow(GLFWwindow* window); /*! @brief Checks the close flag of the specified window. * * This function returns the value of the close flag of the specified window. * * @param[in] window The window to query. * @return The value of the close flag. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @sa @ref window_close * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); /*! @brief Sets the close flag of the specified window. * * This function sets the value of the close flag of the specified window. * This can be used to override the user's attempt to close the window, or * to signal that it should be closed. * * @param[in] window The window whose flag to change. * @param[in] value The new value. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @sa @ref window_close * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); /*! @brief Sets the title of the specified window. * * This function sets the window title, encoded as UTF-8, of the specified * window. * * @param[in] window The window whose title to change. * @param[in] title The UTF-8 encoded window title. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @remark @osx The window title will not be updated until the next time you * process events. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_title * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); /*! @brief Sets the icon for the specified window. * * This function sets the icon of the specified window. If passed an array of * candidate images, those of or closest to the sizes desired by the system are * selected. If no images are specified, the window reverts to its default * icon. * * The desired image sizes varies depending on platform and system settings. * The selected images will be rescaled as needed. Good sizes include 16x16, * 32x32 and 48x48. * * @param[in] window The window whose icon to set. * @param[in] count The number of images in the specified array, or zero to * revert to the default window icon. * @param[in] images The images to create the icon from. This is ignored if * count is zero. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified image data is copied before this function * returns. * * @remark @osx The GLFW window has no icon, as it is not a document * window, so this function does nothing. The dock icon will be the same as * the application bundle's icon. For more information on bundles, see the * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) * in the Mac Developer Library. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_icon * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); /*! @brief Retrieves the position of the client area of the specified window. * * This function retrieves the position, in screen coordinates, of the * upper-left corner of the client area of the specified window. * * Any or all of the position arguments may be `NULL`. If an error occurs, all * non-`NULL` position arguments will be set to zero. * * @param[in] window The window to query. * @param[out] xpos Where to store the x-coordinate of the upper-left corner of * the client area, or `NULL`. * @param[out] ypos Where to store the y-coordinate of the upper-left corner of * the client area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @sa glfwSetWindowPos * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); /*! @brief Sets the position of the client area of the specified window. * * This function sets the position, in screen coordinates, of the upper-left * corner of the client area of the specified windowed mode window. If the * window is a full screen window, this function does nothing. * * __Do not use this function__ to move an already visible window unless you * have very good reasons for doing so, as it will confuse and annoy the user. * * The window manager may put limits on what positions are allowed. GLFW * cannot and should not override these limits. * * @param[in] window The window to query. * @param[in] xpos The x-coordinate of the upper-left corner of the client area. * @param[in] ypos The y-coordinate of the upper-left corner of the client area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @sa glfwGetWindowPos * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); /*! @brief Retrieves the size of the client area of the specified window. * * This function retrieves the size, in screen coordinates, of the client area * of the specified window. If you wish to retrieve the size of the * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. * * @param[in] window The window whose size to retrieve. * @param[out] width Where to store the width, in screen coordinates, of the * client area, or `NULL`. * @param[out] height Where to store the height, in screen coordinates, of the * client area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @sa glfwSetWindowSize * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); /*! @brief Sets the size limits of the specified window. * * This function sets the size limits of the client area of the specified * window. If the window is full screen, the size limits only take effect * once it is made windowed. If the window is not resizable, this function * does nothing. * * The size limits are applied immediately to a windowed mode window and may * cause it to be resized. * * The maximum dimensions must be greater than or equal to the minimum * dimensions and all must be greater than or equal to zero. * * @param[in] window The window to set limits for. * @param[in] minwidth The minimum width, in screen coordinates, of the client * area, or `GLFW_DONT_CARE`. * @param[in] minheight The minimum height, in screen coordinates, of the * client area, or `GLFW_DONT_CARE`. * @param[in] maxwidth The maximum width, in screen coordinates, of the client * area, or `GLFW_DONT_CARE`. * @param[in] maxheight The maximum height, in screen coordinates, of the * client area, or `GLFW_DONT_CARE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @remark If you set size limits and an aspect ratio that conflict, the * results are undefined. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_sizelimits * @sa glfwSetWindowAspectRatio * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); /*! @brief Sets the aspect ratio of the specified window. * * This function sets the required aspect ratio of the client area of the * specified window. If the window is full screen, the aspect ratio only takes * effect once it is made windowed. If the window is not resizable, this * function does nothing. * * The aspect ratio is specified as a numerator and a denominator and both * values must be greater than zero. For example, the common 16:9 aspect ratio * is specified as 16 and 9, respectively. * * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect * ratio limit is disabled. * * The aspect ratio is applied immediately to a windowed mode window and may * cause it to be resized. * * @param[in] window The window to set limits for. * @param[in] numer The numerator of the desired aspect ratio, or * `GLFW_DONT_CARE`. * @param[in] denom The denominator of the desired aspect ratio, or * `GLFW_DONT_CARE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * * @remark If you set size limits and an aspect ratio that conflict, the * results are undefined. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_sizelimits * @sa glfwSetWindowSizeLimits * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); /*! @brief Sets the size of the client area of the specified window. * * This function sets the size, in screen coordinates, of the client area of * the specified window. * * For full screen windows, this function updates the resolution of its desired * video mode and switches to the video mode closest to it, without affecting * the window's context. As the context is unaffected, the bit depths of the * framebuffer remain unchanged. * * If you wish to update the refresh rate of the desired video mode in addition * to its resolution, see @ref glfwSetWindowMonitor. * * The window manager may put limits on what sizes are allowed. GLFW cannot * and should not override these limits. * * @param[in] window The window to resize. * @param[in] width The desired width, in screen coordinates, of the window * client area. * @param[in] height The desired height, in screen coordinates, of the window * client area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @sa glfwGetWindowSize * @sa glfwSetWindowMonitor * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); /*! @brief Retrieves the size of the framebuffer of the specified window. * * This function retrieves the size, in pixels, of the framebuffer of the * specified window. If you wish to retrieve the size of the window in screen * coordinates, see @ref glfwGetWindowSize. * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. * * @param[in] window The window whose framebuffer to query. * @param[out] width Where to store the width, in pixels, of the framebuffer, * or `NULL`. * @param[out] height Where to store the height, in pixels, of the framebuffer, * or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height); /*! @brief Retrieves the size of the frame of the window. * * This function retrieves the size, in screen coordinates, of each edge of the * frame of the specified window. This size includes the title bar, if the * window has one. The size of the frame may vary depending on the * [window-related hints](@ref window_hints_wnd) used to create it. * * Because this function retrieves the size of each window frame edge and not * the offset along a particular coordinate axis, the retrieved values will * always be zero or positive. * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. * * @param[in] window The window whose frame size to query. * @param[out] left Where to store the size, in screen coordinates, of the left * edge of the window frame, or `NULL`. * @param[out] top Where to store the size, in screen coordinates, of the top * edge of the window frame, or `NULL`. * @param[out] right Where to store the size, in screen coordinates, of the * right edge of the window frame, or `NULL`. * @param[out] bottom Where to store the size, in screen coordinates, of the * bottom edge of the window frame, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * * @since Added in version 3.1. * * @ingroup window */ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom); /*! @brief Iconifies the specified window. * * This function iconifies (minimizes) the specified window if it was * previously restored. If the window is already iconified, this function does * nothing. * * If the specified window is a full screen window, the original monitor * resolution is restored until the window is restored. * * @param[in] window The window to iconify. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * @sa glfwRestoreWindow * @sa glfwMaximizeWindow * * @since Added in version 2.1. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwIconifyWindow(GLFWwindow* window); /*! @brief Restores the specified window. * * This function restores the specified window if it was previously iconified * (minimized) or maximized. If the window is already restored, this function * does nothing. * * If the specified window is a full screen window, the resolution chosen for * the window is restored on the selected monitor. * * @param[in] window The window to restore. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * @sa glfwIconifyWindow * @sa glfwMaximizeWindow * * @since Added in version 2.1. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwRestoreWindow(GLFWwindow* window); /*! @brief Maximizes the specified window. * * This function maximizes the specified window if it was previously not * maximized. If the window is already maximized, this function does nothing. * * If the specified window is a full screen window, this function does nothing. * * @param[in] window The window to maximize. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @par Thread Safety * This function may only be called from the main thread. * * @sa @ref window_iconify * @sa glfwIconifyWindow * @sa glfwRestoreWindow * * @since Added in GLFW 3.2. * * @ingroup window */ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window); /*! @brief Makes the specified window visible. * * This function makes the specified window visible if it was previously * hidden. If the window is already visible or is in full screen mode, this * function does nothing. * * @param[in] window The window to make visible. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide * @sa glfwHideWindow * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwShowWindow(GLFWwindow* window); /*! @brief Hides the specified window. * * This function hides the specified window if it was previously visible. If * the window is already hidden or is in full screen mode, this function does * nothing. * * @param[in] window The window to hide. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide * @sa glfwShowWindow * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwHideWindow(GLFWwindow* window); /*! @brief Brings the specified window to front and sets input focus. * * This function brings the specified window to front and sets input focus. * The window should already be visible and not iconified. * * By default, both windowed and full screen mode windows are focused when * initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable * this behavior. * * __Do not use this function__ to steal focus from other applications unless * you are certain that is what the user wants. Focus stealing can be * extremely disruptive. * * @param[in] window The window to give input focus. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_focus * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwFocusWindow(GLFWwindow* window); /*! @brief Returns the monitor that the window uses for full screen mode. * * This function returns the handle of the monitor that the specified window is * in full screen on. * * @param[in] window The window to query. * @return The monitor, or `NULL` if the window is in windowed mode or an error * occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor * @sa glfwSetWindowMonitor * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); /*! @brief Sets the mode, monitor, video mode and placement of a window. * * This function sets the monitor that the window uses for full screen mode or, * if the monitor is `NULL`, makes it windowed mode. * * When setting a monitor, this function updates the width, height and refresh * rate of the desired video mode and switches to the video mode closest to it. * The window position is ignored when setting a monitor. * * When the monitor is `NULL`, the position, width and height are used to * place the window client area. The refresh rate is ignored when no monitor * is specified. * * If you only wish to update the resolution of a full screen window or the * size of a windowed mode window, see @ref glfwSetWindowSize. * * When a window transitions from full screen to windowed mode, this function * restores any previous window settings such as whether it is decorated, * floating, resizable, has size or aspect ratio limits, etc.. * * @param[in] window The window whose monitor, size or video mode to set. * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. * @param[in] xpos The desired x-coordinate of the upper-left corner of the * client area. * @param[in] ypos The desired y-coordinate of the upper-left corner of the * client area. * @param[in] width The desired with, in screen coordinates, of the client area * or video mode. * @param[in] height The desired height, in screen coordinates, of the client * area or video mode. * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode, * or `GLFW_DONT_CARE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor * @sa @ref window_full_screen * @sa glfwGetWindowMonitor * @sa glfwSetWindowSize * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); /*! @brief Returns an attribute of the specified window. * * This function returns the value of an attribute of the specified window or * its OpenGL or OpenGL ES context. * * @param[in] window The window to query. * @param[in] attrib The [window attribute](@ref window_attribs) whose value to * return. * @return The value of the attribute, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @remark Framebuffer related hints are not window attributes. See @ref * window_attribs_fb for more information. * * @remark Zero is a valid value for many window and context related * attributes so you cannot use a return value of zero as an indication of * errors. However, this function should not fail as long as it is passed * valid arguments and the library has been [initialized](@ref intro_init). * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs * * @since Added in version 3.0. Replaces `glfwGetWindowParam` and * `glfwGetGLVersion`. * * @ingroup window */ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); /*! @brief Sets the user pointer of the specified window. * * This function sets the user-defined pointer of the specified window. The * current value is retained until the window is destroyed. The initial value * is `NULL`. * * @param[in] window The window whose pointer to set. * @param[in] pointer The new value. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @sa @ref window_userptr * @sa glfwGetWindowUserPointer * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); /*! @brief Returns the user pointer of the specified window. * * This function returns the current value of the user-defined pointer of the * specified window. The initial value is `NULL`. * * @param[in] window The window whose pointer to return. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @sa @ref window_userptr * @sa glfwSetWindowUserPointer * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); /*! @brief Sets the position callback for the specified window. * * This function sets the position callback of the specified window, which is * called when the window is moved. The callback is provided with the screen * position of the upper-left corner of the client area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun); /*! @brief Sets the size callback for the specified window. * * This function sets the size callback of the specified window, which is * called when the window is resized. The callback is provided with the size, * in screen coordinates, of the client area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * * @since Added in version 1.0. * @glfw3 Added window handle parameter and return value. * * @ingroup window */ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun); /*! @brief Sets the close callback for the specified window. * * This function sets the close callback of the specified window, which is * called when the user attempts to close the window, for example by clicking * the close widget in the title bar. * * The close flag is set before this callback is called, but you can modify it * at any time with @ref glfwSetWindowShouldClose. * * The close callback is not triggered by @ref glfwDestroyWindow. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @remark @osx Selecting Quit from the application menu will trigger the close * callback for all windows. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_close * * @since Added in version 2.5. * @glfw3 Added window handle parameter and return value. * * @ingroup window */ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun); /*! @brief Sets the refresh callback for the specified window. * * This function sets the refresh callback of the specified window, which is * called when the client area of the window needs to be redrawn, for example * if the window has been exposed after having been covered by another window. * * On compositing window systems such as Aero, Compiz or Aqua, where the window * contents are saved off-screen, this callback may be called only very * infrequently or never at all. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_refresh * * @since Added in version 2.5. * @glfw3 Added window handle parameter and return value. * * @ingroup window */ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun); /*! @brief Sets the focus callback for the specified window. * * This function sets the focus callback of the specified window, which is * called when the window gains or loses input focus. * * After the focus callback is called for a window that lost input focus, * synthetic key and mouse button release events will be generated for all such * that had been pressed. For more information, see @ref glfwSetKeyCallback * and @ref glfwSetMouseButtonCallback. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_focus * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun); /*! @brief Sets the iconify callback for the specified window. * * This function sets the iconification callback of the specified window, which * is called when the window is iconified or restored. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun); /*! @brief Sets the framebuffer resize callback for the specified window. * * This function sets the framebuffer resize callback of the specified window, * which is called when the framebuffer of the specified window is resized. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize * * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun); /*! @brief Processes all pending events. * * This function processes only those events that are already in the event * queue and then returns immediately. Processing events will cause the window * and input callbacks associated with those events to be called. * * On some platforms, a window move, resize or menu operation will cause event * processing to block. This is due to how event processing is designed on * those platforms. You can use the * [window refresh callback](@ref window_refresh) to redraw the contents of * your window when necessary during such operations. * * On some platforms, certain events are sent directly to the application * without going through the event queue, causing callbacks to be called * outside of a call to one of the event processing functions. * * Event processing is not required for joystick input to work. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwWaitEvents * @sa glfwWaitEventsTimeout * * @since Added in version 1.0. * * @ingroup window */ GLFWAPI void glfwPollEvents(void); /*! @brief Waits until events are queued and processes them. * * This function puts the calling thread to sleep until at least one event is * available in the event queue. Once one or more events are available, * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue * are processed and the function then returns immediately. Processing events * will cause the window and input callbacks associated with those events to be * called. * * Since not all events are associated with callbacks, this function may return * without a callback having been called even if you are monitoring all * callbacks. * * On some platforms, a window move, resize or menu operation will cause event * processing to block. This is due to how event processing is designed on * those platforms. You can use the * [window refresh callback](@ref window_refresh) to redraw the contents of * your window when necessary during such operations. * * On some platforms, certain callbacks may be called outside of a call to one * of the event processing functions. * * If no windows exist, this function returns immediately. For synchronization * of threads in applications that do not create windows, use your threading * library of choice. * * Event processing is not required for joystick input to work. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwPollEvents * @sa glfwWaitEventsTimeout * * @since Added in version 2.5. * * @ingroup window */ GLFWAPI void glfwWaitEvents(void); /*! @brief Waits with timeout until events are queued and processes them. * * This function puts the calling thread to sleep until at least one event is * available in the event queue, or until the specified timeout is reached. If * one or more events are available, it behaves exactly like @ref * glfwPollEvents, i.e. the events in the queue are processed and the function * then returns immediately. Processing events will cause the window and input * callbacks associated with those events to be called. * * The timeout value must be a positive finite number. * * Since not all events are associated with callbacks, this function may return * without a callback having been called even if you are monitoring all * callbacks. * * On some platforms, a window move, resize or menu operation will cause event * processing to block. This is due to how event processing is designed on * those platforms. You can use the * [window refresh callback](@ref window_refresh) to redraw the contents of * your window when necessary during such operations. * * On some platforms, certain callbacks may be called outside of a call to one * of the event processing functions. * * If no windows exist, this function returns immediately. For synchronization * of threads in applications that do not create windows, use your threading * library of choice. * * Event processing is not required for joystick input to work. * * @param[in] timeout The maximum amount of time, in seconds, to wait. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwPollEvents * @sa glfwWaitEvents * * @since Added in version 3.2. * * @ingroup window */ GLFWAPI void glfwWaitEventsTimeout(double timeout); /*! @brief Posts an empty event to the event queue. * * This function posts an empty event from the current thread to the event * queue, causing @ref glfwWaitEvents to return. * * If no windows exist, this function returns immediately. For synchronization * of threads in applications that do not create windows, use your threading * library of choice. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function may be called from any thread. * * @sa @ref events * @sa glfwWaitEvents * * @since Added in version 3.1. * * @ingroup window */ GLFWAPI void glfwPostEmptyEvent(void); /*! @brief Returns the value of an input option for the specified window. * * This function returns the value of an input option for the specified window. * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * * @param[in] window The window to query. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * * @thread_safety This function must only be called from the main thread. * * @sa glfwSetInputMode * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); /*! @brief Sets an input option for the specified window. * * This function sets an input mode option for the specified window. The mode * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * modes: * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client * area of the window but does not restrict the cursor from leaving. * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual * and unlimited cursor movement. This is useful for implementing for * example 3D camera controls. * * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS` * the next time it is called even if the key had been released before the * call. This is useful when you are only interested in whether keys have been * pressed but not when or in which order. * * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it. * If sticky mouse buttons are enabled, a mouse button press will ensure that * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even * if the mouse button had been released before the call. This is useful when * you are only interested in whether mouse buttons have been pressed but not * when or in which order. * * @param[in] window The window whose input mode to set. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * @param[in] value The new value of the specified input mode. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa glfwGetInputMode * * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`. * * @ingroup input */ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); /*! @brief Returns the localized name of the specified printable key. * * This function returns the localized name of the specified printable key. * This is intended for displaying key bindings to the user. * * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise * the scancode is ignored. If a non-printable key or (if the key is * `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is * specified, this function returns `NULL`. * * This behavior allows you to pass in the arguments passed to the * [key callback](@ref input_key) without modification. * * The printable keys are: * - `GLFW_KEY_APOSTROPHE` * - `GLFW_KEY_COMMA` * - `GLFW_KEY_MINUS` * - `GLFW_KEY_PERIOD` * - `GLFW_KEY_SLASH` * - `GLFW_KEY_SEMICOLON` * - `GLFW_KEY_EQUAL` * - `GLFW_KEY_LEFT_BRACKET` * - `GLFW_KEY_RIGHT_BRACKET` * - `GLFW_KEY_BACKSLASH` * - `GLFW_KEY_WORLD_1` * - `GLFW_KEY_WORLD_2` * - `GLFW_KEY_0` to `GLFW_KEY_9` * - `GLFW_KEY_A` to `GLFW_KEY_Z` * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9` * - `GLFW_KEY_KP_DECIMAL` * - `GLFW_KEY_KP_DIVIDE` * - `GLFW_KEY_KP_MULTIPLY` * - `GLFW_KEY_KP_SUBTRACT` * - `GLFW_KEY_KP_ADD` * - `GLFW_KEY_KP_EQUAL` * * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`. * @param[in] scancode The scancode of the key to query. * @return The localized name of the key, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetKeyName, or until the library is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key_name * * @since Added in version 3.2. * * @ingroup input */ GLFWAPI const char* glfwGetKeyName(int key, int scancode); /*! @brief Returns the last reported state of a keyboard key for the specified * window. * * This function returns the last state reported for the specified key to the * specified window. The returned state is one of `GLFW_PRESS` or * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to * the key callback. * * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns * `GLFW_PRESS` the first time you call it for a key that was pressed, even if * that key has already been released. * * The key functions deal with physical keys, with [key tokens](@ref keys) * named after their use on the standard US keyboard layout. If you want to * input text, use the Unicode character callback instead. * * The [modifier key bit masks](@ref mods) are not key tokens and cannot be * used with this function. * * __Do not use this function__ to implement [text input](@ref input_char). * * @param[in] window The desired window. * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is * not a valid key for this function. * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup input */ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); /*! @brief Returns the last reported state of a mouse button for the specified * window. * * This function returns the last state reported for the specified mouse button * to the specified window. The returned state is one of `GLFW_PRESS` or * `GLFW_RELEASE`. * * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function * `GLFW_PRESS` the first time you call it for a mouse button that was pressed, * even if that mouse button has already been released. * * @param[in] window The desired window. * @param[in] button The desired [mouse button](@ref buttons). * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_mouse_button * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup input */ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); /*! @brief Retrieves the position of the cursor relative to the client area of * the window. * * This function returns the position of the cursor, in screen coordinates, * relative to the upper-left corner of the client area of the specified * window. * * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor * position is unbounded and limited only by the minimum and maximum values of * a `double`. * * The coordinate can be converted to their integer equivalents with the * `floor` function. Casting directly to an integer type works for positive * coordinates, but fails for negative ones. * * Any or all of the position arguments may be `NULL`. If an error occurs, all * non-`NULL` position arguments will be set to zero. * * @param[in] window The desired window. * @param[out] xpos Where to store the cursor x-coordinate, relative to the * left edge of the client area, or `NULL`. * @param[out] ypos Where to store the cursor y-coordinate, relative to the to * top edge of the client area, or `NULL`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @sa glfwSetCursorPos * * @since Added in version 3.0. Replaces `glfwGetMousePos`. * * @ingroup input */ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); /*! @brief Sets the position of the cursor, relative to the client area of the * window. * * This function sets the position, in screen coordinates, of the cursor * relative to the upper-left corner of the client area of the specified * window. The window must have input focus. If the window does not have * input focus when this function is called, it fails silently. * * __Do not use this function__ to implement things like camera controls. GLFW * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the * cursor, transparently re-centers it and provides unconstrained cursor * motion. See @ref glfwSetInputMode for more information. * * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is * unconstrained and limited only by the minimum and maximum values of * a `double`. * * @param[in] window The desired window. * @param[in] xpos The desired x-coordinate, relative to the left edge of the * client area. * @param[in] ypos The desired y-coordinate, relative to the top edge of the * client area. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @sa glfwGetCursorPos * * @since Added in version 3.0. Replaces `glfwSetMousePos`. * * @ingroup input */ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); /*! @brief Creates a custom cursor. * * Creates a new custom cursor image that can be set for a window with @ref * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor. * Any remaining cursors are destroyed by @ref glfwTerminate. * * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight * bits per channel. They are arranged canonically as packed sequential rows, * starting from the top-left corner. * * The cursor hotspot is specified in pixels, relative to the upper-left corner * of the cursor image. Like all other coordinate systems in GLFW, the X-axis * points to the right and the Y-axis points down. * * @param[in] image The desired cursor image. * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot. * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot. * @return The handle of the created cursor, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified image data is copied before this function * returns. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwDestroyCursor * @sa glfwCreateStandardCursor * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); /*! @brief Creates a cursor with a standard shape. * * Returns a cursor with a [standard shape](@ref shapes), that can be set for * a window with @ref glfwSetCursor. * * @param[in] shape One of the [standard shapes](@ref shapes). * @return A new cursor ready to use or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwCreateCursor * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); /*! @brief Destroys a cursor. * * This function destroys a cursor previously created with @ref * glfwCreateCursor. Any remaining cursors will be destroyed by @ref * glfwTerminate. * * @param[in] cursor The cursor object to destroy. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwCreateCursor * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); /*! @brief Sets the cursor for the window. * * This function sets the cursor image to be used when the cursor is over the * client area of the specified window. The set cursor will only be visible * when the [cursor mode](@ref cursor_mode) of the window is * `GLFW_CURSOR_NORMAL`. * * On some platforms, the set cursor may not be visible unless the window also * has input focus. * * @param[in] window The window to set the cursor for. * @param[in] cursor The cursor to set, or `NULL` to switch back to the default * arrow cursor. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); /*! @brief Sets the key callback. * * This function sets the key callback of the specified window, which is called * when a key is pressed, repeated or released. * * The key functions deal with physical keys, with layout independent * [key tokens](@ref keys) named after their values in the standard US keyboard * layout. If you want to input text, use the * [character callback](@ref glfwSetCharCallback) instead. * * When a window loses input focus, it will generate synthetic key release * events for all pressed keys. You can tell these events from user-generated * events by the fact that the synthetic ones are generated after the focus * loss event has been processed, i.e. after the * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * * The scancode of a key is specific to that platform or sometimes even to that * machine. Scancodes are intended to allow users to bind keys that don't have * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their * state is not saved and so it cannot be queried with @ref glfwGetKey. * * Sometimes GLFW needs to generate synthetic key events, in which case the * scancode may be zero. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new key callback, or `NULL` to remove the currently * set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_key * * @since Added in version 1.0. * @glfw3 Added window handle parameter and return value. * * @ingroup input */ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); /*! @brief Sets the Unicode character callback. * * This function sets the character callback of the specified window, which is * called when a Unicode character is input. * * The character callback is intended for Unicode text input. As it deals with * characters, it is keyboard layout dependent, whereas the * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1 * to physical keys, as a key may produce zero, one or more characters. If you * want to know whether a specific physical key was pressed or released, see * the key callback instead. * * The character callback behaves as system text input normally does and will * not be called if modifier keys are held down that would prevent normal text * input on that platform, for example a Super (Command) key on OS X or Alt key * on Windows. There is a * [character with modifiers callback](@ref glfwSetCharModsCallback) that * receives these events. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char * * @since Added in version 2.4. * @glfw3 Added window handle parameter and return value. * * @ingroup input */ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); /*! @brief Sets the Unicode character with modifiers callback. * * This function sets the character with modifiers callback of the specified * window, which is called when a Unicode character is input regardless of what * modifier keys are used. * * The character with modifiers callback is intended for implementing custom * Unicode character input. For regular Unicode text input, see the * [character callback](@ref glfwSetCharCallback). Like the character * callback, the character with modifiers callback deals with characters and is * keyboard layout dependent. Characters do not map 1:1 to physical keys, as * a key may produce zero, one or more characters. If you want to know whether * a specific physical key was pressed or released, see the * [key callback](@ref glfwSetKeyCallback) instead. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or an * error occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun); /*! @brief Sets the mouse button callback. * * This function sets the mouse button callback of the specified window, which * is called when a mouse button is pressed or released. * * When a window loses input focus, it will generate synthetic mouse button * release events for all pressed mouse buttons. You can tell these events * from user-generated events by the fact that the synthetic ones are generated * after the focus loss event has been processed, i.e. after the * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref input_mouse_button * * @since Added in version 1.0. * @glfw3 Added window handle parameter and return value. * * @ingroup input */ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun); /*! @brief Sets the cursor position callback. * * This function sets the cursor position callback of the specified window, * which is called when the cursor is moved. The callback is provided with the * position, in screen coordinates, relative to the upper-left corner of the * client area of the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`. * * @ingroup input */ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun); /*! @brief Sets the cursor enter/exit callback. * * This function sets the cursor boundary crossing callback of the specified * window, which is called when the cursor enters or leaves the client area of * the window. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_enter * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun); /*! @brief Sets the scroll callback. * * This function sets the scroll callback of the specified window, which is * called when a scrolling device is used, such as a mouse wheel or scrolling * area of a touchpad. * * The scroll callback receives all scrolling input, like that from a mouse * wheel or a touchpad scrolling area. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently * set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref scrolling * * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`. * * @ingroup input */ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun); /*! @brief Sets the file drop callback. * * This function sets the file drop callback of the specified window, which is * called when one or more dragged files are dropped on the window. * * Because the path array and its strings may have been generated specifically * for that event, they are not guaranteed to be valid after the callback has * returned. If you wish to use them after the callback returns, you need to * make a deep copy. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new file drop callback, or `NULL` to remove the * currently set callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref path_drop * * @since Added in version 3.1. * * @ingroup input */ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); /*! @brief Returns whether the specified joystick is present. * * This function returns whether the specified joystick is present. * * @param[in] joy The [joystick](@ref joysticks) to query. * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick * * @since Added in version 3.0. Replaces `glfwGetJoystickParam`. * * @ingroup input */ GLFWAPI int glfwJoystickPresent(int joy); /*! @brief Returns the values of all axes of the specified joystick. * * This function returns the values of all axes of the specified joystick. * Each element in the array is a value between -1.0 and 1.0. * * Querying a joystick slot with no device present is not an error, but will * cause this function to return `NULL`. Call @ref glfwJoystickPresent to * check device presence. * * @param[in] joy The [joystick](@ref joysticks) to query. * @param[out] count Where to store the number of axis values in the returned * array. This is set to zero if an error occurred. * @return An array of axis values, or `NULL` if the joystick is not present. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_axis * * @since Added in version 3.0. Replaces `glfwGetJoystickPos`. * * @ingroup input */ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); /*! @brief Returns the state of all buttons of the specified joystick. * * This function returns the state of all buttons of the specified joystick. * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`. * * Querying a joystick slot with no device present is not an error, but will * cause this function to return `NULL`. Call @ref glfwJoystickPresent to * check device presence. * * @param[in] joy The [joystick](@ref joysticks) to query. * @param[out] count Where to store the number of button states in the returned * array. This is set to zero if an error occurred. * @return An array of button states, or `NULL` if the joystick is not present. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_button * * @since Added in version 2.2. * @glfw3 Changed to return a dynamic array. * * @ingroup input */ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); /*! @brief Returns the name of the specified joystick. * * This function returns the name, encoded as UTF-8, of the specified joystick. * The returned string is allocated and freed by GLFW. You should not free it * yourself. * * Querying a joystick slot with no device present is not an error, but will * cause this function to return `NULL`. Call @ref glfwJoystickPresent to * check device presence. * * @param[in] joy The [joystick](@ref joysticks) to query. * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick * is not present. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, this function is called again for that joystick or the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_name * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI const char* glfwGetJoystickName(int joy); /*! @brief Sets the joystick configuration callback. * * This function sets the joystick configuration callback, or removes the * currently set callback. This is called when a joystick is connected to or * disconnected from the system. * * @param[in] cbfun The new callback, or `NULL` to remove the currently set * callback. * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_event * * @since Added in version 3.2. * * @ingroup input */ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun); /*! @brief Sets the clipboard to the specified string. * * This function sets the system clipboard to the specified, UTF-8 encoded * string. * * @param[in] window The window that will own the clipboard contents. * @param[in] string A UTF-8 encoded string. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified string is copied before this function * returns. * * @thread_safety This function must only be called from the main thread. * * @sa @ref clipboard * @sa glfwGetClipboardString * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); /*! @brief Returns the contents of the clipboard as a string. * * This function returns the contents of the system clipboard, if it contains * or is convertible to a UTF-8 encoded string. If the clipboard is empty or * if its contents cannot be converted, `NULL` is returned and a @ref * GLFW_FORMAT_UNAVAILABLE error is generated. * * @param[in] window The window that will request the clipboard contents. * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library * is terminated. * * @thread_safety This function must only be called from the main thread. * * @sa @ref clipboard * @sa glfwSetClipboardString * * @since Added in version 3.0. * * @ingroup input */ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); /*! @brief Returns the value of the GLFW timer. * * This function returns the value of the GLFW timer. Unless the timer has * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW * was initialized. * * The resolution of the timer is system dependent, but is usually on the order * of a few micro- or nanoseconds. It uses the highest-resolution monotonic * time source on each supported platform. * * @return The current value, in seconds, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. Reading and * writing of the internal timer offset is not atomic, so it needs to be * externally synchronized with calls to @ref glfwSetTime. * * @sa @ref time * * @since Added in version 1.0. * * @ingroup input */ GLFWAPI double glfwGetTime(void); /*! @brief Sets the GLFW timer. * * This function sets the value of the GLFW timer. It then continues to count * up from that value. The value must be a positive finite number less than * or equal to 18446744073.0, which is approximately 584.5 years. * * @param[in] time The new value, in seconds. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_VALUE. * * @remark The upper limit of the timer is calculated as * floor((264 - 1) / 109) and is due to implementations * storing nanoseconds in 64 bits. The limit may be increased in the future. * * @thread_safety This function may be called from any thread. Reading and * writing of the internal timer offset is not atomic, so it needs to be * externally synchronized with calls to @ref glfwGetTime. * * @sa @ref time * * @since Added in version 2.2. * * @ingroup input */ GLFWAPI void glfwSetTime(double time); /*! @brief Returns the current value of the raw timer. * * This function returns the current value of the raw timer, measured in * 1 / frequency seconds. To get the frequency, call @ref * glfwGetTimerFrequency. * * @return The value of the timer, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. * * @sa @ref time * @sa glfwGetTimerFrequency * * @since Added in version 3.2. * * @ingroup input */ GLFWAPI uint64_t glfwGetTimerValue(void); /*! @brief Returns the frequency, in Hz, of the raw timer. * * This function returns the frequency, in Hz, of the raw timer. * * @return The frequency of the timer, in Hz, or zero if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. * * @sa @ref time * @sa glfwGetTimerValue * * @since Added in version 3.2. * * @ingroup input */ GLFWAPI uint64_t glfwGetTimerFrequency(void); /*! @brief Makes the context of the specified window current for the calling * thread. * * This function makes the OpenGL or OpenGL ES context of the specified window * current on the calling thread. A context can only be made current on * a single thread at a time and each thread can have only a single current * context at a time. * * By default, making a context non-current implicitly forces a pipeline flush. * On machines that support `GL_KHR_context_flush_control`, you can control * whether a context performs this flush by setting the * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint. * * The specified window must have an OpenGL or OpenGL ES context. Specifying * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT * error. * * @param[in] window The window whose context to make current, or `NULL` to * detach the current context. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function may be called from any thread. * * @sa @ref context_current * @sa glfwGetCurrentContext * * @since Added in version 3.0. * * @ingroup context */ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); /*! @brief Returns the window whose context is current on the calling thread. * * This function returns the window whose OpenGL or OpenGL ES context is * current on the calling thread. * * @return The window whose context is current, or `NULL` if no window's * context is current. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. * * @sa @ref context_current * @sa glfwMakeContextCurrent * * @since Added in version 3.0. * * @ingroup context */ GLFWAPI GLFWwindow* glfwGetCurrentContext(void); /*! @brief Swaps the front and back buffers of the specified window. * * This function swaps the front and back buffers of the specified window when * rendering with OpenGL or OpenGL ES. If the swap interval is greater than * zero, the GPU driver waits the specified number of screen updates before * swapping the buffers. * * The specified window must have an OpenGL or OpenGL ES context. Specifying * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT * error. * * This function does not apply to Vulkan. If you are rendering with Vulkan, * see `vkQueuePresentKHR` instead. * * @param[in] window The window whose buffers to swap. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark __EGL:__ The context of the specified window must be current on the * calling thread. * * @thread_safety This function may be called from any thread. * * @sa @ref buffer_swap * @sa glfwSwapInterval * * @since Added in version 1.0. * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSwapBuffers(GLFWwindow* window); /*! @brief Sets the swap interval for the current context. * * This function sets the swap interval for the current OpenGL or OpenGL ES * context, i.e. the number of screen updates to wait from the time @ref * glfwSwapBuffers was called before swapping the buffers and returning. This * is sometimes called _vertical synchronization_, _vertical retrace * synchronization_ or just _vsync_. * * Contexts that support either of the `WGL_EXT_swap_control_tear` and * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals, * which allow the driver to swap even if a frame arrives a little bit late. * You can check for the presence of these extensions using @ref * glfwExtensionSupported. For more information about swap tearing, see the * extension specifications. * * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * * This function does not apply to Vulkan. If you are rendering with Vulkan, * see the present mode of your swapchain instead. * * @param[in] interval The minimum number of screen updates to wait for * until the buffers are swapped by @ref glfwSwapBuffers. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark This function is not called during context creation, leaving the * swap interval set to whatever is the default on that platform. This is done * because some swap interval extensions used by GLFW do not allow the swap * interval to be reset to zero once it has been set to a non-zero value. * * @remark Some GPU drivers do not honor the requested swap interval, either * because of a user setting that overrides the application's request or due to * bugs in the driver. * * @thread_safety This function may be called from any thread. * * @sa @ref buffer_swap * @sa glfwSwapBuffers * * @since Added in version 1.0. * * @ingroup context */ GLFWAPI void glfwSwapInterval(int interval); /*! @brief Returns whether the specified extension is available. * * This function returns whether the specified * [API extension](@ref context_glext) is supported by the current OpenGL or * OpenGL ES context. It searches both for client API extension and context * creation API extensions. * * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * * As this functions retrieves and searches one or more extension strings each * call, it is recommended that you cache its results if it is going to be used * frequently. The extension strings will not change during the lifetime of * a context, so there is no danger in doing this. * * This function does not apply to Vulkan. If you are using Vulkan, see @ref * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties` * and `vkEnumerateDeviceExtensionProperties` instead. * * @param[in] extension The ASCII encoded name of the extension. * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` * otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref * GLFW_PLATFORM_ERROR. * * @thread_safety This function may be called from any thread. * * @sa @ref context_glext * @sa glfwGetProcAddress * * @since Added in version 1.0. * * @ingroup context */ GLFWAPI int glfwExtensionSupported(const char* extension); /*! @brief Returns the address of the specified function for the current * context. * * This function returns the address of the specified OpenGL or OpenGL ES * [core or extension function](@ref context_glext), if it is supported * by the current context. * * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * * This function does not apply to Vulkan. If you are rendering with Vulkan, * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and * `vkGetDeviceProcAddr` instead. * * @param[in] procname The ASCII encoded name of the function. * @return The address of the function, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark The address of a given function is not guaranteed to be the same * between contexts. * * @remark This function may return a non-`NULL` address despite the * associated version or extension not being available. Always check the * context version or extension string first. * * @pointer_lifetime The returned function pointer is valid until the context * is destroyed or the library is terminated. * * @thread_safety This function may be called from any thread. * * @sa @ref context_glext * @sa glfwExtensionSupported * * @since Added in version 1.0. * * @ingroup context */ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); /*! @brief Returns whether the Vulkan loader has been found. * * This function returns whether the Vulkan loader has been found. This check * is performed by @ref glfwInit. * * The availability of a Vulkan loader does not by itself guarantee that window * surface creation or even device creation is possible. Call @ref * glfwGetRequiredInstanceExtensions to check whether the extensions necessary * for Vulkan surface creation are available and @ref * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of * a physical device supports image presentation. * * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * * @thread_safety This function may be called from any thread. * * @sa @ref vulkan_support * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI int glfwVulkanSupported(void); /*! @brief Returns the Vulkan instance extensions required by GLFW. * * This function returns an array of names of Vulkan instance extensions required * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the * list will always contains `VK_KHR_surface`, so if you don't require any * additional extensions you can pass this list directly to the * `VkInstanceCreateInfo` struct. * * If Vulkan is not available on the machine, this function returns `NULL` and * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported * to check whether Vulkan is available. * * If Vulkan is available but no set of extensions allowing window surface * creation was found, this function returns `NULL`. You may still use Vulkan * for off-screen rendering and compute work. * * @param[out] count Where to store the number of extensions in the returned * array. This is set to zero if an error occurred. * @return An array of ASCII encoded extension names, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_API_UNAVAILABLE. * * @remarks Additional extensions may be required by future versions of GLFW. * You should check if any extensions you wish to enable are already in the * returned array, as it is an error to specify an extension more than once in * the `VkInstanceCreateInfo` struct. * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is guaranteed to be valid only until the * library is terminated. * * @thread_safety This function may be called from any thread. * * @sa @ref vulkan_ext * @sa glfwCreateWindowSurface * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count); #if defined(VK_VERSION_1_0) /*! @brief Returns the address of the specified Vulkan instance function. * * This function returns the address of the specified Vulkan core or extension * function for the specified instance. If instance is set to `NULL` it can * return any function exported from the Vulkan loader, including at least the * following functions: * * - `vkEnumerateInstanceExtensionProperties` * - `vkEnumerateInstanceLayerProperties` * - `vkCreateInstance` * - `vkGetInstanceProcAddr` * * If Vulkan is not available on the machine, this function returns `NULL` and * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported * to check whether Vulkan is available. * * This function is equivalent to calling `vkGetInstanceProcAddr` with * a platform-specific query of the Vulkan loader as a fallback. * * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve * functions related to instance creation. * @param[in] procname The ASCII encoded name of the function. * @return The address of the function, or `NULL` if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_API_UNAVAILABLE. * * @pointer_lifetime The returned function pointer is valid until the library * is terminated. * * @thread_safety This function may be called from any thread. * * @sa @ref vulkan_proc * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname); /*! @brief Returns whether the specified queue family can present images. * * This function returns whether the specified queue family of the specified * physical device supports presentation to the platform GLFW was built for. * * If Vulkan or the required window surface creation instance extensions are * not available on the machine, or if the specified instance was not created * with the required extensions, this function returns `GLFW_FALSE` and * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported * to check whether Vulkan is available and @ref * glfwGetRequiredInstanceExtensions to check what instance extensions are * required. * * @param[in] instance The instance that the physical device belongs to. * @param[in] device The physical device that the queue family belongs to. * @param[in] queuefamily The index of the queue family to query. * @return `GLFW_TRUE` if the queue family supports presentation, or * `GLFW_FALSE` otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function may be called from any thread. For * synchronization details of Vulkan objects, see the Vulkan specification. * * @sa @ref vulkan_present * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); /*! @brief Creates a Vulkan surface for the specified window. * * This function creates a Vulkan surface for the specified window. * * If the Vulkan loader was not found at initialization, this function returns * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was * found. * * If the required window surface creation instance extensions are not * available or if the specified instance was not created with these extensions * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref * glfwGetRequiredInstanceExtensions to check what instance extensions are * required. * * The window surface must be destroyed before the specified Vulkan instance. * It is the responsibility of the caller to destroy the window surface. GLFW * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the * surface. * * @param[in] instance The Vulkan instance to create the surface in. * @param[in] window The window to create the surface for. * @param[in] allocator The allocator to use, or `NULL` to use the default * allocator. * @param[out] surface Where to store the handle of the surface. This is set * to `VK_NULL_HANDLE` if an error occurred. * @return `VK_SUCCESS` if successful, or a Vulkan error code if an * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @remarks If an error occurs before the creation call is made, GLFW returns * the Vulkan error code most appropriate for the error. Appropriate use of * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should * eliminate almost all occurrences of these errors. * * @thread_safety This function may be called from any thread. For * synchronization details of Vulkan objects, see the Vulkan specification. * * @sa @ref vulkan_surface * @sa glfwGetRequiredInstanceExtensions * * @since Added in version 3.2. * * @ingroup vulkan */ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); #endif /*VK_VERSION_1_0*/ /************************************************************************* * Global definition cleanup *************************************************************************/ /* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ #ifdef GLFW_WINGDIAPI_DEFINED #undef WINGDIAPI #undef GLFW_WINGDIAPI_DEFINED #endif #ifdef GLFW_CALLBACK_DEFINED #undef CALLBACK #undef GLFW_CALLBACK_DEFINED #endif /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ #ifdef __cplusplus } #endif #endif /* _glfw3_h_ */ ================================================ FILE: samples/vs2015/glfw-3.2-WIN64/include/GLFW/glfw3native.h ================================================ /************************************************************************* * GLFW 3.2 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard * Copyright (c) 2006-2016 Camilla Berglund * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would * be appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. * *************************************************************************/ #ifndef _glfw3_native_h_ #define _glfw3_native_h_ #ifdef __cplusplus extern "C" { #endif /************************************************************************* * Doxygen documentation *************************************************************************/ /*! @file glfw3native.h * @brief The header of the native access functions. * * This is the header file of the native access functions. See @ref native for * more information. */ /*! @defgroup native Native access * * **By using the native access functions you assert that you know what you're * doing and how to fix problems caused by using them. If you don't, you * shouldn't be using them.** * * Before the inclusion of @ref glfw3native.h, you may define exactly one * window system API macro and zero or more context creation API macros. * * The chosen backends must match those the library was compiled for. Failure * to do this will cause a link-time error. * * The available window API macros are: * * `GLFW_EXPOSE_NATIVE_WIN32` * * `GLFW_EXPOSE_NATIVE_COCOA` * * `GLFW_EXPOSE_NATIVE_X11` * * `GLFW_EXPOSE_NATIVE_WAYLAND` * * `GLFW_EXPOSE_NATIVE_MIR` * * The available context API macros are: * * `GLFW_EXPOSE_NATIVE_WGL` * * `GLFW_EXPOSE_NATIVE_NSGL` * * `GLFW_EXPOSE_NATIVE_GLX` * * `GLFW_EXPOSE_NATIVE_EGL` * * These macros select which of the native access functions that are declared * and which platform-specific headers to include. It is then up your (by * definition platform-specific) code to handle which of these should be * defined. */ /************************************************************************* * System headers and types *************************************************************************/ #if defined(GLFW_EXPOSE_NATIVE_WIN32) // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for // example to allow applications to correctly declare a GL_ARB_debug_output // callback) but windows.h assumes no one will define APIENTRY before it does #undef APIENTRY #include #elif defined(GLFW_EXPOSE_NATIVE_COCOA) #include #if defined(__OBJC__) #import #else typedef void* id; #endif #elif defined(GLFW_EXPOSE_NATIVE_X11) #include #include #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) #include #elif defined(GLFW_EXPOSE_NATIVE_MIR) #include #endif #if defined(GLFW_EXPOSE_NATIVE_WGL) /* WGL is declared by windows.h */ #endif #if defined(GLFW_EXPOSE_NATIVE_NSGL) /* NSGL is declared by Cocoa.h */ #endif #if defined(GLFW_EXPOSE_NATIVE_GLX) #include #endif #if defined(GLFW_EXPOSE_NATIVE_EGL) #include #endif /************************************************************************* * Functions *************************************************************************/ #if defined(GLFW_EXPOSE_NATIVE_WIN32) /*! @brief Returns the adapter device name of the specified monitor. * * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`) * of the specified monitor, or `NULL` if an [error](@ref error_handling) * occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); /*! @brief Returns the display device name of the specified monitor. * * @return The UTF-8 encoded display device name (for example * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); /*! @brief Returns the `HWND` of the specified window. * * @return The `HWND` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_WGL) /*! @brief Returns the `HGLRC` of the specified window. * * @return The `HGLRC` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_COCOA) /*! @brief Returns the `CGDirectDisplayID` of the specified monitor. * * @return The `CGDirectDisplayID` of the specified monitor, or * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); /*! @brief Returns the `NSWindow` of the specified window. * * @return The `NSWindow` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_NSGL) /*! @brief Returns the `NSOpenGLContext` of the specified window. * * @return The `NSOpenGLContext` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_X11) /*! @brief Returns the `Display` used by GLFW. * * @return The `Display` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI Display* glfwGetX11Display(void); /*! @brief Returns the `RRCrtc` of the specified monitor. * * @return The `RRCrtc` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); /*! @brief Returns the `RROutput` of the specified monitor. * * @return The `RROutput` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.1. * * @ingroup native */ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); /*! @brief Returns the `Window` of the specified window. * * @return The `Window` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI Window glfwGetX11Window(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_GLX) /*! @brief Returns the `GLXContext` of the specified window. * * @return The `GLXContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); /*! @brief Returns the `GLXWindow` of the specified window. * * @return The `GLXWindow` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) /*! @brief Returns the `struct wl_display*` used by GLFW. * * @return The `struct wl_display*` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); /*! @brief Returns the `struct wl_output*` of the specified monitor. * * @return The `struct wl_output*` of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); /*! @brief Returns the main `struct wl_surface*` of the specified window. * * @return The main `struct wl_surface*` of the specified window, or `NULL` if * an [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_MIR) /*! @brief Returns the `MirConnection*` used by GLFW. * * @return The `MirConnection*` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI MirConnection* glfwGetMirDisplay(void); /*! @brief Returns the Mir output ID of the specified monitor. * * @return The Mir output ID of the specified monitor, or zero if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor); /*! @brief Returns the `MirSurface*` of the specified window. * * @return The `MirSurface*` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.2. * * @ingroup native */ GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_EGL) /*! @brief Returns the `EGLDisplay` used by GLFW. * * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI EGLDisplay glfwGetEGLDisplay(void); /*! @brief Returns the `EGLContext` of the specified window. * * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); /*! @brief Returns the `EGLSurface` of the specified window. * * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * [error](@ref error_handling) occurred. * * @thread_safety This function may be called from any thread. Access is not * synchronized. * * @since Added in version 3.0. * * @ingroup native */ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); #endif #ifdef __cplusplus } #endif #endif /* _glfw3_native_h_ */