mirror of
https://github.com/recp/cglm.git
synced 2026-02-17 03:39:05 +00:00
Compare commits
104 Commits
neon-updat
...
simd-3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
607182982d | ||
|
|
ad17f38934 | ||
|
|
8302f78484 | ||
|
|
9665be3138 | ||
|
|
5c22ca3abb | ||
|
|
7f9585ca72 | ||
|
|
d0ab3aaa2e | ||
|
|
83dbdcc4a9 | ||
|
|
8ce45b4303 | ||
|
|
f19ff5d064 | ||
|
|
d6b93f052e | ||
|
|
28705be5a3 | ||
|
|
e1b142bce7 | ||
|
|
0f96eaad20 | ||
|
|
d5d3178ae0 | ||
|
|
13269f4af8 | ||
|
|
faf6186c29 | ||
|
|
2be6ac949b | ||
|
|
5b7bc522ac | ||
|
|
376cf31ee7 | ||
|
|
d28b381dd6 | ||
|
|
3673622cc3 | ||
|
|
a90f706e12 | ||
|
|
c065d71a2f | ||
|
|
1b3b91fe0b | ||
|
|
17560a0687 | ||
|
|
ba634d6c83 | ||
|
|
f35badd436 | ||
|
|
04eaf9c535 | ||
|
|
bd6641bd0a | ||
|
|
4e4bff418d | ||
|
|
55ebbdbe40 | ||
|
|
e4c35e32fc | ||
|
|
ec467fef1f | ||
|
|
1e8865233b | ||
|
|
155eb109a8 | ||
|
|
2903813765 | ||
|
|
0ab50f7208 | ||
|
|
701e015bfd | ||
|
|
1fb941a41b | ||
|
|
92151c6328 | ||
|
|
afac887850 | ||
|
|
a111693b6b | ||
|
|
ce9e5f5575 | ||
|
|
d13842e7de | ||
|
|
059e5010e6 | ||
|
|
65292a94a6 | ||
|
|
f303984aad | ||
|
|
7d5c4da7cf | ||
|
|
63988a515c | ||
|
|
9725b60d46 | ||
|
|
50c93f3d30 | ||
|
|
f14ca0c3f2 | ||
|
|
0c165cba76 | ||
|
|
2de1133012 | ||
|
|
12dc054e49 | ||
|
|
ebba4eea8e | ||
|
|
aa2fa89e6c | ||
|
|
7b0eee497e | ||
|
|
04008d9c3f | ||
|
|
11b1588105 | ||
|
|
7c81482248 | ||
|
|
f3f29bd383 | ||
|
|
0d0d22f96c | ||
|
|
7df5aa2e26 | ||
|
|
7cc4c37afb | ||
|
|
abe29a788a | ||
|
|
c5655bbd2e | ||
|
|
47e0045015 | ||
|
|
8f09cc8583 | ||
|
|
d6a0ac320b | ||
|
|
616d38c13a | ||
|
|
9e12908556 | ||
|
|
405cda6ee9 | ||
|
|
1b0322e51c | ||
|
|
4a308dcd9e | ||
|
|
fec396950b | ||
|
|
981af0565e | ||
|
|
1d215ef5f3 | ||
|
|
2b7cfde64f | ||
|
|
c783c42101 | ||
|
|
bddcfedead | ||
|
|
34e7438271 | ||
|
|
485ff6bc46 | ||
|
|
4ab9ab4772 | ||
|
|
a5ff477fc8 | ||
|
|
254570d006 | ||
|
|
681f20d540 | ||
|
|
fd87f6e2c3 | ||
|
|
2c12c6dce5 | ||
|
|
5619527fd3 | ||
|
|
8b1c3c3fc4 | ||
|
|
ec852c7682 | ||
|
|
5433c9ed6c | ||
|
|
2a2d51624b | ||
|
|
5fa908602f | ||
|
|
9da74f9654 | ||
|
|
dddb077b13 | ||
|
|
6107287c9a | ||
|
|
7dccbef6e3 | ||
|
|
d920a62be2 | ||
|
|
73f32b9ef7 | ||
|
|
2e5257bcc1 | ||
|
|
65b0b461ab |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -75,3 +75,4 @@ Default-568h@2x.png
|
|||||||
build/
|
build/
|
||||||
conftest.dir/*
|
conftest.dir/*
|
||||||
confdefs.h
|
confdefs.h
|
||||||
|
*.xcuserdatad
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.8.2)
|
cmake_minimum_required(VERSION 3.8.2)
|
||||||
project(cglm VERSION 0.7.9 LANGUAGES C)
|
project(cglm VERSION 0.8.3 LANGUAGES C)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
set(CMAKE_C_STANDARD_REQUIRED YES)
|
set(CMAKE_C_STANDARD_REQUIRED YES)
|
||||||
@@ -18,7 +18,7 @@ else(CGLM_STATIC)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CGLM_USE_C99)
|
if(CGLM_USE_C99)
|
||||||
set(C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
@@ -93,6 +93,11 @@ target_include_directories(${PROJECT_NAME}
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Target for header-only usage
|
||||||
|
add_library(${PROJECT_NAME}_headers INTERFACE)
|
||||||
|
target_include_directories(${PROJECT_NAME}_headers INTERFACE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
# Test Configuration
|
# Test Configuration
|
||||||
if(CGLM_USE_TEST)
|
if(CGLM_USE_TEST)
|
||||||
include(CTest)
|
include(CTest)
|
||||||
@@ -117,6 +122,16 @@ export(TARGETS ${PROJECT_NAME}
|
|||||||
)
|
)
|
||||||
|
|
||||||
install(EXPORT ${PROJECT_NAME}
|
install(EXPORT ${PROJECT_NAME}
|
||||||
|
FILE "${PROJECT_NAME}Config.cmake"
|
||||||
NAMESPACE ${PROJECT_NAME}::
|
NAMESPACE ${PROJECT_NAME}::
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/cmake)
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
||||||
|
|
||||||
|
set(PACKAGE_NAME ${PROJECT_NAME})
|
||||||
|
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||||
|
set(exec_prefix ${CMAKE_INSTALL_PREFIX})
|
||||||
|
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
|
set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
configure_file(${CMAKE_CURRENT_LIST_DIR}/cglm.pc.in ${CMAKE_BINARY_DIR}/cglm.pc @ONLY)
|
||||||
|
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/cglm.pc
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
|
|||||||
9
CREDITS
9
CREDITS
@@ -70,4 +70,11 @@ Möller–Trumbore ray-triangle intersection algorithm, from "Fast, Minimum Stor
|
|||||||
Authors:
|
Authors:
|
||||||
Thomas Möller (tompa@clarus.se)
|
Thomas Möller (tompa@clarus.se)
|
||||||
Ben Trumbore (wbt@graphics.cornell.edu)
|
Ben Trumbore (wbt@graphics.cornell.edu)
|
||||||
Link to paper: http://webserver2.tecgraf.puc-rio.br/~mgattass/cg/trbRR/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
|
Link to paper: http://webserver2.tecgraf.puc-rio.br/~mgattass/cg/trbRR/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
|
||||||
|
|
||||||
|
14. ARM NEON: Matrix Vector Multiplication
|
||||||
|
https://stackoverflow.com/a/57793352/2676533
|
||||||
|
|
||||||
|
16. ARM NEON Div
|
||||||
|
|
||||||
|
http://github.com/microsoft/DirectXMath
|
||||||
|
|||||||
@@ -109,7 +109,10 @@ cglm_simd_avx_HEADERS = include/cglm/simd/avx/mat4.h \
|
|||||||
include/cglm/simd/avx/affine.h
|
include/cglm/simd/avx/affine.h
|
||||||
|
|
||||||
cglm_simd_neondir=$(includedir)/cglm/simd/neon
|
cglm_simd_neondir=$(includedir)/cglm/simd/neon
|
||||||
cglm_simd_neon_HEADERS = include/cglm/simd/neon/mat4.h
|
cglm_simd_neon_HEADERS = include/cglm/simd/neon/mat4.h \
|
||||||
|
include/cglm/simd/neon/mat2.h \
|
||||||
|
include/cglm/simd/neon/affine.h \
|
||||||
|
include/cglm/simd/neon/quat.h
|
||||||
|
|
||||||
cglm_structdir=$(includedir)/cglm/struct
|
cglm_structdir=$(includedir)/cglm/struct
|
||||||
cglm_struct_HEADERS = include/cglm/struct/mat4.h \
|
cglm_struct_HEADERS = include/cglm/struct/mat4.h \
|
||||||
|
|||||||
44
Package.swift
Normal file
44
Package.swift
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// swift-tools-version:5.2
|
||||||
|
|
||||||
|
import PackageDescription
|
||||||
|
|
||||||
|
let package = Package(
|
||||||
|
name: "cglm",
|
||||||
|
products: [
|
||||||
|
.library(name: "cglm", type: .static, targets: ["cglmHeader"]),
|
||||||
|
.library(name: "cglmc", targets: ["cglmCompiled"]),
|
||||||
|
],
|
||||||
|
dependencies: [],
|
||||||
|
targets: [
|
||||||
|
.target(
|
||||||
|
name: "cglmCompiled",
|
||||||
|
path: "./",
|
||||||
|
exclude: [
|
||||||
|
"./docs",
|
||||||
|
"./src/swift",
|
||||||
|
"./include",
|
||||||
|
"./test",
|
||||||
|
"./win",
|
||||||
|
],
|
||||||
|
sources: [
|
||||||
|
"./src",
|
||||||
|
],
|
||||||
|
publicHeadersPath: "./include"
|
||||||
|
),
|
||||||
|
.target(
|
||||||
|
name: "cglmHeader",
|
||||||
|
path: "./",
|
||||||
|
exclude: [
|
||||||
|
"./docs",
|
||||||
|
"./include",
|
||||||
|
"./test",
|
||||||
|
"./win",
|
||||||
|
],
|
||||||
|
sources: [
|
||||||
|
"./src/swift",
|
||||||
|
],
|
||||||
|
publicHeadersPath: "./include"
|
||||||
|
),
|
||||||
|
],
|
||||||
|
cLanguageStandard: .c11
|
||||||
|
)
|
||||||
54
README.md
54
README.md
@@ -95,9 +95,9 @@ Currently *cglm* uses default clip space configuration (-1, 1) for camera functi
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
You have two option to call a function/operation: inline or library call (link)
|
You have two options to call a function/operation: inline or library call (link)
|
||||||
Almost all functions are marked inline (always_inline) so compiler will probably inline.
|
Almost all functions are marked inline (always_inline) so compiler will probably inline.
|
||||||
To call pre-compiled version, just use `glmc_` (c stands for 'call') instead of `glm_`.
|
To call pre-compiled versions, just use `glmc_` (c stands for 'call') instead of `glm_`.
|
||||||
|
|
||||||
```C
|
```C
|
||||||
#include <cglm/cglm.h> /* for inline */
|
#include <cglm/cglm.h> /* for inline */
|
||||||
@@ -168,6 +168,24 @@ option(CGLM_USE_C99 "" OFF) # C11
|
|||||||
option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test
|
option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Use as header-only library with your CMake project
|
||||||
|
|
||||||
|
This requires no building or installation of cglm.
|
||||||
|
|
||||||
|
* Example:
|
||||||
|
|
||||||
|
``` cmake
|
||||||
|
cmake_minimum_required(VERSION 3.8.2)
|
||||||
|
|
||||||
|
project(<Your Project Name>)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} src/main.c)
|
||||||
|
target_link_libraries(${LIBRARY_NAME} PRIVATE
|
||||||
|
cglm_headers)
|
||||||
|
|
||||||
|
add_subdirectory(external/cglm/ EXCLUDE_FROM_ALL)
|
||||||
|
```
|
||||||
|
|
||||||
#### Use with your CMake project
|
#### Use with your CMake project
|
||||||
* Example:
|
* Example:
|
||||||
```cmake
|
```cmake
|
||||||
@@ -212,6 +230,38 @@ cglm_dep = dependency('cglm', fallback : 'cglm', 'cglm_dep')
|
|||||||
executable('exe', 'src/main.c', dependencies : cglm_dep)
|
executable('exe', 'src/main.c', dependencies : cglm_dep)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Swift (Swift Package Manager)
|
||||||
|
|
||||||
|
Currently only default build options are supported. Add **cglm** dependency to your project:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
...
|
||||||
|
Package(
|
||||||
|
...
|
||||||
|
dependencies: [
|
||||||
|
...
|
||||||
|
.package(url: "https://github.com/recp/cglm", .branch("master")),
|
||||||
|
]
|
||||||
|
...
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Now add **cgml** as a dependency to your target. Product choices are:
|
||||||
|
- **cglm** for inlined version of the library which can be linked only statically
|
||||||
|
- **cglmc** for a compiled version of the library with no linking limitation
|
||||||
|
|
||||||
|
```swift
|
||||||
|
...
|
||||||
|
.target(
|
||||||
|
...
|
||||||
|
dependencies: [
|
||||||
|
...
|
||||||
|
.product(name: "cglm", package: "cglm"),
|
||||||
|
]
|
||||||
|
...
|
||||||
|
)
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
### Unix (Autotools)
|
### Unix (Autotools)
|
||||||
|
|
||||||
|
|||||||
15
cglm.podspec
15
cglm.podspec
@@ -2,10 +2,10 @@ Pod::Spec.new do |s|
|
|||||||
|
|
||||||
# Description
|
# Description
|
||||||
s.name = "cglm"
|
s.name = "cglm"
|
||||||
s.version = "0.7.2"
|
s.version = "0.8.2"
|
||||||
s.summary = "📽 Optimized OpenGL/Graphics Math (glm) for C"
|
s.summary = "📽 Highly Optimized Graphics Math (glm) for C"
|
||||||
s.description = <<-DESC
|
s.description = <<-DESC
|
||||||
cglm is math library for graphics programming for C. It is similar to original glm but it is written for C instead of C++ (you can use here too). See the documentation or README for all features.
|
cglm is math library for graphics programming for C. See the documentation or README for all features.
|
||||||
DESC
|
DESC
|
||||||
|
|
||||||
s.documentation_url = "http://cglm.readthedocs.io"
|
s.documentation_url = "http://cglm.readthedocs.io"
|
||||||
@@ -25,4 +25,13 @@ cglm is math library for graphics programming for C. It is similar to original g
|
|||||||
|
|
||||||
# Linking
|
# Linking
|
||||||
s.library = "m"
|
s.library = "m"
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
s.pod_target_xcconfig = {
|
||||||
|
'CLANG_ENABLE_MODULES' => 'NO',
|
||||||
|
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
|
||||||
|
'CLANG_WARN_DOCUMENTATION_COMMENTS' => 'NO',
|
||||||
|
'GCC_C_LANGUAGE_STANDARD' => 'gnu11',
|
||||||
|
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GLM_TESTS_NO_COLORFUL_OUTPUT'
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
|
|
||||||
AC_PREREQ([2.69])
|
AC_PREREQ([2.69])
|
||||||
AC_INIT([cglm], [0.7.9], [info@recp.me])
|
AC_INIT([cglm], [0.8.3], [info@recp.me])
|
||||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects serial-tests])
|
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects serial-tests])
|
||||||
|
|
||||||
# Don't use the default cflags (-O2 -g), we set ours manually in Makefile.am.
|
# Don't use the default cflags (-O2 -g), we set ours manually in Makefile.am.
|
||||||
|
|||||||
@@ -32,6 +32,22 @@ If you don't want to install **cglm** to your system's folder you can get static
|
|||||||
option(CGLM_USE_C99 "" OFF) # C11
|
option(CGLM_USE_C99 "" OFF) # C11
|
||||||
option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test
|
option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test
|
||||||
|
|
||||||
|
**Use as header-only library with your CMake project example**
|
||||||
|
This requires no building or installation of cglm.
|
||||||
|
|
||||||
|
.. code-block:: CMake
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.8.2)
|
||||||
|
|
||||||
|
project(<Your Project Name>)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} src/main.c)
|
||||||
|
target_link_libraries(${LIBRARY_NAME} PRIVATE
|
||||||
|
cglm_headers)
|
||||||
|
|
||||||
|
add_subdirectory(external/cglm/ EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
**Use with your CMake project example**
|
**Use with your CMake project example**
|
||||||
|
|
||||||
.. code-block:: CMake
|
.. code-block:: CMake
|
||||||
@@ -50,7 +66,7 @@ If you don't want to install **cglm** to your system's folder you can get static
|
|||||||
Meson (All platforms):
|
Meson (All platforms):
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block::
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
$ meson build # [Optional] --default-library=static
|
$ meson build # [Optional] --default-library=static
|
||||||
@@ -60,7 +76,7 @@ Meson (All platforms):
|
|||||||
|
|
||||||
**Meson Options:**
|
**Meson Options:**
|
||||||
|
|
||||||
.. code-block:: CMake
|
.. code-block::
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
c_std=c11
|
c_std=c11
|
||||||
@@ -69,9 +85,9 @@ Meson (All platforms):
|
|||||||
enable_tests=false # to run tests: ninja test
|
enable_tests=false # to run tests: ninja test
|
||||||
|
|
||||||
|
|
||||||
**Use with your CMake project example**
|
**Use with your Meson project**
|
||||||
|
|
||||||
.. code-block:: CMake
|
.. code-block::
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
# Clone cglm or create a cglm.wrap under <source_root>/subprojects
|
# Clone cglm or create a cglm.wrap under <source_root>/subprojects
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
# If your documentation needs a minimal Sphinx version, state it here.
|
||||||
#
|
#
|
||||||
# needs_sphinx = '1.0'
|
# needs_sphinx = '3.0'
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
@@ -62,9 +62,9 @@ author = u'Recep Aslantas'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = u'0.7.9'
|
version = u'0.8.3'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = u'0.7.9'
|
release = u'0.8.3'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
@@ -197,3 +197,7 @@ epub_exclude_files = ['search.html']
|
|||||||
|
|
||||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||||
todo_include_todos = True
|
todo_include_todos = True
|
||||||
|
|
||||||
|
# -- Options for the C domain ------------------------------------------------
|
||||||
|
|
||||||
|
c_id_attributes = ['__restrict']
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ How to send vector or matrix to OpenGL like API
|
|||||||
==================================================
|
==================================================
|
||||||
|
|
||||||
*cglm*'s vector and matrix types are arrays. So you can send them directly to a
|
*cglm*'s vector and matrix types are arrays. So you can send them directly to a
|
||||||
function which accecpts pointer. But you may got warnings for matrix because it is
|
function which accepts pointer. But you may got warnings for matrix because it is
|
||||||
two dimensional array.
|
two dimensional array.
|
||||||
|
|
||||||
Passing / Uniforming Matrix to OpenGL:
|
Passing / Uniforming Matrix to OpenGL:
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ Functions:
|
|||||||
#. :c:func:`glm_quat_mat3`
|
#. :c:func:`glm_quat_mat3`
|
||||||
#. :c:func:`glm_quat_mat3t`
|
#. :c:func:`glm_quat_mat3t`
|
||||||
#. :c:func:`glm_quat_lerp`
|
#. :c:func:`glm_quat_lerp`
|
||||||
|
#. :c:func:`glm_quat_nlerp`
|
||||||
#. :c:func:`glm_quat_slerp`
|
#. :c:func:`glm_quat_slerp`
|
||||||
#. :c:func:`glm_quat_look`
|
#. :c:func:`glm_quat_look`
|
||||||
#. :c:func:`glm_quat_for`
|
#. :c:func:`glm_quat_for`
|
||||||
@@ -304,6 +305,25 @@ Functions documentation
|
|||||||
| *[in]* **t** interpolant (amount) clamped between 0 and 1
|
| *[in]* **t** interpolant (amount) clamped between 0 and 1
|
||||||
| *[out]* **dest** result quaternion
|
| *[out]* **dest** result quaternion
|
||||||
|
|
||||||
|
.. c:function:: void glm_quat_nlerp(versor q, versor r, float t, versor dest)
|
||||||
|
|
||||||
|
| interpolates between two quaternions
|
||||||
|
| taking the shortest rotation path using
|
||||||
|
| normalized linear interpolation (NLERP)
|
||||||
|
|
||||||
|
| This is a cheaper alternative to slerp; most games use nlerp
|
||||||
|
| for animations as it visually makes little difference.
|
||||||
|
|
||||||
|
References:
|
||||||
|
* `Understanding Slerp, Then Not Using it <http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It>`_
|
||||||
|
* `Lerp, Slerp and Nlerp <https://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/>`_
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
| *[in]* **from** from
|
||||||
|
| *[in]* **to** to
|
||||||
|
| *[in]* **t** interpolant (amount) clamped between 0 and 1
|
||||||
|
| *[out]* **dest** result quaternion
|
||||||
|
|
||||||
.. c:function:: void glm_quat_slerp(versor q, versor r, float t, versor dest)
|
.. c:function:: void glm_quat_slerp(versor q, versor r, float t, versor dest)
|
||||||
|
|
||||||
| interpolates between two quaternions
|
| interpolates between two quaternions
|
||||||
@@ -374,7 +394,7 @@ Functions documentation
|
|||||||
| *[in]* **q** quaternion
|
| *[in]* **q** quaternion
|
||||||
| *[in]* **pivot** pivot
|
| *[in]* **pivot** pivot
|
||||||
|
|
||||||
.. c:function:: void glm_quat_rotate(mat4 m, versor q, mat4 dest)
|
.. c:function:: void glm_quat_rotate_atm(mat4 m, versor q, vec3 pivot)
|
||||||
|
|
||||||
| rotate NEW transform matrix using quaternion at pivot point
|
| rotate NEW transform matrix using quaternion at pivot point
|
||||||
| this creates rotation matrix, it assumes you don't have a matrix
|
| this creates rotation matrix, it assumes you don't have a matrix
|
||||||
|
|||||||
@@ -55,12 +55,12 @@ Functions:
|
|||||||
Functions documentation
|
Functions documentation
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. c:function:: void glm_vec2(vec4 v4, vec2 dest)
|
.. c:function:: void glm_vec2(float * v, vec2 dest)
|
||||||
|
|
||||||
init vec2 using vec3
|
init vec2 using vec3 or vec4
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
| *[in]* **v3** vector3
|
| *[in]* **v** vector
|
||||||
| *[out]* **dest** destination
|
| *[out]* **dest** destination
|
||||||
|
|
||||||
.. c:function:: void glm_vec2_copy(vec2 a, vec2 dest)
|
.. c:function:: void glm_vec2_copy(vec2 a, vec2 dest)
|
||||||
|
|||||||
@@ -26,6 +26,10 @@
|
|||||||
# include "simd/avx/affine.h"
|
# include "simd/avx/affine.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CGLM_NEON_FP
|
||||||
|
# include "simd/neon/affine.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief this is similar to glm_mat4_mul but specialized to affine transform
|
* @brief this is similar to glm_mat4_mul but specialized to affine transform
|
||||||
*
|
*
|
||||||
@@ -49,6 +53,8 @@ glm_mul(mat4 m1, mat4 m2, mat4 dest) {
|
|||||||
glm_mul_avx(m1, m2, dest);
|
glm_mul_avx(m1, m2, dest);
|
||||||
#elif defined( __SSE__ ) || defined( __SSE2__ )
|
#elif defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
glm_mul_sse2(m1, m2, dest);
|
glm_mul_sse2(m1, m2, dest);
|
||||||
|
#elif defined(CGLM_NEON_FP)
|
||||||
|
glm_mul_neon(m1, m2, dest);
|
||||||
#else
|
#else
|
||||||
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
|
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
|
||||||
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
|
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
|
||||||
@@ -103,6 +109,8 @@ void
|
|||||||
glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) {
|
glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
glm_mul_rot_sse2(m1, m2, dest);
|
glm_mul_rot_sse2(m1, m2, dest);
|
||||||
|
#elif defined(CGLM_NEON_FP)
|
||||||
|
glm_mul_rot_neon(m1, m2, dest);
|
||||||
#else
|
#else
|
||||||
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
|
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
|
||||||
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
|
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
|
||||||
@@ -150,6 +158,8 @@ void
|
|||||||
glm_inv_tr(mat4 mat) {
|
glm_inv_tr(mat4 mat) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
glm_inv_tr_sse2(mat);
|
glm_inv_tr_sse2(mat);
|
||||||
|
#elif defined(CGLM_NEON_FP)
|
||||||
|
glm_inv_tr_neon(mat);
|
||||||
#else
|
#else
|
||||||
CGLM_ALIGN_MAT mat3 r;
|
CGLM_ALIGN_MAT mat3 r;
|
||||||
CGLM_ALIGN(8) vec3 t;
|
CGLM_ALIGN(8) vec3 t;
|
||||||
|
|||||||
@@ -50,26 +50,22 @@
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_translate(mat4 m, vec3 v) {
|
glm_translate(mat4 m, vec3 v) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined(CGLM_SIMD)
|
||||||
|
glmm_128 m0, m1, m2, m3;
|
||||||
|
|
||||||
|
m0 = glmm_load(m[0]);
|
||||||
|
m1 = glmm_load(m[1]);
|
||||||
|
m2 = glmm_load(m[2]);
|
||||||
|
m3 = glmm_load(m[3]);
|
||||||
|
|
||||||
glmm_store(m[3],
|
glmm_store(m[3],
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_load(m[0]),
|
glmm_fmadd(m0, glmm_set1(v[0]),
|
||||||
_mm_set1_ps(v[0])),
|
glmm_fmadd(m1, glmm_set1(v[1]),
|
||||||
_mm_mul_ps(glmm_load(m[1]),
|
glmm_fmadd(m2, glmm_set1(v[2]), m3))));
|
||||||
_mm_set1_ps(v[1]))),
|
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_load(m[2]),
|
|
||||||
_mm_set1_ps(v[2])),
|
|
||||||
glmm_load(m[3]))))
|
|
||||||
;
|
|
||||||
#else
|
#else
|
||||||
vec4 v1, v2, v3;
|
glm_vec4_muladds(m[0], v[0], m[3]);
|
||||||
|
glm_vec4_muladds(m[1], v[1], m[3]);
|
||||||
glm_vec4_scale(m[0], v[0], v1);
|
glm_vec4_muladds(m[2], v[2], m[3]);
|
||||||
glm_vec4_scale(m[1], v[1], v2);
|
|
||||||
glm_vec4_scale(m[2], v[2], v3);
|
|
||||||
|
|
||||||
glm_vec4_add(v1, m[3], m[3]);
|
|
||||||
glm_vec4_add(v2, m[3], m[3]);
|
|
||||||
glm_vec4_add(v3, m[3], m[3]);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,12 +95,8 @@ glm_translate_to(mat4 m, vec3 v, mat4 dest) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_translate_x(mat4 m, float x) {
|
glm_translate_x(mat4 m, float x) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined(CGLM_SIMD)
|
||||||
glmm_store(m[3],
|
glmm_store(m[3], glmm_fmadd(glmm_load(m[0]), glmm_set1(x), glmm_load(m[3])));
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_load(m[0]),
|
|
||||||
_mm_set1_ps(x)),
|
|
||||||
glmm_load(m[3])))
|
|
||||||
;
|
|
||||||
#else
|
#else
|
||||||
vec4 v1;
|
vec4 v1;
|
||||||
glm_vec4_scale(m[0], x, v1);
|
glm_vec4_scale(m[0], x, v1);
|
||||||
@@ -121,12 +113,8 @@ glm_translate_x(mat4 m, float x) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_translate_y(mat4 m, float y) {
|
glm_translate_y(mat4 m, float y) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined(CGLM_SIMD)
|
||||||
glmm_store(m[3],
|
glmm_store(m[3], glmm_fmadd(glmm_load(m[1]), glmm_set1(y), glmm_load(m[3])));
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_load(m[1]),
|
|
||||||
_mm_set1_ps(y)),
|
|
||||||
glmm_load(m[3])))
|
|
||||||
;
|
|
||||||
#else
|
#else
|
||||||
vec4 v1;
|
vec4 v1;
|
||||||
glm_vec4_scale(m[1], y, v1);
|
glm_vec4_scale(m[1], y, v1);
|
||||||
@@ -143,12 +131,8 @@ glm_translate_y(mat4 m, float y) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_translate_z(mat4 m, float z) {
|
glm_translate_z(mat4 m, float z) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined(CGLM_SIMD)
|
||||||
glmm_store(m[3],
|
glmm_store(m[3], glmm_fmadd(glmm_load(m[2]), glmm_set1(z), glmm_load(m[3])));
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_load(m[2]),
|
|
||||||
_mm_set1_ps(z)),
|
|
||||||
glmm_load(m[3])))
|
|
||||||
;
|
|
||||||
#else
|
#else
|
||||||
vec4 v1;
|
vec4 v1;
|
||||||
glm_vec4_scale(m[2], z, v1);
|
glm_vec4_scale(m[2], z, v1);
|
||||||
@@ -455,7 +439,7 @@ glm_decompose_rs(mat4 m, mat4 r, vec3 s) {
|
|||||||
glm_vec4_scale(r[1], 1.0f/s[1], r[1]);
|
glm_vec4_scale(r[1], 1.0f/s[1], r[1]);
|
||||||
glm_vec4_scale(r[2], 1.0f/s[2], r[2]);
|
glm_vec4_scale(r[2], 1.0f/s[2], r[2]);
|
||||||
|
|
||||||
/* Note from Apple Open Source (asume that the matrix is orthonormal):
|
/* Note from Apple Open Source (assume that the matrix is orthonormal):
|
||||||
check for a coordinate system flip. If the determinant
|
check for a coordinate system flip. If the determinant
|
||||||
is -1, then negate the matrix and the scaling factors. */
|
is -1, then negate the matrix and the scaling factors. */
|
||||||
glm_vec3_cross(m[0], m[1], v);
|
glm_vec3_cross(m[0], m[1], v);
|
||||||
|
|||||||
@@ -228,6 +228,8 @@ glm_aabb_aabb(vec3 box[2], vec3 other[2]) {
|
|||||||
* https://github.com/erich666/GraphicsGems/blob/master/gems/BoxSphere.c
|
* https://github.com/erich666/GraphicsGems/blob/master/gems/BoxSphere.c
|
||||||
* Solid Box - Solid Sphere test.
|
* Solid Box - Solid Sphere test.
|
||||||
*
|
*
|
||||||
|
* Sphere Representation in cglm: [center.x, center.y, center.z, radii]
|
||||||
|
*
|
||||||
* @param[in] box solid bounding box
|
* @param[in] box solid bounding box
|
||||||
* @param[in] s solid sphere
|
* @param[in] s solid sphere
|
||||||
*/
|
*/
|
||||||
@@ -237,13 +239,13 @@ glm_aabb_sphere(vec3 box[2], vec4 s) {
|
|||||||
float dmin;
|
float dmin;
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
|
|
||||||
a = s[0] >= box[0][0];
|
a = (s[0] < box[0][0]) + (s[0] > box[1][0]);
|
||||||
b = s[1] >= box[0][1];
|
b = (s[1] < box[0][1]) + (s[1] > box[1][1]);
|
||||||
c = s[2] >= box[0][2];
|
c = (s[2] < box[0][2]) + (s[2] > box[1][2]);
|
||||||
|
|
||||||
dmin = glm_pow2(s[0] - box[a][0])
|
dmin = glm_pow2((s[0] - box[!(a - 1)][0]) * (a != 0))
|
||||||
+ glm_pow2(s[1] - box[b][1])
|
+ glm_pow2((s[1] - box[!(b - 1)][1]) * (b != 0))
|
||||||
+ glm_pow2(s[2] - box[c][2]);
|
+ glm_pow2((s[2] - box[!(c - 1)][2]) * (c != 0));
|
||||||
|
|
||||||
return dmin <= glm_pow2(s[3]);
|
return dmin <= glm_pow2(s[3]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,11 +116,15 @@ glmc_quat_mat3t(versor q, mat3 dest);
|
|||||||
CGLM_EXPORT
|
CGLM_EXPORT
|
||||||
void
|
void
|
||||||
glmc_quat_lerp(versor from, versor to, float t, versor dest);
|
glmc_quat_lerp(versor from, versor to, float t, versor dest);
|
||||||
|
|
||||||
CGLM_EXPORT
|
CGLM_EXPORT
|
||||||
void
|
void
|
||||||
glmc_quat_lerpc(versor from, versor to, float t, versor dest);
|
glmc_quat_lerpc(versor from, versor to, float t, versor dest);
|
||||||
|
|
||||||
|
CGLM_EXPORT
|
||||||
|
void
|
||||||
|
glmc_quat_nlerp(versor q, versor r, float t, versor dest);
|
||||||
|
|
||||||
CGLM_EXPORT
|
CGLM_EXPORT
|
||||||
void
|
void
|
||||||
glmc_quat_slerp(versor q, versor r, float t, versor dest);
|
glmc_quat_slerp(versor q, versor r, float t, versor dest);
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ glmc_vec4_scale(vec4 v, float s, vec4 dest);
|
|||||||
|
|
||||||
CGLM_EXPORT
|
CGLM_EXPORT
|
||||||
void
|
void
|
||||||
glmc_vec4_scale_as(vec3 v, float s, vec3 dest);
|
glmc_vec4_scale_as(vec4 v, float s, vec4 dest);
|
||||||
|
|
||||||
CGLM_EXPORT
|
CGLM_EXPORT
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -40,6 +40,10 @@
|
|||||||
# include "simd/sse2/mat2.h"
|
# include "simd/sse2/mat2.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CGLM_NEON_FP
|
||||||
|
# include "simd/neon/mat2.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}}
|
#define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}}
|
||||||
#define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}}
|
#define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}}
|
||||||
|
|
||||||
@@ -130,6 +134,8 @@ void
|
|||||||
glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) {
|
glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
glm_mat2_mul_sse2(m1, m2, dest);
|
glm_mat2_mul_sse2(m1, m2, dest);
|
||||||
|
#elif defined(CGLM_NEON_FP)
|
||||||
|
glm_mat2_mul_neon(m1, m2, dest);
|
||||||
#else
|
#else
|
||||||
float a00 = m1[0][0], a01 = m1[0][1],
|
float a00 = m1[0][0], a01 = m1[0][1],
|
||||||
a10 = m1[1][0], a11 = m1[1][1],
|
a10 = m1[1][0], a11 = m1[1][1],
|
||||||
|
|||||||
@@ -187,8 +187,29 @@ glm_mat4_identity_array(mat4 * __restrict mat, size_t count) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_mat4_zero(mat4 mat) {
|
glm_mat4_zero(mat4 mat) {
|
||||||
|
#ifdef __AVX__
|
||||||
|
__m256 y0;
|
||||||
|
y0 = _mm256_setzero_ps();
|
||||||
|
glmm_store256(mat[0], y0);
|
||||||
|
glmm_store256(mat[2], y0);
|
||||||
|
#elif defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
|
glmm_128 x0;
|
||||||
|
x0 = _mm_setzero_ps();
|
||||||
|
glmm_store(mat[0], x0);
|
||||||
|
glmm_store(mat[1], x0);
|
||||||
|
glmm_store(mat[2], x0);
|
||||||
|
glmm_store(mat[3], x0);
|
||||||
|
#elif defined(CGLM_NEON_FP)
|
||||||
|
glmm_128 x0;
|
||||||
|
x0 = vdupq_n_f32(0.0f);
|
||||||
|
vst1q_f32(mat[0], x0);
|
||||||
|
vst1q_f32(mat[1], x0);
|
||||||
|
vst1q_f32(mat[2], x0);
|
||||||
|
vst1q_f32(mat[3], x0);
|
||||||
|
#else
|
||||||
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_ZERO_INIT;
|
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_ZERO_INIT;
|
||||||
glm_mat4_copy(t, mat);
|
glm_mat4_copy(t, mat);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -539,7 +560,9 @@ glm_mat4_scale_p(mat4 m, float s) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_mat4_scale(mat4 m, float s) {
|
glm_mat4_scale(mat4 m, float s) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#ifdef __AVX__
|
||||||
|
glm_mat4_scale_avx(m, s);
|
||||||
|
#elif defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
glm_mat4_scale_sse2(m, s);
|
glm_mat4_scale_sse2(m, s);
|
||||||
#elif defined(CGLM_NEON_FP)
|
#elif defined(CGLM_NEON_FP)
|
||||||
glm_mat4_scale_neon(m, s);
|
glm_mat4_scale_neon(m, s);
|
||||||
@@ -560,6 +583,8 @@ float
|
|||||||
glm_mat4_det(mat4 mat) {
|
glm_mat4_det(mat4 mat) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
return glm_mat4_det_sse2(mat);
|
return glm_mat4_det_sse2(mat);
|
||||||
|
#elif defined(CGLM_NEON_FP)
|
||||||
|
return glm_mat4_det_neon(mat);
|
||||||
#else
|
#else
|
||||||
/* [square] det(A) = det(At) */
|
/* [square] det(A) = det(At) */
|
||||||
float t[6];
|
float t[6];
|
||||||
@@ -593,6 +618,8 @@ void
|
|||||||
glm_mat4_inv(mat4 mat, mat4 dest) {
|
glm_mat4_inv(mat4 mat, mat4 dest) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
glm_mat4_inv_sse2(mat, dest);
|
glm_mat4_inv_sse2(mat, dest);
|
||||||
|
#elif defined(CGLM_NEON_FP)
|
||||||
|
glm_mat4_inv_neon(mat, dest);
|
||||||
#else
|
#else
|
||||||
float t[6];
|
float t[6];
|
||||||
float det;
|
float det;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
CGLM_INLINE void glm_quat_lerp(versor from, versor to, float t, versor dest);
|
CGLM_INLINE void glm_quat_lerp(versor from, versor to, float t, versor dest);
|
||||||
CGLM_INLINE void glm_quat_lerpc(versor from, versor to, float t, versor dest);
|
CGLM_INLINE void glm_quat_lerpc(versor from, versor to, float t, versor dest);
|
||||||
CGLM_INLINE void glm_quat_slerp(versor q, versor r, float t, versor dest);
|
CGLM_INLINE void glm_quat_slerp(versor q, versor r, float t, versor dest);
|
||||||
|
CGLM_INLINE void glm_quat_nlerp(versor q, versor r, float t, versor dest);
|
||||||
CGLM_INLINE void glm_quat_look(vec3 eye, versor ori, mat4 dest);
|
CGLM_INLINE void glm_quat_look(vec3 eye, versor ori, mat4 dest);
|
||||||
CGLM_INLINE void glm_quat_for(vec3 dir, vec3 fwd, vec3 up, versor dest);
|
CGLM_INLINE void glm_quat_for(vec3 dir, vec3 fwd, vec3 up, versor dest);
|
||||||
CGLM_INLINE void glm_quat_forp(vec3 from,
|
CGLM_INLINE void glm_quat_forp(vec3 from,
|
||||||
@@ -63,6 +64,10 @@
|
|||||||
# include "simd/sse2/quat.h"
|
# include "simd/sse2/quat.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CGLM_NEON_FP
|
||||||
|
# include "simd/neon/quat.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_mat4_mulv(mat4 m, vec4 v, vec4 dest);
|
glm_mat4_mulv(mat4 m, vec4 v, vec4 dest);
|
||||||
@@ -412,6 +417,8 @@ glm_quat_mul(versor p, versor q, versor dest) {
|
|||||||
*/
|
*/
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||||
glm_quat_mul_sse2(p, q, dest);
|
glm_quat_mul_sse2(p, q, dest);
|
||||||
|
#elif defined(CGLM_NEON_FP)
|
||||||
|
glm_quat_mul_neon(p, q, dest);
|
||||||
#else
|
#else
|
||||||
dest[0] = p[3] * q[0] + p[0] * q[3] + p[1] * q[2] - p[2] * q[1];
|
dest[0] = p[3] * q[0] + p[0] * q[3] + p[1] * q[2] - p[2] * q[1];
|
||||||
dest[1] = p[3] * q[1] - p[0] * q[2] + p[1] * q[3] + p[2] * q[0];
|
dest[1] = p[3] * q[1] - p[0] * q[2] + p[1] * q[3] + p[2] * q[0];
|
||||||
@@ -622,6 +629,26 @@ glm_quat_lerpc(versor from, versor to, float t, versor dest) {
|
|||||||
glm_vec4_lerpc(from, to, t, dest);
|
glm_vec4_lerpc(from, to, t, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief interpolates between two quaternions
|
||||||
|
* taking the shortest rotation path using
|
||||||
|
* normalized linear interpolation (NLERP)
|
||||||
|
*
|
||||||
|
* @param[in] from from
|
||||||
|
* @param[in] to to
|
||||||
|
* @param[in] t interpolant (amount)
|
||||||
|
* @param[out] dest result quaternion
|
||||||
|
*/
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_quat_nlerp(versor from, versor to, float t, versor dest) {
|
||||||
|
float dot = glm_vec4_dot(from, to);
|
||||||
|
versor target;
|
||||||
|
glm_vec4_scale(to, (dot >= 0) ? 1 : -1, target);
|
||||||
|
glm_quat_lerp(from, target, t, dest);
|
||||||
|
glm_quat_normalize(dest);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief interpolates between two quaternions
|
* @brief interpolates between two quaternions
|
||||||
* using spherical linear interpolation (SLERP)
|
* using spherical linear interpolation (SLERP)
|
||||||
|
|||||||
@@ -10,19 +10,56 @@
|
|||||||
#include "intrin.h"
|
#include "intrin.h"
|
||||||
#ifdef CGLM_SIMD_ARM
|
#ifdef CGLM_SIMD_ARM
|
||||||
|
|
||||||
|
#if defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || defined(__aarch64__)
|
||||||
|
# define CGLM_ARM64 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#define glmm_load(p) vld1q_f32(p)
|
#define glmm_load(p) vld1q_f32(p)
|
||||||
#define glmm_store(p, a) vst1q_f32(p, a)
|
#define glmm_store(p, a) vst1q_f32(p, a)
|
||||||
|
|
||||||
|
#define glmm_set1(x) vdupq_n_f32(x)
|
||||||
|
#define glmm_128 float32x4_t
|
||||||
|
|
||||||
|
#define glmm_splat_x(x) vdupq_lane_f32(vget_low_f32(x), 0)
|
||||||
|
#define glmm_splat_y(x) vdupq_lane_f32(vget_low_f32(x), 1)
|
||||||
|
#define glmm_splat_z(x) vdupq_lane_f32(vget_high_f32(x), 0)
|
||||||
|
#define glmm_splat_w(x) vdupq_lane_f32(vget_high_f32(x), 1)
|
||||||
|
|
||||||
|
#define glmm_xor(a, b) \
|
||||||
|
vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a), \
|
||||||
|
vreinterpretq_s32_f32(b)))
|
||||||
|
|
||||||
|
#define glmm_swplane(v) vextq_f32(v, v, 2)
|
||||||
|
#define glmm_low(x) vget_low_f32(x)
|
||||||
|
#define glmm_high(x) vget_high_f32(x)
|
||||||
|
|
||||||
|
#define glmm_combine_ll(x, y) vcombine_f32(vget_low_f32(x), vget_low_f32(y))
|
||||||
|
#define glmm_combine_hl(x, y) vcombine_f32(vget_high_f32(x), vget_low_f32(y))
|
||||||
|
#define glmm_combine_lh(x, y) vcombine_f32(vget_low_f32(x), vget_high_f32(y))
|
||||||
|
#define glmm_combine_hh(x, y) vcombine_f32(vget_high_f32(x), vget_high_f32(y))
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
float32x4_t
|
float32x4_t
|
||||||
glmm_abs(float32x4_t v) {
|
glmm_abs(float32x4_t v) {
|
||||||
return vabsq_f32(v);
|
return vabsq_f32(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
float32x4_t
|
||||||
|
glmm_vhadd(float32x4_t v) {
|
||||||
|
return vaddq_f32(vaddq_f32(glmm_splat_x(v), glmm_splat_y(v)),
|
||||||
|
vaddq_f32(glmm_splat_z(v), glmm_splat_w(v)));
|
||||||
|
/*
|
||||||
|
this seems slower:
|
||||||
|
v = vaddq_f32(v, vrev64q_f32(v));
|
||||||
|
return vaddq_f32(v, vcombine_f32(vget_high_f32(v), vget_low_f32(v)));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
float
|
float
|
||||||
glmm_hadd(float32x4_t v) {
|
glmm_hadd(float32x4_t v) {
|
||||||
#if defined(__aarch64__)
|
#if CGLM_ARM64
|
||||||
return vaddvq_f32(v);
|
return vaddvq_f32(v);
|
||||||
#else
|
#else
|
||||||
v = vaddq_f32(v, vrev64q_f32(v));
|
v = vaddq_f32(v, vrev64q_f32(v));
|
||||||
@@ -79,5 +116,58 @@ glmm_norm_inf(float32x4_t a) {
|
|||||||
return glmm_hmax(glmm_abs(a));
|
return glmm_hmax(glmm_abs(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
float32x4_t
|
||||||
|
glmm_div(float32x4_t a, float32x4_t b) {
|
||||||
|
#if CGLM_ARM64
|
||||||
|
return vdivq_f32(a, b);
|
||||||
|
#else
|
||||||
|
/* 2 iterations of Newton-Raphson refinement of reciprocal */
|
||||||
|
float32x4_t r0, r1;
|
||||||
|
r0 = vrecpeq_f32(b);
|
||||||
|
r1 = vrecpsq_f32(r0, b);
|
||||||
|
r0 = vmulq_f32(r1, r0);
|
||||||
|
r1 = vrecpsq_f32(r0, b);
|
||||||
|
r0 = vmulq_f32(r1, r0);
|
||||||
|
return vmulq_f32(a, r0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
float32x4_t
|
||||||
|
glmm_fmadd(float32x4_t a, float32x4_t b, float32x4_t c) {
|
||||||
|
#if CGLM_ARM64
|
||||||
|
return vfmaq_f32(c, a, b); /* why vfmaq_f32 is slower than vmlaq_f32 ??? */
|
||||||
|
#else
|
||||||
|
return vmlaq_f32(c, a, b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
float32x4_t
|
||||||
|
glmm_fnmadd(float32x4_t a, float32x4_t b, float32x4_t c) {
|
||||||
|
#if CGLM_ARM64
|
||||||
|
return vfmsq_f32(c, a, b);
|
||||||
|
#else
|
||||||
|
return vmlsq_f32(c, a, b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
float32x4_t
|
||||||
|
glmm_fmsub(float32x4_t a, float32x4_t b, float32x4_t c) {
|
||||||
|
#if CGLM_ARM64
|
||||||
|
return vfmsq_f32(c, a, b);
|
||||||
|
#else
|
||||||
|
return vmlsq_f32(c, a, b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
float32x4_t
|
||||||
|
glmm_fnmsub(float32x4_t a, float32x4_t b, float32x4_t c) {
|
||||||
|
return vsubq_f32(vdupq_n_f32(0.0f), glmm_fmadd(a, b, c));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* cglm_simd_arm_h */
|
#endif /* cglm_simd_arm_h */
|
||||||
|
|||||||
@@ -14,6 +14,16 @@
|
|||||||
|
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_mat4_scale_avx(mat4 m, float s) {
|
||||||
|
__m256 y0;
|
||||||
|
y0 = _mm256_set1_ps(s);
|
||||||
|
|
||||||
|
glmm_store256(m[0], _mm256_mul_ps(y0, glmm_load256(m[0])));
|
||||||
|
glmm_store256(m[2], _mm256_mul_ps(y0, glmm_load256(m[2])));
|
||||||
|
}
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_mat4_mul_avx(mat4 m1, mat4 m2, mat4 dest) {
|
glm_mat4_mul_avx(mat4 m1, mat4 m2, mat4 dest) {
|
||||||
|
|||||||
122
include/cglm/simd/neon/affine.h
Normal file
122
include/cglm/simd/neon/affine.h
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c), Recep Aslantas.
|
||||||
|
*
|
||||||
|
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||||
|
* Full license can be found in the LICENSE file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cglm_affine_neon_h
|
||||||
|
#define cglm_affine_neon_h
|
||||||
|
#if defined(__ARM_NEON_FP)
|
||||||
|
|
||||||
|
#include "../../common.h"
|
||||||
|
#include "../intrin.h"
|
||||||
|
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_mul_neon(mat4 m1, mat4 m2, mat4 dest) {
|
||||||
|
/* D = R * L (Column-Major) */
|
||||||
|
|
||||||
|
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
|
||||||
|
|
||||||
|
l = glmm_load(m1[0]);
|
||||||
|
r0 = glmm_load(m2[0]);
|
||||||
|
r1 = glmm_load(m2[1]);
|
||||||
|
r2 = glmm_load(m2[2]);
|
||||||
|
r3 = glmm_load(m2[3]);
|
||||||
|
|
||||||
|
v0 = vmulq_f32(glmm_splat_x(r0), l);
|
||||||
|
v1 = vmulq_f32(glmm_splat_x(r1), l);
|
||||||
|
v2 = vmulq_f32(glmm_splat_x(r2), l);
|
||||||
|
v3 = vmulq_f32(glmm_splat_x(r3), l);
|
||||||
|
|
||||||
|
l = glmm_load(m1[1]);
|
||||||
|
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
|
||||||
|
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
|
||||||
|
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
|
||||||
|
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
|
||||||
|
|
||||||
|
l = glmm_load(m1[2]);
|
||||||
|
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
|
||||||
|
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
|
||||||
|
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
|
||||||
|
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
|
||||||
|
|
||||||
|
v3 = glmm_fmadd(glmm_splat_w(r3), glmm_load(m1[3]), v3);
|
||||||
|
|
||||||
|
glmm_store(dest[0], v0);
|
||||||
|
glmm_store(dest[1], v1);
|
||||||
|
glmm_store(dest[2], v2);
|
||||||
|
glmm_store(dest[3], v3);
|
||||||
|
}
|
||||||
|
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_mul_rot_neon(mat4 m1, mat4 m2, mat4 dest) {
|
||||||
|
/* D = R * L (Column-Major) */
|
||||||
|
|
||||||
|
glmm_128 l, r0, r1, r2, v0, v1, v2;
|
||||||
|
|
||||||
|
l = glmm_load(m1[0]);
|
||||||
|
r0 = glmm_load(m2[0]);
|
||||||
|
r1 = glmm_load(m2[1]);
|
||||||
|
r2 = glmm_load(m2[2]);
|
||||||
|
|
||||||
|
v0 = vmulq_f32(glmm_splat_x(r0), l);
|
||||||
|
v1 = vmulq_f32(glmm_splat_x(r1), l);
|
||||||
|
v2 = vmulq_f32(glmm_splat_x(r2), l);
|
||||||
|
|
||||||
|
l = glmm_load(m1[1]);
|
||||||
|
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
|
||||||
|
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
|
||||||
|
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
|
||||||
|
|
||||||
|
l = glmm_load(m1[2]);
|
||||||
|
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
|
||||||
|
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
|
||||||
|
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
|
||||||
|
|
||||||
|
glmm_store(dest[0], v0);
|
||||||
|
glmm_store(dest[1], v1);
|
||||||
|
glmm_store(dest[2], v2);
|
||||||
|
glmm_store(dest[3], glmm_load(m1[3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_inv_tr_neon(mat4 mat) {
|
||||||
|
float32x4x4_t vmat;
|
||||||
|
glmm_128 r0, r1, r2, r3, x0;
|
||||||
|
|
||||||
|
vmat = vld4q_f32(mat[0]);
|
||||||
|
r0 = vmat.val[0];
|
||||||
|
r1 = vmat.val[1];
|
||||||
|
r2 = vmat.val[2];
|
||||||
|
r3 = vmat.val[3];
|
||||||
|
|
||||||
|
x0 = glmm_fmadd(r0, glmm_splat_w(r0),
|
||||||
|
glmm_fmadd(r1, glmm_splat_w(r1),
|
||||||
|
vmulq_f32(r2, glmm_splat_w(r2))));
|
||||||
|
x0 = vnegq_f32(x0);
|
||||||
|
|
||||||
|
glmm_store(mat[0], r0);
|
||||||
|
glmm_store(mat[1], r1);
|
||||||
|
glmm_store(mat[2], r2);
|
||||||
|
glmm_store(mat[3], x0);
|
||||||
|
|
||||||
|
mat[0][3] = 0.0f;
|
||||||
|
mat[1][3] = 0.0f;
|
||||||
|
mat[2][3] = 0.0f;
|
||||||
|
mat[3][3] = 1.0f;
|
||||||
|
|
||||||
|
/* TODO: ?
|
||||||
|
zo = vget_high_f32(r3);
|
||||||
|
vst1_lane_f32(&mat[0][3], zo, 0);
|
||||||
|
vst1_lane_f32(&mat[1][3], zo, 0);
|
||||||
|
vst1_lane_f32(&mat[2][3], zo, 0);
|
||||||
|
vst1_lane_f32(&mat[3][3], zo, 1);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* cglm_affine_neon_h */
|
||||||
44
include/cglm/simd/neon/mat2.h
Normal file
44
include/cglm/simd/neon/mat2.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c), Recep Aslantas.
|
||||||
|
*
|
||||||
|
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||||
|
* Full license can be found in the LICENSE file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cglm_mat2_neon_h
|
||||||
|
#define cglm_mat2_neon_h
|
||||||
|
#if defined(__ARM_NEON_FP)
|
||||||
|
|
||||||
|
#include "../../common.h"
|
||||||
|
#include "../intrin.h"
|
||||||
|
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_mat2_mul_neon(mat2 m1, mat2 m2, mat2 dest) {
|
||||||
|
float32x4x2_t a1;
|
||||||
|
glmm_128 x0, x1, x2;
|
||||||
|
float32x2_t dc, ba;
|
||||||
|
|
||||||
|
x1 = glmm_load(m1[0]); /* d c b a */
|
||||||
|
x2 = glmm_load(m2[0]); /* h g f e */
|
||||||
|
|
||||||
|
dc = vget_high_f32(x1);
|
||||||
|
ba = vget_low_f32(x1);
|
||||||
|
|
||||||
|
/* g g e e, h h f f */
|
||||||
|
a1 = vtrnq_f32(x2, x2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
dest[0][0] = a * e + c * f;
|
||||||
|
dest[0][1] = b * e + d * f;
|
||||||
|
dest[1][0] = a * g + c * h;
|
||||||
|
dest[1][1] = b * g + d * h;
|
||||||
|
*/
|
||||||
|
x0 = glmm_fmadd(vcombine_f32(ba, ba), a1.val[0],
|
||||||
|
vmulq_f32(vcombine_f32(dc, dc), a1.val[1]));
|
||||||
|
|
||||||
|
glmm_store(dest[0], x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* cglm_mat2_neon_h */
|
||||||
@@ -42,41 +42,42 @@ CGLM_INLINE
|
|||||||
void
|
void
|
||||||
glm_mat4_mul_neon(mat4 m1, mat4 m2, mat4 dest) {
|
glm_mat4_mul_neon(mat4 m1, mat4 m2, mat4 dest) {
|
||||||
/* D = R * L (Column-Major) */
|
/* D = R * L (Column-Major) */
|
||||||
float32x4_t l0, l1, l2, l3, r, d0, d1, d2, d3;
|
|
||||||
|
|
||||||
l0 = vld1q_f32(m2[0]);
|
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
|
||||||
l1 = vld1q_f32(m2[1]);
|
|
||||||
l2 = vld1q_f32(m2[2]);
|
|
||||||
l3 = vld1q_f32(m2[3]);
|
|
||||||
|
|
||||||
r = vld1q_f32(m1[0]);
|
l = glmm_load(m1[0]);
|
||||||
d0 = vmulq_lane_f32(r, vget_low_f32(l0), 0);
|
r0 = glmm_load(m2[0]);
|
||||||
d1 = vmulq_lane_f32(r, vget_low_f32(l1), 0);
|
r1 = glmm_load(m2[1]);
|
||||||
d2 = vmulq_lane_f32(r, vget_low_f32(l2), 0);
|
r2 = glmm_load(m2[2]);
|
||||||
d3 = vmulq_lane_f32(r, vget_low_f32(l3), 0);
|
r3 = glmm_load(m2[3]);
|
||||||
|
|
||||||
r = vld1q_f32(m1[1]);
|
v0 = vmulq_f32(glmm_splat_x(r0), l);
|
||||||
d0 = vmlaq_lane_f32(d0, r, vget_low_f32(l0), 1);
|
v1 = vmulq_f32(glmm_splat_x(r1), l);
|
||||||
d1 = vmlaq_lane_f32(d1, r, vget_low_f32(l1), 1);
|
v2 = vmulq_f32(glmm_splat_x(r2), l);
|
||||||
d2 = vmlaq_lane_f32(d2, r, vget_low_f32(l2), 1);
|
v3 = vmulq_f32(glmm_splat_x(r3), l);
|
||||||
d3 = vmlaq_lane_f32(d3, r, vget_low_f32(l3), 1);
|
|
||||||
|
|
||||||
r = vld1q_f32(m1[2]);
|
l = glmm_load(m1[1]);
|
||||||
d0 = vmlaq_lane_f32(d0, r, vget_high_f32(l0), 0);
|
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
|
||||||
d1 = vmlaq_lane_f32(d1, r, vget_high_f32(l1), 0);
|
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
|
||||||
d2 = vmlaq_lane_f32(d2, r, vget_high_f32(l2), 0);
|
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
|
||||||
d3 = vmlaq_lane_f32(d3, r, vget_high_f32(l3), 0);
|
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
|
||||||
|
|
||||||
r = vld1q_f32(m1[3]);
|
l = glmm_load(m1[2]);
|
||||||
d0 = vmlaq_lane_f32(d0, r, vget_high_f32(l0), 1);
|
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
|
||||||
d1 = vmlaq_lane_f32(d1, r, vget_high_f32(l1), 1);
|
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
|
||||||
d2 = vmlaq_lane_f32(d2, r, vget_high_f32(l2), 1);
|
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
|
||||||
d3 = vmlaq_lane_f32(d3, r, vget_high_f32(l3), 1);
|
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
|
||||||
|
|
||||||
vst1q_f32(dest[0], d0);
|
l = glmm_load(m1[3]);
|
||||||
vst1q_f32(dest[1], d1);
|
v0 = glmm_fmadd(glmm_splat_w(r0), l, v0);
|
||||||
vst1q_f32(dest[2], d2);
|
v1 = glmm_fmadd(glmm_splat_w(r1), l, v1);
|
||||||
vst1q_f32(dest[3], d3);
|
v2 = glmm_fmadd(glmm_splat_w(r2), l, v2);
|
||||||
|
v3 = glmm_fmadd(glmm_splat_w(r3), l, v3);
|
||||||
|
|
||||||
|
glmm_store(dest[0], v0);
|
||||||
|
glmm_store(dest[1], v1);
|
||||||
|
glmm_store(dest[2], v2);
|
||||||
|
glmm_store(dest[3], v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
@@ -101,5 +102,216 @@ glm_mat4_mulv_neon(mat4 m, vec4 v, vec4 dest) {
|
|||||||
vst1q_f32(dest, l0);
|
vst1q_f32(dest, l0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGLM_INLINE
|
||||||
|
float
|
||||||
|
glm_mat4_det_neon(mat4 mat) {
|
||||||
|
float32x4_t r0, r1, r2, r3, x0, x1, x2;
|
||||||
|
float32x2_t ij, op, mn, kl, nn, mm, jj, ii, gh, ef, t12, t34;
|
||||||
|
float32x4x2_t a1;
|
||||||
|
float32x4_t x3 = { 0.f, -0.f, 0.f, -0.f };
|
||||||
|
|
||||||
|
/* 127 <- 0, [square] det(A) = det(At) */
|
||||||
|
r0 = glmm_load(mat[0]); /* d c b a */
|
||||||
|
r1 = vrev64q_f32(glmm_load(mat[1])); /* g h e f */
|
||||||
|
r2 = vrev64q_f32(glmm_load(mat[2])); /* l k i j */
|
||||||
|
r3 = vrev64q_f32(glmm_load(mat[3])); /* o p m n */
|
||||||
|
|
||||||
|
gh = vget_high_f32(r1);
|
||||||
|
ef = vget_low_f32(r1);
|
||||||
|
kl = vget_high_f32(r2);
|
||||||
|
ij = vget_low_f32(r2);
|
||||||
|
op = vget_high_f32(r3);
|
||||||
|
mn = vget_low_f32(r3);
|
||||||
|
mm = vdup_lane_f32(mn, 1);
|
||||||
|
nn = vdup_lane_f32(mn, 0);
|
||||||
|
ii = vdup_lane_f32(ij, 1);
|
||||||
|
jj = vdup_lane_f32(ij, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
t[1] = j * p - n * l;
|
||||||
|
t[2] = j * o - n * k;
|
||||||
|
t[3] = i * p - m * l;
|
||||||
|
t[4] = i * o - m * k;
|
||||||
|
*/
|
||||||
|
x0 = glmm_fnmadd(vcombine_f32(kl, kl), vcombine_f32(nn, mm),
|
||||||
|
vmulq_f32(vcombine_f32(op, op), vcombine_f32(jj, ii)));
|
||||||
|
|
||||||
|
t12 = vget_low_f32(x0);
|
||||||
|
t34 = vget_high_f32(x0);
|
||||||
|
|
||||||
|
/* 1 3 1 3 2 4 2 4 */
|
||||||
|
a1 = vuzpq_f32(x0, x0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
t[0] = k * p - o * l;
|
||||||
|
t[0] = k * p - o * l;
|
||||||
|
t[5] = i * n - m * j;
|
||||||
|
t[5] = i * n - m * j;
|
||||||
|
*/
|
||||||
|
x1 = glmm_fnmadd(vcombine_f32(vdup_lane_f32(kl, 0), jj),
|
||||||
|
vcombine_f32(vdup_lane_f32(op, 1), mm),
|
||||||
|
vmulq_f32(vcombine_f32(vdup_lane_f32(op, 0), nn),
|
||||||
|
vcombine_f32(vdup_lane_f32(kl, 1), ii)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
a * (f * t[0] - g * t[1] + h * t[2])
|
||||||
|
- b * (e * t[0] - g * t[3] + h * t[4])
|
||||||
|
+ c * (e * t[1] - f * t[3] + h * t[5])
|
||||||
|
- d * (e * t[2] - f * t[4] + g * t[5])
|
||||||
|
*/
|
||||||
|
x2 = glmm_fnmadd(vcombine_f32(vdup_lane_f32(gh, 1), vdup_lane_f32(ef, 0)),
|
||||||
|
vcombine_f32(vget_low_f32(a1.val[0]), t34),
|
||||||
|
vmulq_f32(vcombine_f32(ef, vdup_lane_f32(ef, 1)),
|
||||||
|
vcombine_f32(vget_low_f32(x1), t12)));
|
||||||
|
|
||||||
|
x2 = glmm_fmadd(vcombine_f32(vdup_lane_f32(gh, 0), gh),
|
||||||
|
vcombine_f32(vget_low_f32(a1.val[1]), vget_high_f32(x1)), x2);
|
||||||
|
|
||||||
|
x2 = glmm_xor(x2, x3);
|
||||||
|
|
||||||
|
return glmm_hadd(vmulq_f32(x2, r0));
|
||||||
|
}
|
||||||
|
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_mat4_inv_neon(mat4 mat, mat4 dest) {
|
||||||
|
float32x4_t r0, r1, r2, r3,
|
||||||
|
v0, v1, v2, v3,
|
||||||
|
t0, t1, t2, t3, t4, t5,
|
||||||
|
x0, x1, x2, x3, x4, x5, x6, x7, x8;
|
||||||
|
float32x4x2_t a1;
|
||||||
|
float32x2_t lp, ko, hg, jn, im, fe, ae, bf, cg, dh;
|
||||||
|
float32x4_t x9 = { -0.f, 0.f, -0.f, 0.f };
|
||||||
|
|
||||||
|
x8 = vrev64q_f32(x9);
|
||||||
|
|
||||||
|
/* 127 <- 0 */
|
||||||
|
r0 = glmm_load(mat[0]); /* d c b a */
|
||||||
|
r1 = glmm_load(mat[1]); /* h g f e */
|
||||||
|
r2 = glmm_load(mat[2]); /* l k j i */
|
||||||
|
r3 = glmm_load(mat[3]); /* p o n m */
|
||||||
|
|
||||||
|
/* l p k o, j n i m */
|
||||||
|
a1 = vzipq_f32(r3, r2);
|
||||||
|
|
||||||
|
jn = vget_high_f32(a1.val[0]);
|
||||||
|
im = vget_low_f32(a1.val[0]);
|
||||||
|
lp = vget_high_f32(a1.val[1]);
|
||||||
|
ko = vget_low_f32(a1.val[1]);
|
||||||
|
hg = vget_high_f32(r1);
|
||||||
|
|
||||||
|
x1 = vcombine_f32(vdup_lane_f32(lp, 0), lp); /* l p p p */
|
||||||
|
x2 = vcombine_f32(vdup_lane_f32(ko, 0), ko); /* k o o o */
|
||||||
|
x0 = vcombine_f32(vdup_lane_f32(lp, 1), vdup_lane_f32(hg, 1)); /* h h l l */
|
||||||
|
x3 = vcombine_f32(vdup_lane_f32(ko, 1), vdup_lane_f32(hg, 0)); /* g g k k */
|
||||||
|
|
||||||
|
/* t1[0] = k * p - o * l;
|
||||||
|
t1[0] = k * p - o * l;
|
||||||
|
t2[0] = g * p - o * h;
|
||||||
|
t3[0] = g * l - k * h; */
|
||||||
|
t0 = glmm_fnmadd(x2, x0, vmulq_f32(x3, x1));
|
||||||
|
|
||||||
|
fe = vget_low_f32(r1);
|
||||||
|
x4 = vcombine_f32(vdup_lane_f32(jn, 0), jn); /* j n n n */
|
||||||
|
x5 = vcombine_f32(vdup_lane_f32(jn, 1), vdup_lane_f32(fe, 1)); /* f f j j */
|
||||||
|
|
||||||
|
/* t1[1] = j * p - n * l;
|
||||||
|
t1[1] = j * p - n * l;
|
||||||
|
t2[1] = f * p - n * h;
|
||||||
|
t3[1] = f * l - j * h; */
|
||||||
|
t1 = glmm_fnmadd(x4, x0, vmulq_f32(x5, x1));
|
||||||
|
|
||||||
|
/* t1[2] = j * o - n * k
|
||||||
|
t1[2] = j * o - n * k;
|
||||||
|
t2[2] = f * o - n * g;
|
||||||
|
t3[2] = f * k - j * g; */
|
||||||
|
t2 = glmm_fnmadd(x4, x3, vmulq_f32(x5, x2));
|
||||||
|
|
||||||
|
x6 = vcombine_f32(vdup_lane_f32(im, 1), vdup_lane_f32(fe, 0)); /* e e i i */
|
||||||
|
x7 = vcombine_f32(vdup_lane_f32(im, 0), im); /* i m m m */
|
||||||
|
|
||||||
|
/* t1[3] = i * p - m * l;
|
||||||
|
t1[3] = i * p - m * l;
|
||||||
|
t2[3] = e * p - m * h;
|
||||||
|
t3[3] = e * l - i * h; */
|
||||||
|
t3 = glmm_fnmadd(x7, x0, vmulq_f32(x6, x1));
|
||||||
|
|
||||||
|
/* t1[4] = i * o - m * k;
|
||||||
|
t1[4] = i * o - m * k;
|
||||||
|
t2[4] = e * o - m * g;
|
||||||
|
t3[4] = e * k - i * g; */
|
||||||
|
t4 = glmm_fnmadd(x7, x3, vmulq_f32(x6, x2));
|
||||||
|
|
||||||
|
/* t1[5] = i * n - m * j;
|
||||||
|
t1[5] = i * n - m * j;
|
||||||
|
t2[5] = e * n - m * f;
|
||||||
|
t3[5] = e * j - i * f; */
|
||||||
|
t5 = glmm_fnmadd(x7, x5, vmulq_f32(x6, x4));
|
||||||
|
|
||||||
|
/* h d f b, g c e a */
|
||||||
|
a1 = vtrnq_f32(r0, r1);
|
||||||
|
|
||||||
|
x4 = vrev64q_f32(a1.val[0]); /* c g a e */
|
||||||
|
x5 = vrev64q_f32(a1.val[1]); /* d h b f */
|
||||||
|
|
||||||
|
ae = vget_low_f32(x4);
|
||||||
|
cg = vget_high_f32(x4);
|
||||||
|
bf = vget_low_f32(x5);
|
||||||
|
dh = vget_high_f32(x5);
|
||||||
|
|
||||||
|
x0 = vcombine_f32(ae, vdup_lane_f32(ae, 1)); /* a a a e */
|
||||||
|
x1 = vcombine_f32(bf, vdup_lane_f32(bf, 1)); /* b b b f */
|
||||||
|
x2 = vcombine_f32(cg, vdup_lane_f32(cg, 1)); /* c c c g */
|
||||||
|
x3 = vcombine_f32(dh, vdup_lane_f32(dh, 1)); /* d d d h */
|
||||||
|
|
||||||
|
/*
|
||||||
|
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
|
||||||
|
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
|
||||||
|
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
|
||||||
|
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
|
||||||
|
v0 = glmm_xor(glmm_fmadd(x3, t2, glmm_fnmadd(x2, t1, vmulq_f32(x1, t0))), x8);
|
||||||
|
|
||||||
|
/*
|
||||||
|
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
|
||||||
|
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
|
||||||
|
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
|
||||||
|
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
|
||||||
|
v2 = glmm_xor(glmm_fmadd(x3, t5, glmm_fnmadd(x1, t3, vmulq_f32(x0, t1))), x8);
|
||||||
|
|
||||||
|
/*
|
||||||
|
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
|
||||||
|
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
|
||||||
|
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
|
||||||
|
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
|
||||||
|
v1 = glmm_xor(glmm_fmadd(x3, t4, glmm_fnmadd(x2, t3, vmulq_f32(x0, t0))), x9);
|
||||||
|
|
||||||
|
/*
|
||||||
|
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
|
||||||
|
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
|
||||||
|
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
|
||||||
|
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
|
||||||
|
v3 = glmm_xor(glmm_fmadd(x2, t5, glmm_fnmadd(x1, t4, vmulq_f32(x0, t2))), x9);
|
||||||
|
|
||||||
|
/* determinant */
|
||||||
|
x0 = vcombine_f32(vget_low_f32(vzipq_f32(v0, v1).val[0]),
|
||||||
|
vget_low_f32(vzipq_f32(v2, v3).val[0]));
|
||||||
|
|
||||||
|
/*
|
||||||
|
x0 = glmm_div(glmm_set1(1.0f), glmm_vhadd(vmulq_f32(x0, r0)));
|
||||||
|
|
||||||
|
glmm_store(dest[0], vmulq_f32(v0, x0));
|
||||||
|
glmm_store(dest[1], vmulq_f32(v1, x0));
|
||||||
|
glmm_store(dest[2], vmulq_f32(v2, x0));
|
||||||
|
glmm_store(dest[3], vmulq_f32(v3, x0));
|
||||||
|
*/
|
||||||
|
|
||||||
|
x0 = glmm_vhadd(vmulq_f32(x0, r0));
|
||||||
|
|
||||||
|
glmm_store(dest[0], glmm_div(v0, x0));
|
||||||
|
glmm_store(dest[1], glmm_div(v1, x0));
|
||||||
|
glmm_store(dest[2], glmm_div(v2, x0));
|
||||||
|
glmm_store(dest[3], glmm_div(v3, x0));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* cglm_mat4_neon_h */
|
#endif /* cglm_mat4_neon_h */
|
||||||
|
|||||||
56
include/cglm/simd/neon/quat.h
Normal file
56
include/cglm/simd/neon/quat.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c), Recep Aslantas.
|
||||||
|
*
|
||||||
|
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||||
|
* Full license can be found in the LICENSE file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cglm_quat_neon_h
|
||||||
|
#define cglm_quat_neon_h
|
||||||
|
#if defined(__ARM_NEON_FP)
|
||||||
|
|
||||||
|
#include "../../common.h"
|
||||||
|
#include "../intrin.h"
|
||||||
|
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_quat_mul_neon(versor p, versor q, versor dest) {
|
||||||
|
/*
|
||||||
|
+ (a1 b2 + b1 a2 + c1 d2 − d1 c2)i
|
||||||
|
+ (a1 c2 − b1 d2 + c1 a2 + d1 b2)j
|
||||||
|
+ (a1 d2 + b1 c2 − c1 b2 + d1 a2)k
|
||||||
|
a1 a2 − b1 b2 − c1 c2 − d1 d2
|
||||||
|
*/
|
||||||
|
|
||||||
|
glmm_128 xp, xq, xqr, r, x, y, z, s2, s3;
|
||||||
|
glmm_128 s1 = {-0.f, 0.f, 0.f, -0.f};
|
||||||
|
float32x2_t qh, ql;
|
||||||
|
|
||||||
|
xp = glmm_load(p); /* 3 2 1 0 */
|
||||||
|
xq = glmm_load(q);
|
||||||
|
|
||||||
|
r = vmulq_f32(glmm_splat_w(xp), xq);
|
||||||
|
x = glmm_splat_x(xp);
|
||||||
|
y = glmm_splat_y(xp);
|
||||||
|
z = glmm_splat_z(xp);
|
||||||
|
|
||||||
|
ql = vget_high_f32(s1);
|
||||||
|
s3 = vcombine_f32(ql, ql);
|
||||||
|
s2 = vzipq_f32(s3, s3).val[0];
|
||||||
|
|
||||||
|
xqr = vrev64q_f32(xq);
|
||||||
|
qh = vget_high_f32(xqr);
|
||||||
|
ql = vget_low_f32(xqr);
|
||||||
|
|
||||||
|
r = glmm_fmadd(glmm_xor(x, s3), vcombine_f32(qh, ql), r);
|
||||||
|
|
||||||
|
r = glmm_fmadd(glmm_xor(y, s2), vcombine_f32(vget_high_f32(xq),
|
||||||
|
vget_low_f32(xq)), r);
|
||||||
|
|
||||||
|
r = glmm_fmadd(glmm_xor(z, s1), vcombine_f32(ql, qh), r);
|
||||||
|
|
||||||
|
glmm_store(dest, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* cglm_quat_neon_h */
|
||||||
@@ -16,75 +16,76 @@ CGLM_INLINE
|
|||||||
void
|
void
|
||||||
glm_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
|
glm_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
|
||||||
/* D = R * L (Column-Major) */
|
/* D = R * L (Column-Major) */
|
||||||
__m128 l0, l1, l2, l3, r;
|
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
|
||||||
|
|
||||||
l0 = glmm_load(m1[0]);
|
l = glmm_load(m1[0]);
|
||||||
l1 = glmm_load(m1[1]);
|
r0 = glmm_load(m2[0]);
|
||||||
l2 = glmm_load(m1[2]);
|
r1 = glmm_load(m2[1]);
|
||||||
l3 = glmm_load(m1[3]);
|
r2 = glmm_load(m2[2]);
|
||||||
|
r3 = glmm_load(m2[3]);
|
||||||
|
|
||||||
r = glmm_load(m2[0]);
|
v0 = _mm_mul_ps(glmm_splat_x(r0), l);
|
||||||
glmm_store(dest[0],
|
v1 = _mm_mul_ps(glmm_splat_x(r1), l);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
v2 = _mm_mul_ps(glmm_splat_x(r2), l);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
v3 = _mm_mul_ps(glmm_splat_x(r3), l);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
|
|
||||||
|
|
||||||
r = glmm_load(m2[1]);
|
l = glmm_load(m1[1]);
|
||||||
glmm_store(dest[1],
|
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
|
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
|
||||||
|
|
||||||
r = glmm_load(m2[2]);
|
l = glmm_load(m1[2]);
|
||||||
glmm_store(dest[2],
|
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
|
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
|
||||||
|
|
||||||
r = glmm_load(m2[3]);
|
l = glmm_load(m1[3]);
|
||||||
glmm_store(dest[3],
|
v3 = glmm_fmadd(glmm_splat_w(r3), l, v3);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
glmm_store(dest[0], v0);
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
|
glmm_store(dest[1], v1);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
|
glmm_store(dest[2], v2);
|
||||||
|
glmm_store(dest[3], v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_mul_rot_sse2(mat4 m1, mat4 m2, mat4 dest) {
|
glm_mul_rot_sse2(mat4 m1, mat4 m2, mat4 dest) {
|
||||||
/* D = R * L (Column-Major) */
|
/* D = R * L (Column-Major) */
|
||||||
__m128 l0, l1, l2, l3, r;
|
|
||||||
|
|
||||||
l0 = glmm_load(m1[0]);
|
glmm_128 l, r0, r1, r2, v0, v1, v2;
|
||||||
l1 = glmm_load(m1[1]);
|
|
||||||
l2 = glmm_load(m1[2]);
|
|
||||||
l3 = glmm_load(m1[3]);
|
|
||||||
|
|
||||||
r = glmm_load(m2[0]);
|
l = glmm_load(m1[0]);
|
||||||
glmm_store(dest[0],
|
r0 = glmm_load(m2[0]);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
r1 = glmm_load(m2[1]);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
r2 = glmm_load(m2[2]);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
|
|
||||||
|
|
||||||
r = glmm_load(m2[1]);
|
v0 = _mm_mul_ps(glmm_splat_x(r0), l);
|
||||||
glmm_store(dest[1],
|
v1 = _mm_mul_ps(glmm_splat_x(r1), l);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
v2 = _mm_mul_ps(glmm_splat_x(r2), l);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
|
|
||||||
|
|
||||||
r = glmm_load(m2[2]);
|
l = glmm_load(m1[1]);
|
||||||
glmm_store(dest[2],
|
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
|
|
||||||
|
|
||||||
glmm_store(dest[3], l3);
|
l = glmm_load(m1[2]);
|
||||||
|
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
|
||||||
|
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
|
||||||
|
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
|
||||||
|
|
||||||
|
glmm_store(dest[0], v0);
|
||||||
|
glmm_store(dest[1], v1);
|
||||||
|
glmm_store(dest[2], v2);
|
||||||
|
glmm_store(dest[3], glmm_load(m1[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_inv_tr_sse2(mat4 mat) {
|
glm_inv_tr_sse2(mat4 mat) {
|
||||||
__m128 r0, r1, r2, r3, x0, x1;
|
__m128 r0, r1, r2, r3, x0, x1, x2, x3, x4, x5;
|
||||||
|
|
||||||
r0 = glmm_load(mat[0]);
|
r0 = glmm_load(mat[0]);
|
||||||
r1 = glmm_load(mat[1]);
|
r1 = glmm_load(mat[1]);
|
||||||
@@ -94,10 +95,13 @@ glm_inv_tr_sse2(mat4 mat) {
|
|||||||
|
|
||||||
_MM_TRANSPOSE4_PS(r0, r1, r2, x1);
|
_MM_TRANSPOSE4_PS(r0, r1, r2, x1);
|
||||||
|
|
||||||
x0 = _mm_add_ps(_mm_mul_ps(r0, glmm_shuff1(r3, 0, 0, 0, 0)),
|
x2 = glmm_shuff1(r3, 0, 0, 0, 0);
|
||||||
_mm_mul_ps(r1, glmm_shuff1(r3, 1, 1, 1, 1)));
|
x3 = glmm_shuff1(r3, 1, 1, 1, 1);
|
||||||
x0 = _mm_add_ps(x0, _mm_mul_ps(r2, glmm_shuff1(r3, 2, 2, 2, 2)));
|
x4 = glmm_shuff1(r3, 2, 2, 2, 2);
|
||||||
x0 = _mm_xor_ps(x0, _mm_set1_ps(-0.f));
|
x5 = _mm_set1_ps(-0.f);
|
||||||
|
|
||||||
|
x0 = glmm_fmadd(r0, x2, glmm_fmadd(r1, x3, _mm_mul_ps(r2, x4)));
|
||||||
|
x0 = _mm_xor_ps(x0, x5);
|
||||||
|
|
||||||
x0 = _mm_add_ps(x0, x1);
|
x0 = _mm_add_ps(x0, x1);
|
||||||
|
|
||||||
|
|||||||
@@ -15,22 +15,25 @@
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_mat2_mul_sse2(mat2 m1, mat2 m2, mat2 dest) {
|
glm_mat2_mul_sse2(mat2 m1, mat2 m2, mat2 dest) {
|
||||||
__m128 x0, x1, x2;
|
__m128 x0, x1, x2, x3, x4;
|
||||||
|
|
||||||
x1 = glmm_load(m1[0]); /* d c b a */
|
x1 = glmm_load(m1[0]); /* d c b a */
|
||||||
x2 = glmm_load(m2[0]); /* h g f e */
|
x2 = glmm_load(m2[0]); /* h g f e */
|
||||||
|
|
||||||
|
x3 = glmm_shuff1(x2, 2, 2, 0, 0);
|
||||||
|
x4 = glmm_shuff1(x2, 3, 3, 1, 1);
|
||||||
|
x0 = _mm_movelh_ps(x1, x1);
|
||||||
|
x2 = _mm_movehl_ps(x1, x1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dest[0][0] = a * e + c * f;
|
dest[0][0] = a * e + c * f;
|
||||||
dest[0][1] = b * e + d * f;
|
dest[0][1] = b * e + d * f;
|
||||||
dest[1][0] = a * g + c * h;
|
dest[1][0] = a * g + c * h;
|
||||||
dest[1][1] = b * g + d * h;
|
dest[1][1] = b * g + d * h;
|
||||||
*/
|
*/
|
||||||
x0 = _mm_mul_ps(_mm_movelh_ps(x1, x1), glmm_shuff1(x2, 2, 2, 0, 0));
|
x0 = glmm_fmadd(x0, x3, _mm_mul_ps(x2, x4));
|
||||||
x1 = _mm_mul_ps(_mm_movehl_ps(x1, x1), glmm_shuff1(x2, 3, 3, 1, 1));
|
|
||||||
x1 = _mm_add_ps(x0, x1);
|
|
||||||
|
|
||||||
glmm_store(dest[0], x1);
|
glmm_store(dest[0], x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
|
|||||||
@@ -15,44 +15,61 @@
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_mat3_mul_sse2(mat3 m1, mat3 m2, mat3 dest) {
|
glm_mat3_mul_sse2(mat3 m1, mat3 m2, mat3 dest) {
|
||||||
__m128 l0, l1, l2;
|
__m128 l0, l1, l2, r0, r1, r2, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
|
||||||
__m128 r0, r1, r2;
|
|
||||||
__m128 x0, x1, x2;
|
|
||||||
|
|
||||||
l0 = _mm_loadu_ps(m1[0]);
|
l0 = _mm_loadu_ps(m1[0]);
|
||||||
l1 = _mm_loadu_ps(&m1[1][1]);
|
l1 = _mm_loadu_ps(&m1[1][1]);
|
||||||
l2 = _mm_set1_ps(m1[2][2]);
|
|
||||||
|
|
||||||
r0 = _mm_loadu_ps(m2[0]);
|
r0 = _mm_loadu_ps(m2[0]);
|
||||||
r1 = _mm_loadu_ps(&m2[1][1]);
|
r1 = _mm_loadu_ps(&m2[1][1]);
|
||||||
r2 = _mm_set1_ps(m2[2][2]);
|
|
||||||
|
|
||||||
x1 = glmm_shuff2(l0, l1, 1, 0, 3, 3, 0, 3, 2, 0);
|
x8 = glmm_shuff1(l0, 0, 2, 1, 0); /* a00 a02 a01 a00 */
|
||||||
x2 = glmm_shuff2(l1, l2, 0, 0, 3, 2, 0, 2, 1, 0);
|
x1 = glmm_shuff1(r0, 3, 0, 0, 0); /* b10 b00 b00 b00 */
|
||||||
|
x2 = _mm_shuffle_ps(l0, l1, _MM_SHUFFLE(1, 0, 3, 3)); /* a12 a11 a10 a10 */
|
||||||
|
x3 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(2, 0, 3, 1)); /* b20 b11 b10 b01 */
|
||||||
|
x0 = _mm_mul_ps(x8, x1);
|
||||||
|
|
||||||
x0 = _mm_add_ps(_mm_mul_ps(glmm_shuff1(l0, 0, 2, 1, 0),
|
x6 = glmm_shuff1(l0, 1, 0, 2, 1); /* a01 a00 a02 a01 */
|
||||||
glmm_shuff1(r0, 3, 0, 0, 0)),
|
x7 = glmm_shuff1(x3, 3, 3, 1, 1); /* b20 b20 b10 b10 */
|
||||||
_mm_mul_ps(x1, glmm_shuff2(r0, r1, 0, 0, 1, 1, 2, 0, 0, 0)));
|
l2 = _mm_load_ss(&m1[2][2]);
|
||||||
|
r2 = _mm_load_ss(&m2[2][2]);
|
||||||
|
x1 = _mm_mul_ps(x6, x7);
|
||||||
|
l2 = glmm_shuff1(l2, 0, 0, 1, 0); /* a22 a22 0.f a22 */
|
||||||
|
r2 = glmm_shuff1(r2, 0, 0, 1, 0); /* b22 b22 0.f b22 */
|
||||||
|
|
||||||
x0 = _mm_add_ps(x0,
|
x4 = glmm_shuff1(x2, 0, 3, 2, 0); /* a10 a12 a11 a10 */
|
||||||
_mm_mul_ps(x2, glmm_shuff2(r0, r1, 1, 1, 2, 2, 2, 0, 0, 0)));
|
x5 = glmm_shuff1(x2, 2, 0, 3, 2); /* a11 a10 a12 a11 */
|
||||||
|
x6 = glmm_shuff1(x3, 2, 0, 0, 0); /* b11 b01 b01 b01 */
|
||||||
|
x2 = glmm_shuff1(r1, 3, 3, 0, 0); /* b21 b21 b11 b11 */
|
||||||
|
|
||||||
_mm_storeu_ps(dest[0], x0);
|
x8 = _mm_unpackhi_ps(x8, x4); /* a10 a00 a12 a02 */
|
||||||
|
x9 = _mm_unpackhi_ps(x7, x2); /* b21 b20 b21 b20 */
|
||||||
|
|
||||||
x0 = _mm_add_ps(_mm_mul_ps(glmm_shuff1(l0, 1, 0, 2, 1),
|
x0 = glmm_fmadd(x4, x6, x0);
|
||||||
_mm_shuffle_ps(r0, r1, _MM_SHUFFLE(2, 2, 3, 3))),
|
x1 = glmm_fmadd(x5, x2, x1);
|
||||||
_mm_mul_ps(glmm_shuff1(x1, 1, 0, 2, 1),
|
|
||||||
glmm_shuff1(r1, 3, 3, 0, 0)));
|
|
||||||
|
|
||||||
x0 = _mm_add_ps(x0,
|
x2 = _mm_movehl_ps(l2, l1); /* a22 a22 a21 a20 */
|
||||||
_mm_mul_ps(glmm_shuff1(x2, 1, 0, 2, 1),
|
x3 = glmm_shuff1(x2, 0, 2, 1, 0); /* a20 a22 a21 a20 */
|
||||||
_mm_shuffle_ps(r1, r2, _MM_SHUFFLE(0, 0, 1, 1))));
|
x2 = glmm_shuff1(x2, 1, 0, 2, 1); /* a21 a20 a22 a21 */
|
||||||
|
x4 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(1, 1, 2, 2)); /* b12 b12 b02 b02 */
|
||||||
|
|
||||||
|
x5 = glmm_shuff1(x4, 3, 0, 0, 0); /* b12 b02 b02 b02 */
|
||||||
|
x4 = _mm_movehl_ps(r2, x4); /* b22 b22 b12 b12 */
|
||||||
|
x0 = glmm_fmadd(x3, x5, x0);
|
||||||
|
x1 = glmm_fmadd(x2, x4, x1);
|
||||||
|
|
||||||
_mm_storeu_ps(&dest[1][1], x0);
|
/*
|
||||||
|
Dot Product : dest[2][2] = a02 * b20 +
|
||||||
|
a12 * b21 +
|
||||||
|
a22 * b22 +
|
||||||
|
0 * 00 */
|
||||||
|
x2 = _mm_movelh_ps(x8, l2); /* 0.f a22 a12 a02 */
|
||||||
|
x3 = _mm_movelh_ps(x9, r2); /* 0.f b22 b21 b20 */
|
||||||
|
x2 = glmm_vdots(x2, x3);
|
||||||
|
|
||||||
dest[2][2] = m1[0][2] * m2[2][0]
|
_mm_storeu_ps(&dest[0][0], x0);
|
||||||
+ m1[1][2] * m2[2][1]
|
_mm_storeu_ps(&dest[1][1], x1);
|
||||||
+ m1[2][2] * m2[2][2];
|
_mm_store_ss (&dest[2][2], x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -49,53 +49,65 @@ void
|
|||||||
glm_mat4_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
|
glm_mat4_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
|
||||||
/* D = R * L (Column-Major) */
|
/* D = R * L (Column-Major) */
|
||||||
|
|
||||||
__m128 l0, l1, l2, l3, r;
|
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
|
||||||
|
|
||||||
l0 = glmm_load(m1[0]);
|
l = glmm_load(m1[0]);
|
||||||
l1 = glmm_load(m1[1]);
|
r0 = glmm_load(m2[0]);
|
||||||
l2 = glmm_load(m1[2]);
|
r1 = glmm_load(m2[1]);
|
||||||
l3 = glmm_load(m1[3]);
|
r2 = glmm_load(m2[2]);
|
||||||
|
r3 = glmm_load(m2[3]);
|
||||||
|
|
||||||
r = glmm_load(m2[0]);
|
v0 = _mm_mul_ps(glmm_splat_x(r0), l);
|
||||||
glmm_store(dest[0],
|
v1 = _mm_mul_ps(glmm_splat_x(r1), l);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
v2 = _mm_mul_ps(glmm_splat_x(r2), l);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
v3 = _mm_mul_ps(glmm_splat_x(r3), l);
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
|
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
|
|
||||||
r = glmm_load(m2[1]);
|
|
||||||
glmm_store(dest[1],
|
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
|
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
|
|
||||||
r = glmm_load(m2[2]);
|
|
||||||
glmm_store(dest[2],
|
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
|
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
|
|
||||||
|
|
||||||
r = glmm_load(m2[3]);
|
l = glmm_load(m1[1]);
|
||||||
glmm_store(dest[3],
|
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
|
||||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
|
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
|
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
|
||||||
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
|
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
|
||||||
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
|
|
||||||
|
l = glmm_load(m1[2]);
|
||||||
|
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
|
||||||
|
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
|
||||||
|
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
|
||||||
|
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
|
||||||
|
|
||||||
|
l = glmm_load(m1[3]);
|
||||||
|
v0 = glmm_fmadd(glmm_splat_w(r0), l, v0);
|
||||||
|
v1 = glmm_fmadd(glmm_splat_w(r1), l, v1);
|
||||||
|
v2 = glmm_fmadd(glmm_splat_w(r2), l, v2);
|
||||||
|
v3 = glmm_fmadd(glmm_splat_w(r3), l, v3);
|
||||||
|
|
||||||
|
glmm_store(dest[0], v0);
|
||||||
|
glmm_store(dest[1], v1);
|
||||||
|
glmm_store(dest[2], v2);
|
||||||
|
glmm_store(dest[3], v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_mat4_mulv_sse2(mat4 m, vec4 v, vec4 dest) {
|
glm_mat4_mulv_sse2(mat4 m, vec4 v, vec4 dest) {
|
||||||
__m128 x0, x1, x2;
|
__m128 x0, x1, m0, m1, m2, m3, v0, v1, v2, v3;
|
||||||
|
|
||||||
|
m0 = glmm_load(m[0]);
|
||||||
|
m1 = glmm_load(m[1]);
|
||||||
|
m2 = glmm_load(m[2]);
|
||||||
|
m3 = glmm_load(m[3]);
|
||||||
|
|
||||||
x0 = glmm_load(v);
|
x0 = glmm_load(v);
|
||||||
x1 = _mm_add_ps(_mm_mul_ps(glmm_load(m[0]), glmm_shuff1x(x0, 0)),
|
v0 = glmm_splat_x(x0);
|
||||||
_mm_mul_ps(glmm_load(m[1]), glmm_shuff1x(x0, 1)));
|
v1 = glmm_splat_y(x0);
|
||||||
|
v2 = glmm_splat_z(x0);
|
||||||
|
v3 = glmm_splat_w(x0);
|
||||||
|
|
||||||
x2 = _mm_add_ps(_mm_mul_ps(glmm_load(m[2]), glmm_shuff1x(x0, 2)),
|
x1 = _mm_mul_ps(m3, v3);
|
||||||
_mm_mul_ps(glmm_load(m[3]), glmm_shuff1x(x0, 3)));
|
x1 = glmm_fmadd(m2, v2, x1);
|
||||||
|
x1 = glmm_fmadd(m1, v1, x1);
|
||||||
|
x1 = glmm_fmadd(m0, v0, x1);
|
||||||
|
|
||||||
glmm_store(dest, _mm_add_ps(x1, x2));
|
glmm_store(dest, x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
@@ -115,20 +127,18 @@ glm_mat4_det_sse2(mat4 mat) {
|
|||||||
t[3] = i * p - m * l;
|
t[3] = i * p - m * l;
|
||||||
t[4] = i * o - m * k;
|
t[4] = i * o - m * k;
|
||||||
*/
|
*/
|
||||||
x0 = _mm_sub_ps(_mm_mul_ps(glmm_shuff1(r2, 0, 0, 1, 1),
|
x0 = glmm_fnmadd(glmm_shuff1(r3, 0, 0, 1, 1), glmm_shuff1(r2, 2, 3, 2, 3),
|
||||||
glmm_shuff1(r3, 2, 3, 2, 3)),
|
_mm_mul_ps(glmm_shuff1(r2, 0, 0, 1, 1),
|
||||||
_mm_mul_ps(glmm_shuff1(r3, 0, 0, 1, 1),
|
glmm_shuff1(r3, 2, 3, 2, 3)));
|
||||||
glmm_shuff1(r2, 2, 3, 2, 3)));
|
|
||||||
/*
|
/*
|
||||||
t[0] = k * p - o * l;
|
t[0] = k * p - o * l;
|
||||||
t[0] = k * p - o * l;
|
t[0] = k * p - o * l;
|
||||||
t[5] = i * n - m * j;
|
t[5] = i * n - m * j;
|
||||||
t[5] = i * n - m * j;
|
t[5] = i * n - m * j;
|
||||||
*/
|
*/
|
||||||
x1 = _mm_sub_ps(_mm_mul_ps(glmm_shuff1(r2, 0, 0, 2, 2),
|
x1 = glmm_fnmadd(glmm_shuff1(r3, 0, 0, 2, 2), glmm_shuff1(r2, 1, 1, 3, 3),
|
||||||
glmm_shuff1(r3, 1, 1, 3, 3)),
|
_mm_mul_ps(glmm_shuff1(r2, 0, 0, 2, 2),
|
||||||
_mm_mul_ps(glmm_shuff1(r3, 0, 0, 2, 2),
|
glmm_shuff1(r3, 1, 1, 3, 3)));
|
||||||
glmm_shuff1(r2, 1, 1, 3, 3)));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
a * (f * t[0] - g * t[1] + h * t[2])
|
a * (f * t[0] - g * t[1] + h * t[2])
|
||||||
@@ -136,21 +146,16 @@ glm_mat4_det_sse2(mat4 mat) {
|
|||||||
+ c * (e * t[1] - f * t[3] + h * t[5])
|
+ c * (e * t[1] - f * t[3] + h * t[5])
|
||||||
- d * (e * t[2] - f * t[4] + g * t[5])
|
- d * (e * t[2] - f * t[4] + g * t[5])
|
||||||
*/
|
*/
|
||||||
x2 = _mm_sub_ps(_mm_mul_ps(glmm_shuff1(r1, 0, 0, 0, 1),
|
x2 = glmm_fnmadd(glmm_shuff1(r1, 1, 1, 2, 2), glmm_shuff1(x0, 3, 2, 2, 0),
|
||||||
_mm_shuffle_ps(x1, x0, _MM_SHUFFLE(1, 0, 0, 0))),
|
_mm_mul_ps(glmm_shuff1(r1, 0, 0, 0, 1),
|
||||||
_mm_mul_ps(glmm_shuff1(r1, 1, 1, 2, 2),
|
_mm_shuffle_ps(x1, x0, _MM_SHUFFLE(1, 0, 0, 0))));
|
||||||
glmm_shuff1(x0, 3, 2, 2, 0)));
|
x2 = glmm_fmadd(glmm_shuff1(r1, 2, 3, 3, 3),
|
||||||
|
_mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1)),
|
||||||
x2 = _mm_add_ps(x2,
|
x2);
|
||||||
_mm_mul_ps(glmm_shuff1(r1, 2, 3, 3, 3),
|
|
||||||
_mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1))));
|
|
||||||
x2 = _mm_xor_ps(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
x2 = _mm_xor_ps(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
||||||
|
|
||||||
x0 = _mm_mul_ps(r0, x2);
|
return glmm_hadd(_mm_mul_ps(x2, r0));
|
||||||
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 0, 1, 2, 3));
|
|
||||||
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 3, 3, 1));
|
|
||||||
|
|
||||||
return _mm_cvtss_f32(x0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
@@ -159,117 +164,129 @@ glm_mat4_inv_fast_sse2(mat4 mat, mat4 dest) {
|
|||||||
__m128 r0, r1, r2, r3,
|
__m128 r0, r1, r2, r3,
|
||||||
v0, v1, v2, v3,
|
v0, v1, v2, v3,
|
||||||
t0, t1, t2, t3, t4, t5,
|
t0, t1, t2, t3, t4, t5,
|
||||||
x0, x1, x2, x3, x4, x5, x6, x7;
|
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
|
||||||
|
|
||||||
|
x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f);
|
||||||
|
x9 = glmm_shuff1(x8, 2, 1, 2, 1);
|
||||||
|
|
||||||
/* 127 <- 0 */
|
/* 127 <- 0 */
|
||||||
r0 = glmm_load(mat[0]); /* d c b a */
|
r0 = glmm_load(mat[0]); /* d c b a */
|
||||||
r1 = glmm_load(mat[1]); /* h g f e */
|
r1 = glmm_load(mat[1]); /* h g f e */
|
||||||
r2 = glmm_load(mat[2]); /* l k j i */
|
r2 = glmm_load(mat[2]); /* l k j i */
|
||||||
r3 = glmm_load(mat[3]); /* p o n m */
|
r3 = glmm_load(mat[3]); /* p o n m */
|
||||||
|
|
||||||
x0 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(3, 2, 3, 2)); /* p o l k */
|
x0 = _mm_movehl_ps(r3, r2); /* p o l k */
|
||||||
x1 = glmm_shuff1(x0, 1, 3, 3, 3); /* l p p p */
|
x3 = _mm_movelh_ps(r2, r3); /* n m j i */
|
||||||
|
x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */
|
||||||
x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */
|
x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */
|
||||||
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
|
x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */
|
||||||
x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */
|
x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */
|
||||||
|
|
||||||
|
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
|
||||||
|
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
|
||||||
|
x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */
|
||||||
|
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
|
||||||
|
|
||||||
|
t0 = _mm_mul_ps(x3, x1);
|
||||||
|
t1 = _mm_mul_ps(x5, x1);
|
||||||
|
t2 = _mm_mul_ps(x5, x2);
|
||||||
|
t3 = _mm_mul_ps(x6, x1);
|
||||||
|
t4 = _mm_mul_ps(x6, x2);
|
||||||
|
t5 = _mm_mul_ps(x6, x4);
|
||||||
|
|
||||||
/* t1[0] = k * p - o * l;
|
/* t1[0] = k * p - o * l;
|
||||||
t1[0] = k * p - o * l;
|
t1[0] = k * p - o * l;
|
||||||
t2[0] = g * p - o * h;
|
t2[0] = g * p - o * h;
|
||||||
t3[0] = g * l - k * h; */
|
t3[0] = g * l - k * h; */
|
||||||
t0 = _mm_sub_ps(_mm_mul_ps(x3, x1), _mm_mul_ps(x2, x0));
|
t0 = glmm_fnmadd(x2, x0, t0);
|
||||||
|
|
||||||
x4 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(2, 1, 2, 1)); /* o n k j */
|
|
||||||
x4 = glmm_shuff1(x4, 0, 2, 2, 2); /* j n n n */
|
|
||||||
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
|
|
||||||
|
|
||||||
/* t1[1] = j * p - n * l;
|
/* t1[1] = j * p - n * l;
|
||||||
t1[1] = j * p - n * l;
|
t1[1] = j * p - n * l;
|
||||||
t2[1] = f * p - n * h;
|
t2[1] = f * p - n * h;
|
||||||
t3[1] = f * l - j * h; */
|
t3[1] = f * l - j * h; */
|
||||||
t1 = _mm_sub_ps(_mm_mul_ps(x5, x1), _mm_mul_ps(x4, x0));
|
t1 = glmm_fnmadd(x4, x0, t1);
|
||||||
|
|
||||||
/* t1[2] = j * o - n * k
|
/* t1[2] = j * o - n * k
|
||||||
t1[2] = j * o - n * k;
|
t1[2] = j * o - n * k;
|
||||||
t2[2] = f * o - n * g;
|
t2[2] = f * o - n * g;
|
||||||
t3[2] = f * k - j * g; */
|
t3[2] = f * k - j * g; */
|
||||||
t2 = _mm_sub_ps(_mm_mul_ps(x5, x2), _mm_mul_ps(x4, x3));
|
t2 = glmm_fnmadd(x4, x3, t2);
|
||||||
|
|
||||||
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
|
|
||||||
x7 = glmm_shuff2(r3, r2, 0, 0, 0, 0, 2, 0, 0, 0); /* i m m m */
|
|
||||||
|
|
||||||
/* t1[3] = i * p - m * l;
|
/* t1[3] = i * p - m * l;
|
||||||
t1[3] = i * p - m * l;
|
t1[3] = i * p - m * l;
|
||||||
t2[3] = e * p - m * h;
|
t2[3] = e * p - m * h;
|
||||||
t3[3] = e * l - i * h; */
|
t3[3] = e * l - i * h; */
|
||||||
t3 = _mm_sub_ps(_mm_mul_ps(x6, x1), _mm_mul_ps(x7, x0));
|
t3 = glmm_fnmadd(x7, x0, t3);
|
||||||
|
|
||||||
/* t1[4] = i * o - m * k;
|
/* t1[4] = i * o - m * k;
|
||||||
t1[4] = i * o - m * k;
|
t1[4] = i * o - m * k;
|
||||||
t2[4] = e * o - m * g;
|
t2[4] = e * o - m * g;
|
||||||
t3[4] = e * k - i * g; */
|
t3[4] = e * k - i * g; */
|
||||||
t4 = _mm_sub_ps(_mm_mul_ps(x6, x2), _mm_mul_ps(x7, x3));
|
t4 = glmm_fnmadd(x7, x3, t4);
|
||||||
|
|
||||||
/* t1[5] = i * n - m * j;
|
/* t1[5] = i * n - m * j;
|
||||||
t1[5] = i * n - m * j;
|
t1[5] = i * n - m * j;
|
||||||
t2[5] = e * n - m * f;
|
t2[5] = e * n - m * f;
|
||||||
t3[5] = e * j - i * f; */
|
t3[5] = e * j - i * f; */
|
||||||
t5 = _mm_sub_ps(_mm_mul_ps(x6, x4), _mm_mul_ps(x7, x5));
|
t5 = glmm_fnmadd(x7, x5, t5);
|
||||||
|
|
||||||
x0 = glmm_shuff2(r1, r0, 0, 0, 0, 0, 2, 2, 2, 0); /* a a a e */
|
x4 = _mm_movelh_ps(r0, r1); /* f e b a */
|
||||||
x1 = glmm_shuff2(r1, r0, 1, 1, 1, 1, 2, 2, 2, 0); /* b b b f */
|
x5 = _mm_movehl_ps(r1, r0); /* h g d c */
|
||||||
x2 = glmm_shuff2(r1, r0, 2, 2, 2, 2, 2, 2, 2, 0); /* c c c g */
|
|
||||||
x3 = glmm_shuff2(r1, r0, 3, 3, 3, 3, 2, 2, 2, 0); /* d d d h */
|
x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */
|
||||||
|
x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */
|
||||||
|
x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */
|
||||||
|
x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */
|
||||||
|
|
||||||
|
v2 = _mm_mul_ps(x0, t1);
|
||||||
|
v1 = _mm_mul_ps(x0, t0);
|
||||||
|
v3 = _mm_mul_ps(x0, t2);
|
||||||
|
v0 = _mm_mul_ps(x1, t0);
|
||||||
|
|
||||||
|
v2 = glmm_fnmadd(x1, t3, v2);
|
||||||
|
v3 = glmm_fnmadd(x1, t4, v3);
|
||||||
|
v0 = glmm_fnmadd(x2, t1, v0);
|
||||||
|
v1 = glmm_fnmadd(x2, t3, v1);
|
||||||
|
|
||||||
|
v3 = glmm_fmadd(x2, t5, v3);
|
||||||
|
v0 = glmm_fmadd(x3, t2, v0);
|
||||||
|
v2 = glmm_fmadd(x3, t5, v2);
|
||||||
|
v1 = glmm_fmadd(x3, t4, v1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
|
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
|
||||||
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
|
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
|
||||||
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
|
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
|
||||||
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
|
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
|
||||||
v0 = _mm_add_ps(_mm_mul_ps(x3, t2),
|
v0 = _mm_xor_ps(v0, x8);
|
||||||
_mm_sub_ps(_mm_mul_ps(x1, t0),
|
|
||||||
_mm_mul_ps(x2, t1)));
|
/*
|
||||||
v0 = _mm_xor_ps(v0, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
|
||||||
|
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
|
||||||
|
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
|
||||||
|
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
|
||||||
|
v2 = _mm_xor_ps(v2, x8);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
|
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
|
||||||
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
|
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
|
||||||
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
|
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
|
||||||
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
|
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
|
||||||
v1 = _mm_add_ps(_mm_mul_ps(x3, t4),
|
v1 = _mm_xor_ps(v1, x9);
|
||||||
_mm_sub_ps(_mm_mul_ps(x0, t0),
|
|
||||||
_mm_mul_ps(x2, t3)));
|
|
||||||
v1 = _mm_xor_ps(v1, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
|
|
||||||
|
|
||||||
/*
|
|
||||||
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
|
|
||||||
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
|
|
||||||
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
|
|
||||||
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
|
|
||||||
v2 = _mm_add_ps(_mm_mul_ps(x3, t5),
|
|
||||||
_mm_sub_ps(_mm_mul_ps(x0, t1),
|
|
||||||
_mm_mul_ps(x1, t3)));
|
|
||||||
v2 = _mm_xor_ps(v2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
|
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
|
||||||
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
|
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
|
||||||
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
|
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
|
||||||
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
|
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
|
||||||
v3 = _mm_add_ps(_mm_mul_ps(x2, t5),
|
v3 = _mm_xor_ps(v3, x9);
|
||||||
_mm_sub_ps(_mm_mul_ps(x0, t2),
|
|
||||||
_mm_mul_ps(x1, t4)));
|
|
||||||
v3 = _mm_xor_ps(v3, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
|
|
||||||
|
|
||||||
/* determinant */
|
/* determinant */
|
||||||
x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0));
|
x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0));
|
||||||
x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0));
|
x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0));
|
||||||
x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0));
|
x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0));
|
||||||
|
|
||||||
x0 = _mm_mul_ps(x0, r0);
|
x0 = _mm_rcp_ps(glmm_vhadd(_mm_mul_ps(x0, r0)));
|
||||||
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 0, 1, 2, 3));
|
|
||||||
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 0, 0, 1));
|
|
||||||
x0 = _mm_rcp_ps(x0);
|
|
||||||
|
|
||||||
glmm_store(dest[0], _mm_mul_ps(v0, x0));
|
glmm_store(dest[0], _mm_mul_ps(v0, x0));
|
||||||
glmm_store(dest[1], _mm_mul_ps(v1, x0));
|
glmm_store(dest[1], _mm_mul_ps(v1, x0));
|
||||||
@@ -283,117 +300,129 @@ glm_mat4_inv_sse2(mat4 mat, mat4 dest) {
|
|||||||
__m128 r0, r1, r2, r3,
|
__m128 r0, r1, r2, r3,
|
||||||
v0, v1, v2, v3,
|
v0, v1, v2, v3,
|
||||||
t0, t1, t2, t3, t4, t5,
|
t0, t1, t2, t3, t4, t5,
|
||||||
x0, x1, x2, x3, x4, x5, x6, x7;
|
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
|
||||||
|
|
||||||
|
x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f);
|
||||||
|
x9 = glmm_shuff1(x8, 2, 1, 2, 1);
|
||||||
|
|
||||||
/* 127 <- 0 */
|
/* 127 <- 0 */
|
||||||
r0 = glmm_load(mat[0]); /* d c b a */
|
r0 = glmm_load(mat[0]); /* d c b a */
|
||||||
r1 = glmm_load(mat[1]); /* h g f e */
|
r1 = glmm_load(mat[1]); /* h g f e */
|
||||||
r2 = glmm_load(mat[2]); /* l k j i */
|
r2 = glmm_load(mat[2]); /* l k j i */
|
||||||
r3 = glmm_load(mat[3]); /* p o n m */
|
r3 = glmm_load(mat[3]); /* p o n m */
|
||||||
|
|
||||||
x0 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(3, 2, 3, 2)); /* p o l k */
|
x0 = _mm_movehl_ps(r3, r2); /* p o l k */
|
||||||
x1 = glmm_shuff1(x0, 1, 3, 3, 3); /* l p p p */
|
x3 = _mm_movelh_ps(r2, r3); /* n m j i */
|
||||||
|
x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */
|
||||||
x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */
|
x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */
|
||||||
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
|
x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */
|
||||||
x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */
|
x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */
|
||||||
|
|
||||||
|
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
|
||||||
|
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
|
||||||
|
x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */
|
||||||
|
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
|
||||||
|
|
||||||
|
t0 = _mm_mul_ps(x3, x1);
|
||||||
|
t1 = _mm_mul_ps(x5, x1);
|
||||||
|
t2 = _mm_mul_ps(x5, x2);
|
||||||
|
t3 = _mm_mul_ps(x6, x1);
|
||||||
|
t4 = _mm_mul_ps(x6, x2);
|
||||||
|
t5 = _mm_mul_ps(x6, x4);
|
||||||
|
|
||||||
/* t1[0] = k * p - o * l;
|
/* t1[0] = k * p - o * l;
|
||||||
t1[0] = k * p - o * l;
|
t1[0] = k * p - o * l;
|
||||||
t2[0] = g * p - o * h;
|
t2[0] = g * p - o * h;
|
||||||
t3[0] = g * l - k * h; */
|
t3[0] = g * l - k * h; */
|
||||||
t0 = _mm_sub_ps(_mm_mul_ps(x3, x1), _mm_mul_ps(x2, x0));
|
t0 = glmm_fnmadd(x2, x0, t0);
|
||||||
|
|
||||||
x4 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(2, 1, 2, 1)); /* o n k j */
|
|
||||||
x4 = glmm_shuff1(x4, 0, 2, 2, 2); /* j n n n */
|
|
||||||
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
|
|
||||||
|
|
||||||
/* t1[1] = j * p - n * l;
|
/* t1[1] = j * p - n * l;
|
||||||
t1[1] = j * p - n * l;
|
t1[1] = j * p - n * l;
|
||||||
t2[1] = f * p - n * h;
|
t2[1] = f * p - n * h;
|
||||||
t3[1] = f * l - j * h; */
|
t3[1] = f * l - j * h; */
|
||||||
t1 = _mm_sub_ps(_mm_mul_ps(x5, x1), _mm_mul_ps(x4, x0));
|
t1 = glmm_fnmadd(x4, x0, t1);
|
||||||
|
|
||||||
/* t1[2] = j * o - n * k
|
/* t1[2] = j * o - n * k
|
||||||
t1[2] = j * o - n * k;
|
t1[2] = j * o - n * k;
|
||||||
t2[2] = f * o - n * g;
|
t2[2] = f * o - n * g;
|
||||||
t3[2] = f * k - j * g; */
|
t3[2] = f * k - j * g; */
|
||||||
t2 = _mm_sub_ps(_mm_mul_ps(x5, x2), _mm_mul_ps(x4, x3));
|
t2 = glmm_fnmadd(x4, x3, t2);
|
||||||
|
|
||||||
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
|
|
||||||
x7 = glmm_shuff2(r3, r2, 0, 0, 0, 0, 2, 0, 0, 0); /* i m m m */
|
|
||||||
|
|
||||||
/* t1[3] = i * p - m * l;
|
/* t1[3] = i * p - m * l;
|
||||||
t1[3] = i * p - m * l;
|
t1[3] = i * p - m * l;
|
||||||
t2[3] = e * p - m * h;
|
t2[3] = e * p - m * h;
|
||||||
t3[3] = e * l - i * h; */
|
t3[3] = e * l - i * h; */
|
||||||
t3 = _mm_sub_ps(_mm_mul_ps(x6, x1), _mm_mul_ps(x7, x0));
|
t3 = glmm_fnmadd(x7, x0, t3);
|
||||||
|
|
||||||
/* t1[4] = i * o - m * k;
|
/* t1[4] = i * o - m * k;
|
||||||
t1[4] = i * o - m * k;
|
t1[4] = i * o - m * k;
|
||||||
t2[4] = e * o - m * g;
|
t2[4] = e * o - m * g;
|
||||||
t3[4] = e * k - i * g; */
|
t3[4] = e * k - i * g; */
|
||||||
t4 = _mm_sub_ps(_mm_mul_ps(x6, x2), _mm_mul_ps(x7, x3));
|
t4 = glmm_fnmadd(x7, x3, t4);
|
||||||
|
|
||||||
/* t1[5] = i * n - m * j;
|
/* t1[5] = i * n - m * j;
|
||||||
t1[5] = i * n - m * j;
|
t1[5] = i * n - m * j;
|
||||||
t2[5] = e * n - m * f;
|
t2[5] = e * n - m * f;
|
||||||
t3[5] = e * j - i * f; */
|
t3[5] = e * j - i * f; */
|
||||||
t5 = _mm_sub_ps(_mm_mul_ps(x6, x4), _mm_mul_ps(x7, x5));
|
t5 = glmm_fnmadd(x7, x5, t5);
|
||||||
|
|
||||||
x0 = glmm_shuff2(r1, r0, 0, 0, 0, 0, 2, 2, 2, 0); /* a a a e */
|
x4 = _mm_movelh_ps(r0, r1); /* f e b a */
|
||||||
x1 = glmm_shuff2(r1, r0, 1, 1, 1, 1, 2, 2, 2, 0); /* b b b f */
|
x5 = _mm_movehl_ps(r1, r0); /* h g d c */
|
||||||
x2 = glmm_shuff2(r1, r0, 2, 2, 2, 2, 2, 2, 2, 0); /* c c c g */
|
|
||||||
x3 = glmm_shuff2(r1, r0, 3, 3, 3, 3, 2, 2, 2, 0); /* d d d h */
|
x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */
|
||||||
|
x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */
|
||||||
|
x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */
|
||||||
|
x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */
|
||||||
|
|
||||||
|
v2 = _mm_mul_ps(x0, t1);
|
||||||
|
v1 = _mm_mul_ps(x0, t0);
|
||||||
|
v3 = _mm_mul_ps(x0, t2);
|
||||||
|
v0 = _mm_mul_ps(x1, t0);
|
||||||
|
|
||||||
|
v2 = glmm_fnmadd(x1, t3, v2);
|
||||||
|
v3 = glmm_fnmadd(x1, t4, v3);
|
||||||
|
v0 = glmm_fnmadd(x2, t1, v0);
|
||||||
|
v1 = glmm_fnmadd(x2, t3, v1);
|
||||||
|
|
||||||
|
v3 = glmm_fmadd(x2, t5, v3);
|
||||||
|
v0 = glmm_fmadd(x3, t2, v0);
|
||||||
|
v2 = glmm_fmadd(x3, t5, v2);
|
||||||
|
v1 = glmm_fmadd(x3, t4, v1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
|
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
|
||||||
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
|
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
|
||||||
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
|
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
|
||||||
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
|
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
|
||||||
v0 = _mm_add_ps(_mm_mul_ps(x3, t2),
|
v0 = _mm_xor_ps(v0, x8);
|
||||||
_mm_sub_ps(_mm_mul_ps(x1, t0),
|
|
||||||
_mm_mul_ps(x2, t1)));
|
/*
|
||||||
v0 = _mm_xor_ps(v0, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
|
||||||
|
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
|
||||||
|
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
|
||||||
|
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
|
||||||
|
v2 = _mm_xor_ps(v2, x8);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
|
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
|
||||||
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
|
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
|
||||||
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
|
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
|
||||||
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
|
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
|
||||||
v1 = _mm_add_ps(_mm_mul_ps(x3, t4),
|
v1 = _mm_xor_ps(v1, x9);
|
||||||
_mm_sub_ps(_mm_mul_ps(x0, t0),
|
|
||||||
_mm_mul_ps(x2, t3)));
|
|
||||||
v1 = _mm_xor_ps(v1, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
|
|
||||||
|
|
||||||
/*
|
|
||||||
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
|
|
||||||
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
|
|
||||||
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
|
|
||||||
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
|
|
||||||
v2 = _mm_add_ps(_mm_mul_ps(x3, t5),
|
|
||||||
_mm_sub_ps(_mm_mul_ps(x0, t1),
|
|
||||||
_mm_mul_ps(x1, t3)));
|
|
||||||
v2 = _mm_xor_ps(v2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
|
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
|
||||||
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
|
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
|
||||||
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
|
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
|
||||||
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
|
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
|
||||||
v3 = _mm_add_ps(_mm_mul_ps(x2, t5),
|
v3 = _mm_xor_ps(v3, x9);
|
||||||
_mm_sub_ps(_mm_mul_ps(x0, t2),
|
|
||||||
_mm_mul_ps(x1, t4)));
|
|
||||||
v3 = _mm_xor_ps(v3, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
|
|
||||||
|
|
||||||
/* determinant */
|
/* determinant */
|
||||||
x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0));
|
x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0));
|
||||||
x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0));
|
x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0));
|
||||||
x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0));
|
x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0));
|
||||||
|
|
||||||
x0 = _mm_mul_ps(x0, r0);
|
x0 = _mm_div_ps(_mm_set1_ps(1.0f), glmm_vhadd(_mm_mul_ps(x0, r0)));
|
||||||
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 0, 1, 2, 3));
|
|
||||||
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 0, 0, 1));
|
|
||||||
x0 = _mm_div_ps(_mm_set1_ps(1.0f), x0);
|
|
||||||
|
|
||||||
glmm_store(dest[0], _mm_mul_ps(v0, x0));
|
glmm_store(dest[0], _mm_mul_ps(v0, x0));
|
||||||
glmm_store(dest[1], _mm_mul_ps(v1, x0));
|
glmm_store(dest[1], _mm_mul_ps(v1, x0));
|
||||||
|
|||||||
@@ -22,25 +22,33 @@ glm_quat_mul_sse2(versor p, versor q, versor dest) {
|
|||||||
a1 a2 − b1 b2 − c1 c2 − d1 d2
|
a1 a2 − b1 b2 − c1 c2 − d1 d2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
__m128 xp, xq, x0, r;
|
__m128 xp, xq, x1, x2, x3, r, x, y, z;
|
||||||
|
|
||||||
xp = glmm_load(p); /* 3 2 1 0 */
|
xp = glmm_load(p); /* 3 2 1 0 */
|
||||||
xq = glmm_load(q);
|
xq = glmm_load(q);
|
||||||
|
x1 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); /* TODO: _mm_set1_ss() + shuff ? */
|
||||||
|
r = _mm_mul_ps(glmm_splat_w(xp), xq);
|
||||||
|
|
||||||
|
x2 = _mm_unpackhi_ps(x1, x1);
|
||||||
|
x3 = glmm_shuff1(x1, 3, 2, 0, 1);
|
||||||
|
x = glmm_splat_x(xp);
|
||||||
|
y = glmm_splat_y(xp);
|
||||||
|
z = glmm_splat_z(xp);
|
||||||
|
|
||||||
r = _mm_mul_ps(glmm_shuff1x(xp, 3), xq);
|
x = _mm_xor_ps(x, x1);
|
||||||
|
y = _mm_xor_ps(y, x2);
|
||||||
x0 = _mm_xor_ps(glmm_shuff1x(xp, 0), _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
z = _mm_xor_ps(z, x3);
|
||||||
r = _mm_add_ps(r, _mm_mul_ps(x0, glmm_shuff1(xq, 0, 1, 2, 3)));
|
|
||||||
|
x1 = glmm_shuff1(xq, 0, 1, 2, 3);
|
||||||
x0 = _mm_xor_ps(glmm_shuff1x(xp, 1), _mm_set_ps(-0.f, -0.f, 0.f, 0.f));
|
x2 = glmm_shuff1(xq, 1, 0, 3, 2);
|
||||||
r = _mm_add_ps(r, _mm_mul_ps(x0, glmm_shuff1(xq, 1, 0, 3, 2)));
|
x3 = glmm_shuff1(xq, 2, 3, 0, 1);
|
||||||
|
|
||||||
x0 = _mm_xor_ps(glmm_shuff1x(xp, 2), _mm_set_ps(-0.f, 0.f, 0.f, -0.f));
|
r = glmm_fmadd(x, x1, r);
|
||||||
r = _mm_add_ps(r, _mm_mul_ps(x0, glmm_shuff1(xq, 2, 3, 0, 1)));
|
r = glmm_fmadd(y, x2, r);
|
||||||
|
r = glmm_fmadd(z, x3, r);
|
||||||
|
|
||||||
glmm_store(dest, r);
|
glmm_store(dest, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* cglm_quat_simd_h */
|
#endif /* cglm_quat_simd_h */
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
# define glmm_store(p, a) _mm_store_ps(p, a)
|
# define glmm_store(p, a) _mm_store_ps(p, a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define glmm_set1(x) _mm_set1_ps(x)
|
||||||
|
#define glmm_128 __m128
|
||||||
|
|
||||||
#ifdef CGLM_USE_INT_DOMAIN
|
#ifdef CGLM_USE_INT_DOMAIN
|
||||||
# define glmm_shuff1(xmm, z, y, x, w) \
|
# define glmm_shuff1(xmm, z, y, x, w) \
|
||||||
_mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(xmm), \
|
_mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(xmm), \
|
||||||
@@ -27,7 +30,16 @@
|
|||||||
_mm_shuffle_ps(xmm, xmm, _MM_SHUFFLE(z, y, x, w))
|
_mm_shuffle_ps(xmm, xmm, _MM_SHUFFLE(z, y, x, w))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define glmm_splat(x, lane) glmm_shuff1(x, lane, lane, lane, lane)
|
||||||
|
|
||||||
|
#define glmm_splat_x(x) glmm_splat(x, 0)
|
||||||
|
#define glmm_splat_y(x) glmm_splat(x, 1)
|
||||||
|
#define glmm_splat_z(x) glmm_splat(x, 2)
|
||||||
|
#define glmm_splat_w(x) glmm_splat(x, 3)
|
||||||
|
|
||||||
|
/* glmm_shuff1x() is DEPRECATED!, use glmm_splat() */
|
||||||
#define glmm_shuff1x(xmm, x) glmm_shuff1(xmm, x, x, x, x)
|
#define glmm_shuff1x(xmm, x) glmm_shuff1(xmm, x, x, x, x)
|
||||||
|
|
||||||
#define glmm_shuff2(a, b, z0, y0, x0, w0, z1, y1, x1, w1) \
|
#define glmm_shuff2(a, b, z0, y0, x0, w0, z1, y1, x1, w1) \
|
||||||
glmm_shuff1(_mm_shuffle_ps(a, b, _MM_SHUFFLE(z0, y0, x0, w0)), \
|
glmm_shuff1(_mm_shuffle_ps(a, b, _MM_SHUFFLE(z0, y0, x0, w0)), \
|
||||||
z1, y1, x1, w1)
|
z1, y1, x1, w1)
|
||||||
@@ -48,6 +60,15 @@ glmm_abs(__m128 x) {
|
|||||||
return _mm_andnot_ps(_mm_set1_ps(-0.0f), x);
|
return _mm_andnot_ps(_mm_set1_ps(-0.0f), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m128
|
||||||
|
glmm_vhadd(__m128 v) {
|
||||||
|
__m128 x0;
|
||||||
|
x0 = _mm_add_ps(v, glmm_shuff1(v, 0, 1, 2, 3));
|
||||||
|
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 0, 0, 1));
|
||||||
|
return x0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
__m128
|
__m128
|
||||||
glmm_vhadds(__m128 v) {
|
glmm_vhadds(__m128 v) {
|
||||||
@@ -80,7 +101,7 @@ glmm_vhmin(__m128 v) {
|
|||||||
__m128 x0, x1, x2;
|
__m128 x0, x1, x2;
|
||||||
x0 = _mm_movehl_ps(v, v); /* [2, 3, 2, 3] */
|
x0 = _mm_movehl_ps(v, v); /* [2, 3, 2, 3] */
|
||||||
x1 = _mm_min_ps(x0, v); /* [0|2, 1|3, 2|2, 3|3] */
|
x1 = _mm_min_ps(x0, v); /* [0|2, 1|3, 2|2, 3|3] */
|
||||||
x2 = glmm_shuff1x(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
|
x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
|
||||||
return _mm_min_ss(x1, x2);
|
return _mm_min_ss(x1, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +117,7 @@ glmm_vhmax(__m128 v) {
|
|||||||
__m128 x0, x1, x2;
|
__m128 x0, x1, x2;
|
||||||
x0 = _mm_movehl_ps(v, v); /* [2, 3, 2, 3] */
|
x0 = _mm_movehl_ps(v, v); /* [2, 3, 2, 3] */
|
||||||
x1 = _mm_max_ps(x0, v); /* [0|2, 1|3, 2|2, 3|3] */
|
x1 = _mm_max_ps(x0, v); /* [0|2, 1|3, 2|2, 3|3] */
|
||||||
x2 = glmm_shuff1x(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
|
x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
|
||||||
return _mm_max_ss(x1, x2);
|
return _mm_max_ss(x1, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +196,7 @@ glmm_load3(float v[3]) {
|
|||||||
__m128i xy;
|
__m128i xy;
|
||||||
__m128 z;
|
__m128 z;
|
||||||
|
|
||||||
xy = _mm_loadl_epi64((const __m128i *)v);
|
xy = _mm_loadl_epi64(CGLM_CASTPTR_ASSUME_ALIGNED(v, const __m128i));
|
||||||
z = _mm_load_ss(&v[2]);
|
z = _mm_load_ss(&v[2]);
|
||||||
|
|
||||||
return _mm_movelh_ps(_mm_castsi128_ps(xy), z);
|
return _mm_movelh_ps(_mm_castsi128_ps(xy), z);
|
||||||
@@ -184,9 +205,103 @@ glmm_load3(float v[3]) {
|
|||||||
static inline
|
static inline
|
||||||
void
|
void
|
||||||
glmm_store3(float v[3], __m128 vx) {
|
glmm_store3(float v[3], __m128 vx) {
|
||||||
_mm_storel_pi((__m64 *)&v[0], vx);
|
_mm_storel_pi(CGLM_CASTPTR_ASSUME_ALIGNED(v, __m64), vx);
|
||||||
_mm_store_ss(&v[2], glmm_shuff1(vx, 2, 2, 2, 2));
|
_mm_store_ss(&v[2], glmm_shuff1(vx, 2, 2, 2, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m128
|
||||||
|
glmm_div(__m128 a, __m128 b) {
|
||||||
|
return _mm_div_ps(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable FMA macro for MSVC? */
|
||||||
|
#if defined(_MSC_VER) && !defined(__FMA__) && defined(__AVX2__)
|
||||||
|
# define __FMA__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m128
|
||||||
|
glmm_fmadd(__m128 a, __m128 b, __m128 c) {
|
||||||
|
#ifdef __FMA__
|
||||||
|
return _mm_fmadd_ps(a, b, c);
|
||||||
|
#else
|
||||||
|
return _mm_add_ps(c, _mm_mul_ps(a, b));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m128
|
||||||
|
glmm_fnmadd(__m128 a, __m128 b, __m128 c) {
|
||||||
|
#ifdef __FMA__
|
||||||
|
return _mm_fnmadd_ps(a, b, c);
|
||||||
|
#else
|
||||||
|
return _mm_sub_ps(c, _mm_mul_ps(a, b));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m128
|
||||||
|
glmm_fmsub(__m128 a, __m128 b, __m128 c) {
|
||||||
|
#ifdef __FMA__
|
||||||
|
return _mm_fmsub_ps(a, b, c);
|
||||||
|
#else
|
||||||
|
return _mm_sub_ps(_mm_mul_ps(a, b), c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m128
|
||||||
|
glmm_fnmsub(__m128 a, __m128 b, __m128 c) {
|
||||||
|
#ifdef __FMA__
|
||||||
|
return _mm_fnmsub_ps(a, b, c);
|
||||||
|
#else
|
||||||
|
return _mm_xor_ps(_mm_add_ps(_mm_mul_ps(a, b), c), _mm_set1_ps(-0.0f));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__AVX__)
|
||||||
|
static inline
|
||||||
|
__m256
|
||||||
|
glmm256_fmadd(__m256 a, __m256 b, __m256 c) {
|
||||||
|
#ifdef __FMA__
|
||||||
|
return _mm256_fmadd_ps(a, b, c);
|
||||||
|
#else
|
||||||
|
return _mm256_add_ps(c, _mm256_mul_ps(a, b));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m256
|
||||||
|
glmm256_fnmadd(__m256 a, __m256 b, __m256 c) {
|
||||||
|
#ifdef __FMA__
|
||||||
|
return _mm256_fnmadd_ps(a, b, c);
|
||||||
|
#else
|
||||||
|
return _mm256_sub_ps(c, _mm256_mul_ps(a, b));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m256
|
||||||
|
glmm256_fmsub(__m256 a, __m256 b, __m256 c) {
|
||||||
|
#ifdef __FMA__
|
||||||
|
return _mm256_fmsub_ps(a, b, c);
|
||||||
|
#else
|
||||||
|
return _mm256_sub_ps(_mm256_mul_ps(a, b), c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
__m256
|
||||||
|
glmm256_fnmsub(__m256 a, __m256 b, __m256 c) {
|
||||||
|
#ifdef __FMA__
|
||||||
|
return _mm256_fmsub_ps(a, b, c);
|
||||||
|
#else
|
||||||
|
return _mm256_xor_ps(_mm256_sub_ps(_mm256_mul_ps(a, b), c),
|
||||||
|
_mm256_set1_ps(-0.0f));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* cglm_simd_x86_h */
|
#endif /* cglm_simd_x86_h */
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
CGLM_INLINE mat3s glms_quat_mat3t(versors q)
|
CGLM_INLINE mat3s glms_quat_mat3t(versors q)
|
||||||
CGLM_INLINE versors glms_quat_lerp(versors from, versors to, float t)
|
CGLM_INLINE versors glms_quat_lerp(versors from, versors to, float t)
|
||||||
CGLM_INLINE versors glms_quat_lerpc(versors from, versors to, float t)
|
CGLM_INLINE versors glms_quat_lerpc(versors from, versors to, float t)
|
||||||
|
CGLM_INLINE versors glms_quat_nlerp(versors from, versors to, float t)
|
||||||
CGLM_INLINE versors glms_quat_slerp(versors from, versors to, float t)
|
CGLM_INLINE versors glms_quat_slerp(versors from, versors to, float t)
|
||||||
CGLM_INLINE mat4s. glms_quat_look(vec3s eye, versors ori)
|
CGLM_INLINE mat4s. glms_quat_look(vec3s eye, versors ori)
|
||||||
CGLM_INLINE versors glms_quat_for(vec3s dir, vec3s fwd, vec3s up)
|
CGLM_INLINE versors glms_quat_for(vec3s dir, vec3s fwd, vec3s up)
|
||||||
@@ -401,6 +402,24 @@ glms_quat_lerpc(versors from, versors to, float t) {
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief interpolates between two quaternions
|
||||||
|
* taking the shortest rotation path using
|
||||||
|
* normalized linear interpolation (NLERP)
|
||||||
|
*
|
||||||
|
* @param[in] from from
|
||||||
|
* @param[in] to to
|
||||||
|
* @param[in] t interpolant (amount)
|
||||||
|
* @param[out] dest result quaternion
|
||||||
|
*/
|
||||||
|
CGLM_INLINE
|
||||||
|
versors
|
||||||
|
glms_quat_nlerp(versors from, versors to, float t) {
|
||||||
|
versors dest;
|
||||||
|
glm_quat_nlerp(from.raw, to.raw, t, dest.raw);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief interpolates between two quaternions
|
* @brief interpolates between two quaternions
|
||||||
* using spherical linear interpolation (SLERP)
|
* using spherical linear interpolation (SLERP)
|
||||||
|
|||||||
@@ -32,6 +32,16 @@
|
|||||||
# define CGLM_ALIGN_MAT CGLM_ALIGN(16)
|
# define CGLM_ALIGN_MAT CGLM_ALIGN(16)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define CGLM_ASSUME_ALIGNED(expr, alignment) \
|
||||||
|
__builtin_assume_aligned((expr), (alignment))
|
||||||
|
#else
|
||||||
|
# define CGLM_ASSUME_ALIGNED(expr, alignment) (expr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CGLM_CASTPTR_ASSUME_ALIGNED(expr, type) \
|
||||||
|
((type*)CGLM_ASSUME_ALIGNED((expr), __alignof__(type)))
|
||||||
|
|
||||||
typedef float vec2[2];
|
typedef float vec2[2];
|
||||||
typedef float vec3[3];
|
typedef float vec3[3];
|
||||||
typedef int ivec3[3];
|
typedef int ivec3[3];
|
||||||
|
|||||||
@@ -237,9 +237,9 @@ glm_vec3_abs(vec3 v, vec3 dest) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_vec3_fract(vec3 v, vec3 dest) {
|
glm_vec3_fract(vec3 v, vec3 dest) {
|
||||||
dest[0] = fminf(v[0] - floorf(v[0]), 0x1.fffffep-1f);
|
dest[0] = fminf(v[0] - floorf(v[0]), 0.999999940395355224609375f);
|
||||||
dest[1] = fminf(v[1] - floorf(v[1]), 0x1.fffffep-1f);
|
dest[1] = fminf(v[1] - floorf(v[1]), 0.999999940395355224609375f);
|
||||||
dest[2] = fminf(v[2] - floorf(v[2]), 0x1.fffffep-1f);
|
dest[2] = fminf(v[2] - floorf(v[2]), 0.999999940395355224609375f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -224,10 +224,10 @@ glm_vec4_sign(vec4 v, vec4 dest) {
|
|||||||
|
|
||||||
x0 = glmm_load(v);
|
x0 = glmm_load(v);
|
||||||
x1 = _mm_set_ps(0.0f, 0.0f, 1.0f, -1.0f);
|
x1 = _mm_set_ps(0.0f, 0.0f, 1.0f, -1.0f);
|
||||||
x2 = glmm_shuff1x(x1, 2);
|
x2 = glmm_splat(x1, 2);
|
||||||
|
|
||||||
x3 = _mm_and_ps(_mm_cmpgt_ps(x0, x2), glmm_shuff1x(x1, 1));
|
x3 = _mm_and_ps(_mm_cmpgt_ps(x0, x2), glmm_splat(x1, 1));
|
||||||
x4 = _mm_and_ps(_mm_cmplt_ps(x0, x2), glmm_shuff1x(x1, 0));
|
x4 = _mm_and_ps(_mm_cmplt_ps(x0, x2), glmm_splat(x1, 0));
|
||||||
|
|
||||||
glmm_store(dest, _mm_or_ps(x3, x4));
|
glmm_store(dest, _mm_or_ps(x3, x4));
|
||||||
#else
|
#else
|
||||||
@@ -268,10 +268,10 @@ glm_vec4_abs(vec4 v, vec4 dest) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_vec4_fract(vec4 v, vec4 dest) {
|
glm_vec4_fract(vec4 v, vec4 dest) {
|
||||||
dest[0] = fminf(v[0] - floorf(v[0]), 0x1.fffffep-1f);
|
dest[0] = fminf(v[0] - floorf(v[0]), 0.999999940395355224609375f);
|
||||||
dest[1] = fminf(v[1] - floorf(v[1]), 0x1.fffffep-1f);
|
dest[1] = fminf(v[1] - floorf(v[1]), 0.999999940395355224609375f);
|
||||||
dest[2] = fminf(v[2] - floorf(v[2]), 0x1.fffffep-1f);
|
dest[2] = fminf(v[2] - floorf(v[2]), 0.999999940395355224609375f);
|
||||||
dest[3] = fminf(v[3] - floorf(v[3]), 0x1.fffffep-1f);
|
dest[3] = fminf(v[3] - floorf(v[3]), 0.999999940395355224609375f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -473,8 +473,8 @@ glm_vec4_scale_as(vec4 v, float s, vec4 dest) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_vec4_div(vec4 a, vec4 b, vec4 dest) {
|
glm_vec4_div(vec4 a, vec4 b, vec4 dest) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined(CGLM_SIMD)
|
||||||
glmm_store(dest, _mm_div_ps(glmm_load(a), glmm_load(b)));
|
glmm_store(dest, glmm_div(glmm_load(a), glmm_load(b)));
|
||||||
#else
|
#else
|
||||||
dest[0] = a[0] / b[0];
|
dest[0] = a[0] / b[0];
|
||||||
dest[1] = a[1] / b[1];
|
dest[1] = a[1] / b[1];
|
||||||
@@ -568,14 +568,8 @@ glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_vec4_muladd(vec4 a, vec4 b, vec4 dest) {
|
glm_vec4_muladd(vec4 a, vec4 b, vec4 dest) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined(CGLM_SIMD)
|
||||||
glmm_store(dest, _mm_add_ps(glmm_load(dest),
|
glmm_store(dest, glmm_fmadd(glmm_load(a), glmm_load(b), glmm_load(dest)));
|
||||||
_mm_mul_ps(glmm_load(a),
|
|
||||||
glmm_load(b))));
|
|
||||||
#elif defined(CGLM_NEON_FP)
|
|
||||||
vst1q_f32(dest, vaddq_f32(vld1q_f32(dest),
|
|
||||||
vmulq_f32(vld1q_f32(a),
|
|
||||||
vld1q_f32(b))));
|
|
||||||
#else
|
#else
|
||||||
dest[0] += a[0] * b[0];
|
dest[0] += a[0] * b[0];
|
||||||
dest[1] += a[1] * b[1];
|
dest[1] += a[1] * b[1];
|
||||||
@@ -596,14 +590,8 @@ glm_vec4_muladd(vec4 a, vec4 b, vec4 dest) {
|
|||||||
CGLM_INLINE
|
CGLM_INLINE
|
||||||
void
|
void
|
||||||
glm_vec4_muladds(vec4 a, float s, vec4 dest) {
|
glm_vec4_muladds(vec4 a, float s, vec4 dest) {
|
||||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
#if defined(CGLM_SIMD)
|
||||||
glmm_store(dest, _mm_add_ps(glmm_load(dest),
|
glmm_store(dest, glmm_fmadd(glmm_load(a), glmm_set1(s), glmm_load(dest)));
|
||||||
_mm_mul_ps(glmm_load(a),
|
|
||||||
_mm_set1_ps(s))));
|
|
||||||
#elif defined(CGLM_NEON_FP)
|
|
||||||
vst1q_f32(dest, vaddq_f32(vld1q_f32(dest),
|
|
||||||
vmulq_f32(vld1q_f32(a),
|
|
||||||
vdupq_n_f32(s))));
|
|
||||||
#else
|
#else
|
||||||
dest[0] += a[0] * s;
|
dest[0] += a[0] * s;
|
||||||
dest[1] += a[1] * s;
|
dest[1] += a[1] * s;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#define cglm_version_h
|
#define cglm_version_h
|
||||||
|
|
||||||
#define CGLM_VERSION_MAJOR 0
|
#define CGLM_VERSION_MAJOR 0
|
||||||
#define CGLM_VERSION_MINOR 7
|
#define CGLM_VERSION_MINOR 8
|
||||||
#define CGLM_VERSION_PATCH 9
|
#define CGLM_VERSION_PATCH 3
|
||||||
|
|
||||||
#endif /* cglm_version_h */
|
#endif /* cglm_version_h */
|
||||||
|
|||||||
14
include/module.modulemap
Normal file
14
include/module.modulemap
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
module cglm {
|
||||||
|
header "cglm/cglm.h"
|
||||||
|
header "cglm/struct.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
}
|
||||||
|
|
||||||
|
module cglmc {
|
||||||
|
header "cglm/cglm.h"
|
||||||
|
header "cglm/struct.h"
|
||||||
|
header "cglm/call.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
}
|
||||||
29
meson.build
29
meson.build
@@ -1,5 +1,5 @@
|
|||||||
project('cglm', 'c',
|
project('cglm', 'c',
|
||||||
version : '0.7.9',
|
version : '0.8.3',
|
||||||
license : 'mit',
|
license : 'mit',
|
||||||
default_options : [
|
default_options : [
|
||||||
'c_std=c11',
|
'c_std=c11',
|
||||||
@@ -11,6 +11,7 @@ project('cglm', 'c',
|
|||||||
|
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
|
|
||||||
|
cglm_install = get_option('install')
|
||||||
cglm_deps = cc.find_library('m', required : false)
|
cglm_deps = cc.find_library('m', required : false)
|
||||||
|
|
||||||
cglm_args = []
|
cglm_args = []
|
||||||
@@ -50,11 +51,9 @@ cglm_src = files(
|
|||||||
'src/vec4.c'
|
'src/vec4.c'
|
||||||
)
|
)
|
||||||
|
|
||||||
install_subdir('include/cglm', install_dir : get_option('includedir'))
|
|
||||||
|
|
||||||
cglm_lib = library('cglm',
|
cglm_lib = library('cglm',
|
||||||
cglm_src,
|
cglm_src,
|
||||||
install : true,
|
install : cglm_install,
|
||||||
dependencies : cglm_deps,
|
dependencies : cglm_deps,
|
||||||
c_args : [ build_args, cglm_args ]
|
c_args : [ build_args, cglm_args ]
|
||||||
)
|
)
|
||||||
@@ -71,17 +70,19 @@ if meson.version().version_compare('>= 0.54.0')
|
|||||||
meson.override_dependency('cglm', cglm_dep)
|
meson.override_dependency('cglm', cglm_dep)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if cglm_install
|
||||||
|
install_subdir('include/cglm', install_dir : get_option('includedir'))
|
||||||
|
|
||||||
pkg = import('pkgconfig')
|
pkg = import('pkgconfig')
|
||||||
|
pkg.generate(
|
||||||
pkg.generate(
|
name : 'cglm',
|
||||||
name : 'cglm',
|
libraries : cglm_lib,
|
||||||
libraries : cglm_lib,
|
extra_cflags : cglm_args,
|
||||||
extra_cflags : cglm_args,
|
version : meson.project_version(),
|
||||||
version : meson.project_version(),
|
url : 'https://github.com/recp/cglm',
|
||||||
url : 'https://github.com/recp/cglm',
|
description : 'OpenGL Mathematics (glm) for C'
|
||||||
description : 'OpenGL Mathematics (glm) for C'
|
)
|
||||||
)
|
endif
|
||||||
|
|
||||||
if get_option('build_tests') == true
|
if get_option('build_tests') == true
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
option('build_tests', type : 'boolean', value : false, description : 'Build tests')
|
option('build_tests', type : 'boolean', value : false, description : 'Build tests')
|
||||||
|
option('install', type : 'boolean', value : true, description : 'Include the library, headers, and pkg-config file in the install target')
|
||||||
|
|||||||
@@ -170,6 +170,12 @@ glmc_quat_lerpc(versor from, versor to, float t, versor dest) {
|
|||||||
glm_quat_lerpc(from, to, t, dest);
|
glm_quat_lerpc(from, to, t, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGLM_EXPORT
|
||||||
|
void
|
||||||
|
glmc_quat_nlerp(versor from, versor to, float t, versor dest) {
|
||||||
|
glm_quat_nlerp(from, to, t, dest);
|
||||||
|
}
|
||||||
|
|
||||||
CGLM_EXPORT
|
CGLM_EXPORT
|
||||||
void
|
void
|
||||||
glmc_quat_slerp(versor from, versor to, float t, versor dest) {
|
glmc_quat_slerp(versor from, versor to, float t, versor dest) {
|
||||||
|
|||||||
1
src/swift/empty.c
Normal file
1
src/swift/empty.c
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// This empty file is needed to trick swiftpm to build the header-only version of cglm as swiftpm itself does not support C targets that have no source code files
|
||||||
@@ -7,6 +7,25 @@
|
|||||||
|
|
||||||
#include "test_common.h"
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#ifndef glm_affine_mat_test_guard
|
||||||
|
#define glm_affine_mat_test_guard
|
||||||
|
CGLM_INLINE
|
||||||
|
void
|
||||||
|
glm_inv_tr_raw(mat4 mat) {
|
||||||
|
CGLM_ALIGN_MAT mat3 r;
|
||||||
|
CGLM_ALIGN(8) vec3 t;
|
||||||
|
|
||||||
|
/* rotate */
|
||||||
|
glm_mat4_pick3t(mat, r);
|
||||||
|
glm_mat4_ins3(r, mat);
|
||||||
|
|
||||||
|
/* translate */
|
||||||
|
glm_mat3_mulv(r, mat[3], t);
|
||||||
|
glm_vec3_negate(t);
|
||||||
|
glm_vec3_copy(t, mat[3]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_IMPL(GLM_PREFIX, mul) {
|
TEST_IMPL(GLM_PREFIX, mul) {
|
||||||
mat4 m1 = GLM_MAT4_IDENTITY_INIT;
|
mat4 m1 = GLM_MAT4_IDENTITY_INIT;
|
||||||
mat4 m2 = GLM_MAT4_IDENTITY_INIT;
|
mat4 m2 = GLM_MAT4_IDENTITY_INIT;
|
||||||
@@ -81,6 +100,12 @@ TEST_IMPL(GLM_PREFIX, inv_tr) {
|
|||||||
GLM(mat4_inv)(m1, m2);
|
GLM(mat4_inv)(m1, m2);
|
||||||
GLM(inv_tr)(m2);
|
GLM(inv_tr)(m2);
|
||||||
ASSERTIFY(test_assert_mat4_eq(m1, m2))
|
ASSERTIFY(test_assert_mat4_eq(m1, m2))
|
||||||
|
|
||||||
|
/* test with raw */
|
||||||
|
glm_mat4_copy(m1, m2);
|
||||||
|
glm_inv_tr_raw(m2);
|
||||||
|
GLM(inv_tr)(m1);
|
||||||
|
ASSERTIFY(test_assert_mat4_eq(m1, m2))
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUCCESS
|
TEST_SUCCESS
|
||||||
|
|||||||
@@ -708,6 +708,38 @@ TEST_IMPL(GLM_PREFIX, quat_lerpc) {
|
|||||||
TEST_SUCCESS
|
TEST_SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_IMPL(GLM_PREFIX, quat_nlerp) {
|
||||||
|
versor q1, q2, q3, q4;
|
||||||
|
vec3 v1 = {10.0f, 0.0f, 0.0f}, v2;
|
||||||
|
|
||||||
|
glm_quatv(q1, glm_rad(30.0f), v1);
|
||||||
|
glm_quatv(q2, glm_rad(90.0f), v1);
|
||||||
|
|
||||||
|
GLM(quat_nlerp)(q1, q2, 1.0f, q3);
|
||||||
|
glm_quat_normalize(q2);
|
||||||
|
ASSERTIFY(test_assert_quat_eq(q2, q3));
|
||||||
|
|
||||||
|
glm_quatv(q1, glm_rad(30.001f), v1);
|
||||||
|
glm_quatv(q2, glm_rad(30.002f), v1);
|
||||||
|
GLM(quat_nlerp)(q1, q2, 0.7f, q3);
|
||||||
|
glm_quat_lerp(q1, q2, 0.7f, q4);
|
||||||
|
ASSERTIFY(test_assert_quat_eq(q3, q4));
|
||||||
|
|
||||||
|
glm_quatv(q1, glm_rad(30.0f), v1);
|
||||||
|
glm_quatv(q2, glm_rad(90.0f), v1);
|
||||||
|
GLM(quat_nlerp)(q1, q2, 0.5f, q3);
|
||||||
|
|
||||||
|
glm_quat_axis(q3, v2);
|
||||||
|
glm_vec3_normalize(v1);
|
||||||
|
glm_vec3_normalize(v2);
|
||||||
|
|
||||||
|
ASSERT(glm_quat_angle(q3) > glm_rad(30.0f));
|
||||||
|
ASSERT(glm_quat_angle(q3) < glm_rad(90.0f));
|
||||||
|
ASSERTIFY(test_assert_vec3_eq(v1, v2))
|
||||||
|
|
||||||
|
TEST_SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
TEST_IMPL(GLM_PREFIX, quat_slerp) {
|
TEST_IMPL(GLM_PREFIX, quat_slerp) {
|
||||||
versor q1, q2, q3, q4;
|
versor q1, q2, q3, q4;
|
||||||
vec3 v1 = {10.0f, 0.0f, 0.0f}, v2;
|
vec3 v1 = {10.0f, 0.0f, 0.0f}, v2;
|
||||||
|
|||||||
@@ -284,6 +284,7 @@ TEST_DECLARE(glm_quat_mat3)
|
|||||||
TEST_DECLARE(glm_quat_mat3t)
|
TEST_DECLARE(glm_quat_mat3t)
|
||||||
TEST_DECLARE(glm_quat_lerp)
|
TEST_DECLARE(glm_quat_lerp)
|
||||||
TEST_DECLARE(glm_quat_lerpc)
|
TEST_DECLARE(glm_quat_lerpc)
|
||||||
|
TEST_DECLARE(glm_quat_nlerp)
|
||||||
TEST_DECLARE(glm_quat_slerp)
|
TEST_DECLARE(glm_quat_slerp)
|
||||||
TEST_DECLARE(glm_quat_look)
|
TEST_DECLARE(glm_quat_look)
|
||||||
TEST_DECLARE(glm_quat_for)
|
TEST_DECLARE(glm_quat_for)
|
||||||
@@ -320,6 +321,7 @@ TEST_DECLARE(glmc_quat_mat3)
|
|||||||
TEST_DECLARE(glmc_quat_mat3t)
|
TEST_DECLARE(glmc_quat_mat3t)
|
||||||
TEST_DECLARE(glmc_quat_lerp)
|
TEST_DECLARE(glmc_quat_lerp)
|
||||||
TEST_DECLARE(glmc_quat_lerpc)
|
TEST_DECLARE(glmc_quat_lerpc)
|
||||||
|
TEST_DECLARE(glmc_quat_nlerp)
|
||||||
TEST_DECLARE(glmc_quat_slerp)
|
TEST_DECLARE(glmc_quat_slerp)
|
||||||
TEST_DECLARE(glmc_quat_look)
|
TEST_DECLARE(glmc_quat_look)
|
||||||
TEST_DECLARE(glmc_quat_for)
|
TEST_DECLARE(glmc_quat_for)
|
||||||
@@ -1006,6 +1008,7 @@ TEST_LIST {
|
|||||||
TEST_ENTRY(glm_quat_mat3t)
|
TEST_ENTRY(glm_quat_mat3t)
|
||||||
TEST_ENTRY(glm_quat_lerp)
|
TEST_ENTRY(glm_quat_lerp)
|
||||||
TEST_ENTRY(glm_quat_lerpc)
|
TEST_ENTRY(glm_quat_lerpc)
|
||||||
|
TEST_ENTRY(glm_quat_nlerp)
|
||||||
TEST_ENTRY(glm_quat_slerp)
|
TEST_ENTRY(glm_quat_slerp)
|
||||||
TEST_ENTRY(glm_quat_look)
|
TEST_ENTRY(glm_quat_look)
|
||||||
TEST_ENTRY(glm_quat_for)
|
TEST_ENTRY(glm_quat_for)
|
||||||
@@ -1042,6 +1045,7 @@ TEST_LIST {
|
|||||||
TEST_ENTRY(glmc_quat_mat3t)
|
TEST_ENTRY(glmc_quat_mat3t)
|
||||||
TEST_ENTRY(glmc_quat_lerp)
|
TEST_ENTRY(glmc_quat_lerp)
|
||||||
TEST_ENTRY(glmc_quat_lerpc)
|
TEST_ENTRY(glmc_quat_lerpc)
|
||||||
|
TEST_ENTRY(glmc_quat_nlerp)
|
||||||
TEST_ENTRY(glmc_quat_slerp)
|
TEST_ENTRY(glmc_quat_slerp)
|
||||||
TEST_ENTRY(glmc_quat_look)
|
TEST_ENTRY(glmc_quat_look)
|
||||||
TEST_ENTRY(glmc_quat_for)
|
TEST_ENTRY(glmc_quat_for)
|
||||||
|
|||||||
@@ -90,7 +90,10 @@
|
|||||||
<ClInclude Include="..\include\cglm\simd\avx\affine.h" />
|
<ClInclude Include="..\include\cglm\simd\avx\affine.h" />
|
||||||
<ClInclude Include="..\include\cglm\simd\avx\mat4.h" />
|
<ClInclude Include="..\include\cglm\simd\avx\mat4.h" />
|
||||||
<ClInclude Include="..\include\cglm\simd\intrin.h" />
|
<ClInclude Include="..\include\cglm\simd\intrin.h" />
|
||||||
|
<ClInclude Include="..\include\cglm\simd\neon\affine.h" />
|
||||||
|
<ClInclude Include="..\include\cglm\simd\neon\mat2.h" />
|
||||||
<ClInclude Include="..\include\cglm\simd\neon\mat4.h" />
|
<ClInclude Include="..\include\cglm\simd\neon\mat4.h" />
|
||||||
|
<ClInclude Include="..\include\cglm\simd\neon\quat.h" />
|
||||||
<ClInclude Include="..\include\cglm\simd\sse2\affine.h" />
|
<ClInclude Include="..\include\cglm\simd\sse2\affine.h" />
|
||||||
<ClInclude Include="..\include\cglm\simd\sse2\mat2.h" />
|
<ClInclude Include="..\include\cglm\simd\sse2\mat2.h" />
|
||||||
<ClInclude Include="..\include\cglm\simd\sse2\mat3.h" />
|
<ClInclude Include="..\include\cglm\simd\sse2\mat3.h" />
|
||||||
|
|||||||
@@ -370,5 +370,14 @@
|
|||||||
<ClInclude Include="..\include\cglm\struct\affine2d.h">
|
<ClInclude Include="..\include\cglm\struct\affine2d.h">
|
||||||
<Filter>include\cglm\struct</Filter>
|
<Filter>include\cglm\struct</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\cglm\simd\neon\affine.h">
|
||||||
|
<Filter>include\cglm\simd\neon</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\cglm\simd\neon\mat2.h">
|
||||||
|
<Filter>include\cglm\simd\neon</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\cglm\simd\neon\quat.h">
|
||||||
|
<Filter>include\cglm\simd\neon</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user