First commit

This commit is contained in:
Adam Sawicki 2017-06-16 17:21:31 +02:00
commit e6e498f63a
157 changed files with 24645 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build/
doc/html/*

19
LICENSE.txt Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

7
README.md Normal file
View File

@ -0,0 +1,7 @@
# Vulkan Memory Allocator
This is a README file for Vulkan Memory Allocator library and accompanying sample application.
**License:** MIT. See `LICENSE.txt`.
**Documentation:** Doxygen-style comments in `src/vk_mem_alloc.h`.

BIN
bin/Shader.frag.spv Normal file

Binary file not shown.

BIN
bin/Shader.vert.spv Normal file

Binary file not shown.

Binary file not shown.

BIN
media/Thumbnail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

43
premake/premake5.lua Normal file
View File

@ -0,0 +1,43 @@
-- _ACTION is a premake global variable and for our usage will be vs2012, vs2013, etc.
-- Strip "vs" from this string to make a suffix for solution and project files.
_SUFFIX = string.gsub(_ACTION, "vs", "")
workspace "VulkanSample"
configurations { "Debug", "Release" }
platforms { "x64" }
location "../build"
filename ("VulkanSample_" .. _SUFFIX)
startproject "VulkanSample"
filter "platforms:x64"
system "Windows"
architecture "x64"
includedirs { "../third_party/mathfu-1.1.0/include" }
libdirs { "$(VULKAN_SDK)\\Bin" }
project "VulkanSample"
kind "ConsoleApp"
language "C++"
location "../build"
filename ("VulkanSample_" .. _SUFFIX)
targetdir "../bin"
objdir "../build/Desktop_%{_SUFFIX}/%{cfg.platform}/%{cfg.buildcfg}"
floatingpoint "Fast"
files { "../src/*.h", "../src/*.cpp" }
links { "vulkan-1" }
flags { "NoPCH", "FatalWarnings" }
characterset "Unicode"
defines { "WIN32", "_CONSOLE", "PROFILE", "_WINDOWS", "_WIN32_WINNT=0x0601" }
filter "configurations:Debug"
defines { "_DEBUG", "DEBUG" }
flags { }
targetsuffix ("_Debug_" .. _SUFFIX)
buildoptions { "/MDd" }
filter "configurations:Release"
defines { "NDEBUG" }
optimize "On"
flags { "LinkTimeOptimization" }
targetsuffix ("_Release_" .. _SUFFIX)
buildoptions { "/MD" }

2492
src/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
%VULKAN_SDK%/Bin32/glslangValidator.exe -V -o ../../bin/Shader.vert.spv Shader.vert
%VULKAN_SDK%/Bin32/glslangValidator.exe -V -o ../../bin/Shader.frag.spv Shader.frag
pause

37
src/Shaders/Shader.frag Normal file
View File

@ -0,0 +1,37 @@
//
// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 inColor;
layout(location = 1) in vec2 inTexCoord;
layout(location = 0) out vec4 outColor;
layout(binding = 1) uniform sampler2D texSampler;
void main()
{
outColor = texture(texSampler, inTexCoord);
outColor.rgb *= inColor;
}

42
src/Shaders/Shader.vert Normal file
View File

@ -0,0 +1,42 @@
//
// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(push_constant) uniform UniformBufferObject
{
mat4 ModelViewProj;
} ubo;
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;
layout(location = 0) out vec3 outColor;
layout(location = 1) out vec2 outTexCoord;
void main() {
gl_Position = ubo.ModelViewProj * vec4(inPosition, 1.0);
outColor = inColor;
outTexCoord = inTexCoord;
}

1724
src/VulkanSample.cpp Normal file

File diff suppressed because it is too large Load Diff

3876
src/vk_mem_alloc.h Normal file

File diff suppressed because it is too large Load Diff

37
third_party/mathfu-1.1.0/.gitignore vendored Normal file
View File

@ -0,0 +1,37 @@
**/bin/**
**/libs/**
**/obj/**
*.pyc
apks/**
docs/html/
docs/linklint_results/
CMakeCache.txt
CMakeFiles
CMakeScripts/
Makefile
MathFu.build/
MathFu.xcodeproj/
benchmarks/CMakeFiles
benchmarks/Debug/
benchmarks/Makefile
benchmarks/MathFu.build/
benchmarks/Release/
benchmarks/cmake_install.cmake
benchmarks/matrix_*benchmarks
benchmarks/vector_*benchmarks
unit_tests/CMakeFiles/
unit_tests/Debug/
unit_tests/Makefile
unit_tests/MathFu.build/
unit_tests/Release/
unit_tests/cmake_install.cmake
unit_tests/matrix_*tests
unit_tests/quaternion_*tests
unit_tests/vector_*tests
build.xml
cmake_install.cmake
googletest/
local.properties
proguard-project.txt
project.properties
.DS_Store

9
third_party/mathfu-1.1.0/.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[submodule "dependencies/fplutil"]
path = dependencies/fplutil
url = http://github.com/google/fplutil.git
[submodule "dependencies/vectorial"]
path = dependencies/vectorial
url = http://github.com/scoopr/vectorial.git
[submodule "dependencies/googletest"]
path = dependencies/googletest
url = http://github.com/google/googletest.git

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Empty Manifest so the NDK build process can find the project
directory. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- Empty application since this project just builds the mathfu
libraries -->
<application android:label="mathfu" android:enabled="false"
android:hasCode="false">
<activity android:name="android.app.NativeActivity">
<meta-data android:name="android.app.lib_name"
android:value="mathfu" />
</activity>
</application>
</manifest>

137
third_party/mathfu-1.1.0/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,137 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 2.8.12)
set(PROJECT_NAME MathFu)
project(MathFu)
# Call fplutil to get locations of dependencies and set common build settings.
include("cmake/find_fplutil.cmake")
include("${fplutil_dir}/buildutil/cmake_common.txt")
set_common_build_variables()
# Options that control the build configuration.
# To configure MathFu flags per build target, see the
# mathfu_configure_flags() function.
option(mathfu_enable_simd "Use SIMD implementations when available." ON)
option(mathfu_build_benchmarks "Build MathFu benchmarks." ON)
option(mathfu_build_tests "Build MathFu unit tests." ON)
# Save the mathfu directory, store this in the cache so that it's globally
# accessible from mathfu_configure_flags().
set(mathfu_dir ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "mathfu directory")
# Set build options for ${target} that are required to build with MathFu.
# This takes the optional arguments "enable_simd force_padding".
#
# If enable_simd is specified it configures whether the project should be
# built with SIMD optimized functions. If force_padding is specified and
# SIMD is enabled, some data structures are padded to work more efficiently
# with SIMD instructions.
#
# If enable_simd is not specified, the mathfu_enable_simd option is used.
# If force_padding isn't specified padding is enabled based upon the
# best general configuration for the target architecture.
function(mathfu_configure_flags target)
if(fpl_ios)
set(enable_simd NO)
else()
set(enable_simd ${mathfu_enable_simd})
endif()
# Add required includes to the target.
target_include_directories(${target}
PRIVATE ${mathfu_dir}/include ${dependencies_vectorial_dir}/include)
# Parse optional arguments.
set(additional_args ${ARGN})
list(LENGTH additional_args num_additional_args)
if(${num_additional_args} GREATER 0)
list(GET additional_args 0 enable_simd)
endif()
if(${num_additional_args} GREATER 1)
list(GET additional_args 1 force_padding)
endif()
# If the SIMD build option is enabled.
if(enable_simd)
# Enable SSE4.1 when building with GCC / Clang.
# NOTE: It's also possible to build the library using using SSE2 with GCC /
# Clang, change -msse4.1 to -msse2.
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR
CMAKE_COMPILER_IS_CLANGXX)
target_compile_options(${target} PRIVATE -msse4.1)
endif()
# Enable SSE2 by default when building with MSVC for 32-bit targets.
# Note that SSE2 is enabled by default for 64-bit targets, and the
# compile option will generate an "unknown option" warning.
if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 4)
target_compile_options(${target} PRIVATE /arch:SSE2)
endif()
# Conditionally enable padding.
if(DEFINED force_padding)
if(force_padding)
target_compile_definitions(${target} PRIVATE
-DMATHFU_COMPILE_FORCE_PADDING=1)
else()
target_compile_definitions(${target} PRIVATE
-DMATHFU_COMPILE_FORCE_PADDING=0)
endif()
endif()
else()
target_compile_definitions(${target} PRIVATE
-DMATHFU_COMPILE_WITHOUT_SIMD_SUPPORT)
endif()
endfunction()
# Modify CMAKE_C_FLAGS and CMAKE_CXX_FLAGS to enable a maximum reasonable
# warning level.
function(mathfu_enable_warnings target)
get_target_property(target_compile_flags ${target} COMPILE_FLAGS)
if(MSVC)
# C4127: conditional expression is constant
# C4577: 'noexcept' used with no exception handling mode specified.
target_compile_options(${target} PRIVATE /W4 /WX /wd4127 /wd4577)
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR
CMAKE_COMPILER_IS_CLANGXX)
# Set the maximum warning level for gcc.
target_compile_options(${target} PRIVATE -Wall -Wextra -Werror
-Wno-long-long -Wno-variadic-macros)
endif()
endfunction()
# Macro defined here so that it can be used by all projects included
macro(mathfu_set_ios_attributes project)
if(fpl_ios)
set_target_properties(${project} PROPERTIES
XCODE_ATTRIBUTE_SDKROOT "iphoneos")
set_target_properties(${project} PROPERTIES
XCODE_ATTRIBUTE_ARCHS "$(ARCHS_STANDARD)")
set_target_properties(${project} PROPERTIES
XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO")
set_target_properties(${project} PROPERTIES
XCODE_ATTRIBUTE_VALID_ARCHS "$(ARCHS_STANDARD)")
set_target_properties(${project} PROPERTIES
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "8.0")
endif()
endmacro(mathfu_set_ios_attributes)
file(GLOB_RECURSE MATHFU_HEADERS ${CMAKE_CURRENT_LIST_DIR}/include/mathfu *.h)
if(mathfu_build_benchmarks)
add_subdirectory(benchmarks)
endif()
if(mathfu_build_tests)
add_subdirectory(unit_tests)
endif()

28
third_party/mathfu-1.1.0/CONTRIBUTING vendored Normal file
View File

@ -0,0 +1,28 @@
Contributing {#contributing}
============
Want to contribute? Great! First, read this page (including the small print at
the end).
# Before you contribute
Before we can use your code, you must sign the
[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
(CLA), which you can do online. The CLA is necessary mainly because you own the
copyright to your changes, even after your contribution becomes part of our
codebase, so we need your permission to use and distribute your code. We also
need to be sure of various other things—for instance that you'll tell us if you
know that your code infringes on other people's patents. You don't have to sign
the CLA until after you've submitted your code for review and a member has
approved it, but you must do it before we can put your code into our codebase.
Before you start working on a larger contribution, you should get in touch with
us first through the issue tracker with your idea so that we can help out and
possibly guide you. Coordinating up front makes it much easier to avoid
frustration later on.
# Code reviews
All submissions, including submissions by project members, require review. We
use Github pull requests for this purpose.
# The small print
Contributions made by corporations are covered by a different agreement than
the one above, the Software Grant and Corporate Contributor License Agreement.

202
third_party/mathfu-1.1.0/LICENSE vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,49 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FIND_FPLUTIL_OK_IF_NOT_FOUND:=1
include $(call my-dir)/jni/find_fplutil.mk
ifneq ($(FPLUTIL_DIR),)
# If fplutil is found, grab the project locations from it.
include $(FPLUTIL_DIR)/buildutil/android_common.mk
else
# If fplutil is not found, assume project locations are in 'dependencies'
# or are set externally with the DEPENDENCIES_ROOT value.
#
# If the dependencies directory exists either as a subdirectory or as the
# container of this project directory, assume the dependencies directory is
# the root directory for all libraries required by this project.
$(foreach dep_dir,$(wildcard $(MATHFU_DIR)/dependencies) \
$(wildcard $(MATHFU_DIR)/../../dependencies),\
$(eval DEPENDENCIES_ROOT?=$(dep_dir)))
ifeq ($(DEPENDENCIES_ROOT),)
$(error "Cannot find directory with dependent projects.")
endif
# Location of the vectorial library.
DEPENDENCIES_VECTORIAL_DIR?=$(DEPENDENCIES_ROOT)/vectorial
# Location of the googletest library.
DEPENDENCIES_GTEST_DIR?=$(DEPENDENCIES_ROOT)/fplutil/libfplutil/jni/libs/googletest
# Location of the fplutil library.
DEPENDENCIES_FPLUTIL_DIR?=$(DEPENDENCIES_ROOT)/fplutil
endif
# Whether to disable SIMD.
MATHFU_DISABLE_SIMD?=0
# Whether to force padding of data structures with SIMD enabled.
# -1 = default, 0 = no padding, 1 = padding
MATHFU_FORCE_PADDING?=-1

View File

@ -0,0 +1,54 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 2.8)
# Generate a rule to build a performance test executable
# ${benchmark_executable_name} from ${benchmark_source}. For details of
# additional arguments, see mathfu_configure_flags().
function(benchmark_executable benchmark_executable_name benchmark_source)
add_executable(${benchmark_executable_name} ${benchmark_source})
mathfu_configure_flags(${benchmark_executable_name} ${ARGN})
mathfu_enable_warnings(${benchmark_executable_name})
target_include_directories(${benchmark_executable_name}
PRIVATE ${CMAKE_CURRENT_LIST_DIR})
if(UNIX AND NOT APPLE)
target_link_libraries(${benchmark_executable_name} rt)
endif(UNIX AND NOT APPLE)
endfunction()
# Generates a rule to build performance test executables. This only builds
# ${benchmark_name}_benchmarks if SIMD is disabled (see ${mathfu_enable_simd})
# or ${benchmark_name}_benchmarks and ${benchmark_name}_no_simd_benchmarks if
# SIMD is enabled where the no_simd_benchmarks binary has SIMD disabled.
function(benchmark_executables benchmark_name benchmark_source)
# Default build options.
benchmark_executable(${benchmark_name}_benchmarks ${benchmark_source})
if(mathfu_enable_simd)
# NOTE: A build configuration below will deliberately duplicate the
# default build configuration, since these configs could result in
# different compile time preprocessor code paths.
# SIMD enabled, padding enabled.
benchmark_executable(${benchmark_name}_simd_padding_benchmarks
${benchmark_source} TRUE TRUE)
# SIMD enabled, padding disabled.
benchmark_executable(${benchmark_name}_simd_no_padding_benchmarks
${benchmark_source} TRUE FALSE)
# SIMD disabled, padding disabled.
benchmark_executable(${benchmark_name}_no_simd_benchmarks
${benchmark_source} FALSE FALSE)
endif()
endfunction()
benchmark_executables(matrix matrix_benchmark/main.cpp)
benchmark_executables(vector vector_benchmark/main.cpp)

View File

@ -0,0 +1,48 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(CLEAR_VARS)
# Configure the locations of MathFu's dependencies.
MATHFU_DIR:=$(LOCAL_PATH)/../..
MATHFU_DIR_BASENAME:=$(notdir $(abspath $(MATHFU_DIR)))
include $(MATHFU_DIR)/android_config.mk
namespace:=$(if $(NDK_PROJECT_PATH),,_mathfu)
LOCAL_MODULE:=$(LOCAL_BENCHMARK_NAME)${namespace}
LOCAL_MODULE_TAGS:=optional
LOCAL_SRC_FILES:= main.cpp
LOCAL_C_INCLUDES:=$(MATHFU_DIR)/benchmarks
LOCAL_LDLIBS:=-llog -landroid
LOCAL_WHOLE_STATIC_LIBRARIES:=\
libfplutil_main \
libfplutil_print
# MATHFU_LIB (by default libmathfu) is used to select the build configuration
# for the target using mathfu.
LOCAL_STATIC_LIBRARIES:=\
android_native_app_glue \
libgtest \
$(MATHFU_LIB)
LOCAL_CFLAGS:=-Wall -Werror
LOCAL_ARM_MODE:=arm
include $(BUILD_SHARED_LIBRARY)
$(call import-add-path,$(abspath $(MATHFU_DIR)/..))
$(call import-add-path,$(abspath $(DEPENDENCIES_FPLUTIL_DIR)))
$(call import-module,$(MATHFU_DIR_BASENAME)/jni)
$(call import-module,libfplutil/jni)
$(call import-module,android/native_app_glue)
LOCAL_BENCHMARK_NAME:=
MATHFU_DIR:=

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
APP_PLATFORM:=android-10
APP_ABI:=armeabi-v7a
APP_STL:=c++_static

View File

@ -0,0 +1,107 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_BENCHMARKS_BENCHMARKCOMMON_H_
#define MATHFU_BENCHMARKS_BENCHMARKCOMMON_H_
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <sys/time.h>
#include <time.h>
#endif // defined(_WIN32)
// This macro stands in for a double loop over a vector with size elements.
// This double loop is repeated iterations times to create more accurate
// performance test.
#define PERFTEST_2D_VECTOR_LOOP(iterations, size) \
for (unsigned int k = 0; k < iterations; k++) \
for (unsigned int i = 0; i < size; i++) \
for (unsigned int j = 0; j < size; j++)
// High resolution timer.
class Timer {
public:
Timer() {
InitializeTickPeriod();
Reset();
}
// Save the current number of counter ticks.
void Reset() {
start_ = GetTicks();
}
// Get the time elapsed in counter ticks since Reset() was called.
unsigned long long GetElapsedTicks() {
return GetTicks() - start_;
}
// Get the time elapsed in seconds since Reset() was called.
double GetElapsedSeconds() {
return static_cast<double>(GetElapsedTicks()) * tick_period();
}
public:
// Initialize the tick period value.
static void InitializeTickPeriod() {
if (tick_period_ != 0) {
return;
}
#if defined(_WIN32)
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
tick_period_ = 1.0 / static_cast<double>(frequency.QuadPart);
#elif defined(__linux__)
// Use a fixed frequency of 1ns to match timespec.
tick_period_ = 1e-9;
#else
// Use a fixed frequency of 1us to match timeval.
tick_period_ = 1e-6;
#endif // defined(_WIN32)
}
// Get the period of one counter tick.
static double tick_period() {
return tick_period_;
}
// Get the number of counter ticks elapsed.
static unsigned long long GetTicks() {
#if defined(_WIN32)
LARGE_INTEGER ticks;
QueryPerformanceCounter(&ticks);
return ticks.QuadPart;
#elif defined(__linux__)
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return (static_cast<unsigned long long>(time.tv_sec) * 1000000000ULL) +
time.tv_nsec;
#else
struct timeval time;
gettimeofday(&time, NULL);
return (static_cast<unsigned long long>(time.tv_sec) * 1000000ULL) +
time.tv_usec;
#endif
}
private:
unsigned long long start_;
static double tick_period_;
};
double Timer::tick_period_ = 0;
#endif // MATHFU_BENCHMARKS_BENCHMARKCOMMON_H_

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu.matrix_benchmark"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name"
android:value="matrix_benchmark" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/../..
LOCAL_BENCHMARK_NAME:=matrix_benchmark
MATHFU_LIB:=libmathfu
include $(LOCAL_PATH)/../android_common.mk

View File

@ -0,0 +1,15 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(NDK_PROJECT_PATH)/../../application_common.mk
APP_MODULES:=matrix_benchmark

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">matrix_benchmark</string>
</resources>

View File

@ -0,0 +1,79 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mathfu/matrix_4x4.h"
#include "mathfu/utilities.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "benchmark_common.h"
// Number of elements to iterate over
static const size_t kMatrixSize = 1000;
// Number of iterations of each operation.
static const size_t kIterations = 50;
using mathfu::Matrix;
using mathfu::Random;
#define MATRIX_DIMENSIONS 4
typedef float T;
typedef Matrix<T, MATRIX_DIMENSIONS> TestMatrix;
// This test creates a number of matrices and performs some mathematical
// operations on them in order to measure expected performance of matrix
// operations.
int main(int argc, char** argv) {
(void)argc;
(void)argv;
// Create an array of matrices containing random values.
TestMatrix * const matrices = new TestMatrix[kMatrixSize];
TestMatrix mul = TestMatrix::Identity();
for (size_t i = 0; i < kMatrixSize; ++i) {
TestMatrix mat;
for (size_t j = 0; j < MATRIX_DIMENSIONS; ++j) {
mat[static_cast<int>(j)] = Random<T>();
}
matrices[i] = mat;
}
// Start matrix benchmark, running a number of loops for more accurate
// numbers.
printf("Running matrix benchmark (%s)...\n", MATHFU_BUILD_OPTIONS_STRING);
Timer timer;
PERFTEST_2D_VECTOR_LOOP(kIterations, kMatrixSize) mul += matrices[j];
PERFTEST_2D_VECTOR_LOOP(kIterations, kMatrixSize) mul *= matrices[j];
#if MATRIX_DIMENSIONS == 4
PERFTEST_2D_VECTOR_LOOP(kIterations, kMatrixSize) {
mathfu::Vector<T, MATRIX_DIMENSIONS> tmp =
matrices[j] * mathfu::Vector<T, MATRIX_DIMENSIONS>(
matrices[i](0, 0), matrices[i](1, 0),
matrices[i](2, 0), matrices[i](3, 0));
mul -= TestMatrix::OuterProduct(tmp, tmp);
}
#endif // MATRIX_DIMENSIONS == 4
PERFTEST_2D_VECTOR_LOOP(kIterations, kMatrixSize) {
mul += matrices[j] * Random<T>();
}
// End matrix performance code
double elapsed = timer.GetElapsedSeconds();
printf("Took %f seconds\n", elapsed);
delete [] matrices;
return 0;
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu.matrix_no_simd_benchmark"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name"
android:value="matrix_no_simd_benchmark" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/../..
LOCAL_BENCHMARK_NAME:=matrix_no_simd_benchmark
MATHFU_LIB:=libmathfu_no_simd
include $(LOCAL_PATH)/../android_common.mk

View File

@ -0,0 +1,15 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(NDK_PROJECT_PATH)/../../application_common.mk
APP_MODULES:=matrix_no_simd_benchmark

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">matrix_no_simd_benchmark</string>
</resources>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu.matrix_simd_no_padding_benchmark"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name"
android:value="matrix_simd_no_padding_benchmark" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/../..
LOCAL_BENCHMARK_NAME:=matrix_simd_no_padding_benchmark
MATHFU_LIB:=libmathfu_simd_no_padding
include $(LOCAL_PATH)/../android_common.mk

View File

@ -0,0 +1,15 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(NDK_PROJECT_PATH)/../../application_common.mk
APP_MODULES:=matrix_simd_no_padding_benchmark

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">matrix_simd_no_padding_benchmark</string>
</resources>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu.matrix_simd_padding_benchmark"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name"
android:value="matrix_simd_padding_benchmark" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/../..
LOCAL_BENCHMARK_NAME:=matrix_simd_padding_benchmark
MATHFU_LIB:=libmathfu_simd_padding
include $(LOCAL_PATH)/../android_common.mk

View File

@ -0,0 +1,15 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(NDK_PROJECT_PATH)/../../application_common.mk
APP_MODULES:=matrix_simd_padding_benchmark

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">matrix_simd_padding_benchmark</string>
</resources>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu.vector_benchmark"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name"
android:value="vector_benchmark" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/../..
LOCAL_BENCHMARK_NAME:=vector_benchmark
MATHFU_LIB:=libmathfu
include $(LOCAL_PATH)/../android_common.mk

View File

@ -0,0 +1,15 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(NDK_PROJECT_PATH)/../../application_common.mk
APP_MODULES:=vector_benchmark

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">vector_benchmark</string>
</resources>

View File

@ -0,0 +1,76 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mathfu/vector.h"
#include "mathfu/utilities.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "benchmark_common.h"
// Number of elements to iterate over.
static const size_t kVectorSize = 1000;
// Number of iterations of each operation.
static const size_t kIterations = 100;
using mathfu::Random;
using mathfu::Vector;
// This test creates a number of vectors and performs some mathematical
// operations on them in order to measure expected performance of vector
// operations.
int main(int argc, char** argv) {
typedef float T;
(void)argc;
(void)argv;
// Create a array of vectors
Vector<T, 3> *vectors = new Vector<T, 3>[kVectorSize];
T final_sum = 0;
Vector<T, 3> sum(0.0f);
for (size_t i = 0; i < kVectorSize; i++) {
Vector<T, 3> vec(Random<T>(), Random<T>(), Random<T>());
if (vec.LengthSquared() == static_cast<T>(0.0)) {
vec.x = static_cast<T>(1.0);
}
vectors[i] = vec;
}
printf("Running vector benchmark (%s)...\n", MATHFU_BUILD_OPTIONS_STRING);
// Start vector performance code. Run a number of loops for more accurate
// numbers.
Timer timer;
PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) sum += vectors[j];
PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) sum -= vectors[j];
PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) sum *= 0.1f;
PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) {
sum += Vector<T, 3>::CrossProduct(vectors[i], vectors[j]);
}
PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) {
final_sum += Vector<T, 3>::DotProduct(vectors[j], vectors[i]);
}
PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) {
final_sum -= vectors[i].Length();
}
PERFTEST_2D_VECTOR_LOOP(kIterations, kVectorSize) {
final_sum += vectors[i].Normalize();
}
final_sum += sum[0] + sum[1] + sum[2];
// End vector performance code
double elapsed = timer.GetElapsedSeconds();
printf("Took %f seconds\n", elapsed);
delete [] vectors;
return 0;
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu.vector_no_simd_benchmark"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name"
android:value="vector_no_simd_benchmark" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/../..
LOCAL_BENCHMARK_NAME:=vector_no_simd_benchmark
MATHFU_LIB:=libmathfu_no_simd
include $(LOCAL_PATH)/../android_common.mk

View File

@ -0,0 +1,15 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(NDK_PROJECT_PATH)/../../application_common.mk
APP_MODULES:=vector_no_simd_benchmark

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">vector_no_simd_benchmark</string>
</resources>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu.vector_simd_no_padding_benchmark"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name"
android:value="vector_simd_no_padding_benchmark" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/../..
LOCAL_BENCHMARK_NAME:=vector_simd_no_padding_benchmark
MATHFU_LIB:=libmathfu_simd_no_padding
include $(LOCAL_PATH)/../android_common.mk

View File

@ -0,0 +1,15 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(NDK_PROJECT_PATH)/../../application_common.mk
APP_MODULES:=vector_simd_no_padding_benchmark

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">vector_simd_no_padding_benchmark</string>
</resources>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.fpl.mathfu.vector_simd_padding_benchmark"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name"
android:value="vector_simd_padding_benchmark" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,17 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/../..
LOCAL_BENCHMARK_NAME:=vector_simd_padding_benchmark
MATHFU_LIB:=libmathfu_simd_padding
include $(LOCAL_PATH)/../android_common.mk

View File

@ -0,0 +1,15 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include $(NDK_PROJECT_PATH)/../../application_common.mk
APP_MODULES:=vector_simd_padding_benchmark

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">vector_simd_padding_benchmark</string>
</resources>

View File

@ -0,0 +1,41 @@
# Find the fplutil directory and set it in `fplutil_dir`.
#
# We search some standard locations, such as
# (1) the cached variable ${dependencies_fplutil_dir}, which can be specified
# on the command line,
# cmake -Ddependencies_fplutil_dir=your_fplutil_directory
# (2) under ${fpl_root}, which is another cached variable that can be
# specified on the command line,
# cmake -Dfpl_root=your_fpl_root_directory
# (3) the "dependencies" directory that gets created when cloning from GitHub,
# (4) several levels up in the directory tree.
#
# Notes
# -----
# - fplutil is the project where we keep all our shared code, so the code in
# this file (which locates fplutil) can unfortunately not be shared.
# - Since this file is duplicated in all FPL projects (except fplutil itself),
# please copy new versions to all FPL projects whenever you make a change.
set(fplutil_dir_possibilities
"${dependencies_fplutil_dir}"
"${fpl_root}/fplutil"
"${CMAKE_CURRENT_SOURCE_DIR}/dependencies/fplutil"
"${CMAKE_CURRENT_LIST_DIR}/../../fplutil"
"${CMAKE_CURRENT_LIST_DIR}/../../../fplutil"
"${CMAKE_CURRENT_LIST_DIR}/../../../../fplutil"
"${CMAKE_CURRENT_LIST_DIR}/../../../../../fplutil")
foreach(dir ${fplutil_dir_possibilities})
if(EXISTS ${dir})
set(fplutil_dir ${dir})
return()
endif()
endforeach(dir)
# Define this cached variable so that cmake GUIs can expose it to the user.
set(dependencies_fplutil_dir ""
CACHE PATH "Directory containing the fplutil library.")
MESSAGE(ERROR
"Can't find fplutil directory. Try cmake -Ddependencies_fplutil_dir=your_location.")

View File

@ -0,0 +1,37 @@
{
"package": {
"name": "mathfu",
"url": "http://github.com/google/mathfu.git",
"branch": "develop",
"is_library": 1,
"third_party": 0,
"push": 1
},
"dependencies": [
{
"name": "googletest",
"url": "http://github.com/google/googletest.git",
"branch": "master",
"revision": "13206d6f53aaff844f2d3595a01ac83a29e383db",
"is_library": 1,
"third_party": 1,
"push": 0
},
{
"name": "fplutil",
"url": "http://github.com/google/fplutil.git",
"branch": "develop",
"is_library": 1,
"third_party": 0,
"push": 1
},
{
"name": "vectorial",
"url": "http://github.com/scoopr/vectorial.git",
"branch": "master",
"is_library": 1,
"third_party": 1,
"push": 0
}
]
}

View File

@ -0,0 +1,54 @@
#!/usr/bin/python
# Copyright 2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Push this project and its dependencies to another git repo.
Uses fplutil/disttools/push_package.py to push the remote of
this git repository and its dependencies (defined by config.json)
to another git repository.
"""
import os
import sys
sys.path.extend((
os.path.realpath(os.path.join(
os.path.dirname(__file__), os.path.pardir, 'dependencies', 'fplutil')),
os.path.realpath(os.path.join(
os.path.dirname(__file__), os.path.pardir, os.path.pardir,
'fplutil'))))
import disttools.push_package # pylint: disable=g-import-not-at-top
## The directory containing this file.
THIS_DIR = os.path.realpath(os.path.dirname(__file__))
## Default root directory of the project.
PROJECT_DIR = os.path.realpath(os.path.join(THIS_DIR, os.path.pardir))
## Default package configuration file.
CONFIG_JSON = os.path.realpath(os.path.join(THIS_DIR, 'config.json'))
def main():
"""See fplutil/disttools/push_package.py.
Returns:
0 if successful, non-zero otherwise.
"""
return disttools.push_package.main(disttools.push_package.parse_arguments(
project_dir=PROJECT_DIR, config_json=CONFIG_JSON))
if __name__ == '__main__':
sys.exit(main())

View File

@ -0,0 +1,41 @@
#!/usr/bin/python
# Copyright 2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generate html documentation from markdown and doxygen comments."""
import os
import sys
THIS_DIR = os.path.realpath(os.path.dirname(__file__))
PROJECT_DIR = os.path.realpath(os.path.join(THIS_DIR, os.pardir))
sys.path.extend(
[os.path.realpath(os.path.join(PROJECT_DIR, os.pardir, 'fplutil')),
os.path.realpath(os.path.join(PROJECT_DIR, 'dependencies', 'fplutil'))])
import docs # pylint: disable=C6204
def main():
"""Generate html documentation from markdown and doxygen comments.
Returns:
0 if successful, 1 otherwise.
"""
sys.argv.extend(('--linklint-dir', THIS_DIR,
'--source-dir', os.path.join(THIS_DIR, 'src'),
'--project-dir', PROJECT_DIR))
return docs.generate_docs.main()
if __name__ == '__main__':
sys.exit(main())

View File

@ -0,0 +1,37 @@
API Reference {#mathfu_api_reference}
=============
This document describes all classes, functions, macros and files that make
up the [MathFu][] library. This is intended to be used as a reference for
C++ programmers who are familiar with [geometry][], [vectors][], [matrices][],
[quaternions][] and [linear algebra][].
The API reference is broken into the following sections:
* [Build Configuration](@ref mathfu_build_config)
- Describes configuration options for [MathFu][] code generation.
* [Allocators](@ref mathfu_allocator)
- Allocators to simplify the process of memory allocation for [MathFu][]
data structures.
* [Constants](@ref mathfu_constants)
- Constants to use in conjunction with [MathFu][] classes.
* [Vectors](@ref mathfu_vector)
- Class and functions to manipulate [vectors][].
* [Matrices](@ref mathfu_matrix)
- Class and functions to manipulate [matrices][].
* [Quaternions](@ref mathfu_quaternion)
- Class and functions to manipulate [quaternions][].
* [GLSL Mappings](@ref mathfu_glsl)
- Mappings to GLSL data types and functions.
* [Utility Functions](@ref mathfu_utilities)
- Variety of useful functions that can be used with
[Vector](@ref mathfu::Vector) and [Matrix](@ref mathfu::Matrix)
classes.
* [Version Constants](@ref mathfu_version)
- Constants which identify the library version.
[MathFu]: @ref mathfu_overview
[geometry]: http://en.wikipedia.org/wiki/Geometry
[vectors]: http://en.wikipedia.org/wiki/Euclidean_vector
[matrices]: http://en.wikipedia.org/wiki/Matrix_(mathematics)
[quaternions]: http://en.wikipedia.org/wiki/Quaternion
[linear algebra]: http://en.wikipedia.org/wiki/Linear_algebra

View File

@ -0,0 +1 @@
../../CONTRIBUTING

2371
third_party/mathfu-1.1.0/docs/src/doxyfile vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,370 @@
<!-- Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<doxygenlayout version="1.0">
<navindex>
<tab type="mainpage" visible="no" title=""/>
<tab type="usergroup" url="" title="Programmer's Guide">
<tab type="usergroup" url="@ref mathfu_guide_introduction"
title="Introduction">
<tab type="user" url="@ref mathfu_guide_about_mathfu"
title="About MathFu"/>
<tab type="user" url="@ref mathfu_guide_prerequisites"
title="Prerequisites"/>
<tab type="user" url="@ref mathfu_guide_about_guide"
title="About This Guide"/>
<tab type="user" url="@ref mathfu_guide_concepts"
title="Concepts"/>
<tab type="user" url="@ref mathfu_guide_optimization"
title="Optimization"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_building"
title="Building">
<tab type="user" url="@ref mathfu_guide_building_options"
title="Integration Options"/>
<tab type="user" url="@ref mathfu_guide_building_compiler_config"
title="Manual Compiler Configuration"/>
<tab type="user" url="@ref mathfu_guide_building_cmake"
title="CMake"/>
<tab type="user" url="@ref mathfu_guide_building_android_makefiles"
title="Android NDK Makefiles"/>
<tab type="usergroup" url="" title="Building Unit Tests">
<tab type="usergroup" url="@ref mathfu_guide_building_android"
title="Building for Android">
<tab type="user" url="@ref mathfu_guide_building_android_version"
title="Version Requirements"/>
<tab type="user"
url="@ref mathfu_guide_building_android_prerequisites"
title="Prerequisites"/>
<tab type="user"
url="@ref mathfu_guide_building_android_building"
title="Building"/>
<tab type="user"
url="@ref mathfu_guide_building_android_building_ndk_build"
title="Building with ndk-build"/>
<tab type="user"
url="@ref mathfu_guide_building_android_building_fplutil"
title="Building with fplutil"/>
<tab type="user"
url="@ref mathfu_guide_building_android_running"
title="Installing and Running Applications"/>
<tab type="user"
url="@ref mathfu_guide_building_android_eclipse"
title="Using Eclipse"/>
<tab type="user"
url="@ref mathfu_guide_building_android_fplutil"
title="Using fplutil"/>
<tab type="user"
url="@ref mathfu_guide_building_android_code_generation"
title="Code Generation"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_building_linux"
title="Building for Linux">
<tab type="user" url="@ref mathfu_guide_building_linux_version"
title="Version Requirements"/>
<tab type="user"
url="@ref mathfu_guide_building_linux_prerequisites"
title="Prerequisites"/>
<tab type="user" url="@ref mathfu_guide_building_linux_building"
title="Building"/>
<tab type="user" url="@ref mathfu_guide_building_linux_running"
title="Running Applications"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_building_osx"
title="Building for OS X">
<tab type="user" url="@ref mathfu_guide_building_osx_version"
title="Version Requirements"/>
<tab type="user"
url="@ref mathfu_guide_building_osx_prerequisites"
title="Prerequisites"/>
<tab type="user" url="@ref mathfu_guide_building_osx_building"
title="Building with Xcode"/>
<tab type="user" url="@ref mathfu_guide_building_osx_running"
title="Running Applications"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_building_windows"
title="Building for Windows">
<tab type="user" url="@ref mathfu_guide_building_windows_version"
title="Version Requirements"/>
<tab type="user"
url="@ref mathfu_guide_building_windows_prerequisites"
title="Prerequisites"/>
<tab type="user" url="@ref mathfu_guide_building_windows_building"
title="Building with Visual Studio"/>
<tab type="user" url="@ref mathfu_guide_building_windows_running"
title="Running Applications"/>
</tab>
</tab>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_vectors"
title="Vectors">
<tab type="usergroup" url="@ref mathfu_guide_vectors_declaration"
title="Declaration">
<tab type="user" url="@ref mathfu_guide_vectors_initialization"
title="Initialization"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_vectors_accessors"
title="Accessors">
<tab type="user" url="@ref mathfu_guide_vectors_assignment"
title="Assignment"/>
</tab>
<tab type="user" url="@ref mathfu_guide_vectors_arithmetic"
title="Arithmetic"/>
<tab type="user" url="@ref mathfu_guide_vectors_constants"
title="Constants"/>
<tab type="user" url="@ref mathfu_guide_vectors_geometric"
title="Geometric Operations"/>
<tab type="user" url="@ref mathfu_guide_vectors_other"
title="Other Operations"/>
<tab type="user" url="@ref mathfu_guide_vectors_packing"
title="Packing"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_quaternions"
title="Quaternions">
<tab type="usergroup" url="@ref mathfu_guide_quaternions_declaration"
title="Declaration">
<tab type="user" url="@ref mathfu_guide_quaternions_initialization"
title="Initialization"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_quaternions_accessors"
title="Accessors">
<tab type="user" url="@ref mathfu_guide_quaternions_assignment"
title="Assignment"/>
</tab>
<tab type="user" url="@ref mathfu_guide_quaternions_repr"
title="Converting Between Representations"/>
<tab type="user" url="@ref mathfu_guide_quaternions_manipulation"
title="Manipulation"/>
<tab type="user" url="@ref mathfu_guide_quaternions_application"
title="Application"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_matrices"
title="Matrices">
<tab type="usergroup" url="@ref mathfu_guide_matrices_declaration"
title="Declaration">
<tab type="user" url="@ref mathfu_guide_matrices_initialization"
title="Initialization"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_matrices_accessors"
title="Accessors">
<tab type="user" url="@ref mathfu_guide_matrices_assignment"
title="Assignment"/>
</tab>
<tab type="user" url="@ref mathfu_guide_matrices_arithmetic"
title="Arithmetic"/>
<tab type="user" url="@ref mathfu_guide_matrices_matrix_ops"
title="Matrix Operations"/>
<tab type="user" url="@ref mathfu_guide_matrices_packing"
title="Packing"/>
</tab>
<tab type="usergroup" url="@ref mathfu_guide_utilities"
title="Utilities">
<tab type="user" url="@ref mathfu_guide_utilities_allocation"
title="Memory Allocation"/>
<tab type="usergroup" url="@ref mathfu_guide_utilities_misc"
title="Miscellaneous Functions">
<tab type="user" url="@ref mathfu_guide_utilities_random"
title="Random Number Generation"/>
</tab>
</tab>
</tab>
<tab type="usergroup" url="@ref mathfu_api_reference"
title="API reference">
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<!--tab type="examples" visible="yes" title="" intro=""/-->
</tab>
<tab type="user" url="@ref mathfu_readme" title="readme"/>
<tab type="user" url="@ref contributing" title="contributing"/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<detaileddescription title=""/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<detaileddescription title=""/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<detaileddescription title=""/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

View File

@ -0,0 +1,28 @@
/// @defgroup mathfu_build_config Build Configuration
/// @brief Macros that control build configuration.
/// @defgroup mathfu_allocator Allocators
/// @brief SIMD-safe memory allocators.
/// @defgroup mathfu_constants Constants
/// @brief Vector constants for specific dimensions.
/// @defgroup mathfu_vector Vectors
/// @brief Vector class and functions.
/// @defgroup mathfu_matrix Matrices
/// @brief Matrix class and functions.
/// @defgroup mathfu_quaternion Quaternions
/// @brief Quaternion class and functions.
/// @defgroup mathfu_glsl GLSL Mappings
/// @brief <a href="https://www.opengl.org/documentation/glsl/">GLSL</a>
/// compatible data types.
/// @defgroup mathfu_utilities Utility Functions
/// @brief Utility functions.
/// @defgroup mathfu_version Version Constants
/// @brief Macros and variables that describe the library version.

View File

@ -0,0 +1,79 @@
MathFu {#mathfu_index}
======
# Overview {#mathfu_overview}
[MathFu][] is a C++ math library developed primarily for games focused on
simplicity and efficiency.
It provides a suite of [vector][], [matrix][] and [quaternion][] classes
to perform basic [geometry][] suitable for game developers. This functionality
can be used to construct geometry for graphics libraries like [OpenGL][] or
perform calculations for animation or physics systems.
[MathFu] can be downloaded from [GitHub](http://github.com/google/mathfu) or
the [releases page](http://github.com/google/mathfu/releases).
**Important**: MathFu uses submodules to reference other components it depends
upon so download the source using:
~~~{.sh}
git clone --recursive https://github.com/google/mathfu.git
~~~
# Functionality
Each [vector][], [matrix][] and [quaternion][] class implements basic
arithmetic operators (addition, subtraction, multiplication, division) in
addition to simple [linear algebra][] operators (e.g dot product,
cross product, inverse, slerp).
# Optimization
[MathFu][] is optimized using [SIMD][] instructions (including [NEON][] for
[ARM][] and [SSE][] for [x86][] architectures). [SIMD][] optimization is
enabled by default based upon the target platform and compiler options used
to build a project. In addition, [MathFu][] provides compile time options to
modify code generation, see [Build Configurations][] for more details.
# Supported Platforms
[MathFu][] has been tested on the following platforms:
* [Android][]
* [Linux][] (x86_64)
* [OS X][]
* [Windows][]
This library is entirely written in C++ with the exception of some
conditionally enabled compiler intrinsics and some workarounds for different
compiler quirks, which means that it *should* work with either no or little
modification on any platform that has a C++ compiler.
# Feedback and Reporting Bugs
* Discuss MathFu with other developers and users on the
[MathFu Google Group][].
* File issues on the [MathFu Issues Tracker][].
* Post your questions to [stackoverflow.com][] with a mention of **mathfu**.
[Android]: http://www.android.com
[ARM]: http://en.wikipedia.org/wiki/ARM_architecture
[Build Configurations]: @ref mathfu_build_config
[Linux]: http://en.m.wikipedia.org/wiki/Linux
[MathFu Google Group]: http://groups.google.com/group/mathfulib
[MathFu Issues Tracker]: http://github.com/google/mathfu/issues
[MathFu]: @ref mathfu_overview
[NEON]: http://www.arm.com/products/processors/technologies/neon.php
[OS X]: http://www.apple.com/osx/
[OpenGL]: http://www.opengl.org/
[SIMD]: http://en.wikipedia.org/wiki/SIMD
[SSE]: http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions
[Windows]: http://windows.microsoft.com/
[geometry]: http://en.wikipedia.org/wiki/Geometry
[linear algebra]: http://en.wikipedia.org/wiki/Linear_algebra
[matrix]: http://en.wikipedia.org/wiki/Matrix_(mathematics)
[quaternion]: http://en.wikipedia.org/wiki/Quaternion
[stackoverflow.com]: http://stackoverflow.com/search?q=mathfu
[vector]: http://en.wikipedia.org/wiki/Euclidean_vector
[x86]: http://en.wikipedia.org/wiki/X86

View File

@ -0,0 +1,177 @@
Building {#mathfu_guide_building}
========
# Integration Options {#mathfu_guide_building_options}
[MathFu][] is designed as a C++ header only library to simplify the process
of including the library in projects. [MathFu] provides the following options
for using it in a project:
* [Manually configure the compiler][] by simply include the appropriate
headers into a project's source code.
* Use the [CMake project][].
* Include the [Android NDK project][] when developing for [Android][]
Before diving into using [MathFu][] in your project, we recommend you spend
some time building and running the unit tests for each platform you wish to
target by working through the following sections:
* [Building for Android][]
* [Building for Linux][]
* [Building for OS X][]
* [Building for Windows][]
# Manual Compiler Configuration {#mathfu_guide_building_compiler_config}
The following directories need to be added to the include paths of a project
to build the default configuration:
* `mathfu/include`
* `vectorial/include`
- If [vectorial][] was downloaded with the [MathFu][] project, this
will be located under the `dependencies/` directory.
In addition, to compile with [SIMD][] enabled an architecture specific flag
must be specified:
Architecture | Compiler | Flag
----------------|---------------------|------------
[x86][] | Android GCC / Clang | -msse
[x86_64][] | Android GCC / Clang | -msse4.1
[x86][] | GCC / Clang | -msse4.1
[ARM][] | GCC / Clang | -mfpu=neon
[x86][] | Visual Studio | /arch:SSE2
For example, to compile the following file `test.cpp` against [MathFu][] with
gcc for x86:
~~~{.cpp}
#include <stdio.h>
#include "mathfu/vector.h"
int main(int argc, char *argv[]) {
mathfu::Vector<float, 3> v1(1.0f, 2.0f, 3.0f), v2(3.0f, 2.5f, 0.5f), v3;
v3 = v1 + v2;
printf("%.1f %.1f %.1f\n", v3.x(), v3.y(), v3.z());
return 0;
}
~~~
requires the following command line (assuming vectorial is in the
`mathfu/dependencies` directory):
~~~{.sh}
g++ -Imathfu/include -Imathfu/dependencies/vectorial/include test.cpp -msse4.1
~~~
In addition, [MathFu][] provides a set of build configuration options that
are controlled using preprocessor symbols described by [Build Configuration][].
# CMake {#mathfu_guide_building_cmake}
[MathFu][] uses a [CMake][] project to build unit tests and benchmarks
for [Linux][], [OS X][] and [Windows][].
[CMake][] is used to generate a platform projects for each target platform:
* [Makefiles][] ([Linux][] / [OS X][])
* [Xcode][] projects ([OS X][])
* [Visual Studio][] projects ([Windows][])
If you're not familiar with [CMake][], see the following sections to learn how
to build on each platform:
* [Building for Linux][]
* [Building for OS X][]
* [Building for Windows][]
In addition to building the [MathFu][] unit tests and benchmarks,
the [MathFu][] [CMake][] project can be used in developers own projects by:
* Disabling the build of unit tests and benchmarks using the options:
- `mathfu_build_benchmarks`
- `mathfu_build_tests`
* Including the [CMake][] project.
* Using the `mathfu_configure_flags` function to add the appropriate
include directories and compiler flags for the project.
For example, in a CMakeLists.txt project file which contains the executable
`mygame`:
~~~
# Include MathFu in this project with test and benchmark builds disabled
# then add MathFu compiler flags to the mygame build target.
set(mathfu_build_benchmarks OFF CACHE BOOL "")
set(mathfu_build_tests OFF CACHE BOOL "")
add_subdirectory(path/to/mathfu mathfu)
mathfu_configure_flags(mygame)
~~~
[MathFu][] build options (see [Build Configuration][]) can be configured
with the `mathfu_configure_flags` function using the optional arguments
`enable_simd` and `force_padding`. For example:
Function Call | Build Configuration
--------------------------------------------|----------------------------------
`mathfu_configure_flags(mygame)` | Default, SIMD & padding enabled.
`mathfu_configure_flags(mygame TRUE FALSE)` | SIMD enabled & padding disabled.
`mathfu_configure_flags(mygame FALSE)` | SIMD disabled.
See the function comment in the CMakeLists.txt file for more information.
# Android NDK Makefiles {#mathfu_guide_building_android_makefiles}
If you're not familiar developing applications with the [Android NDK][],
see [Building for Android][] first.
To use [MathFu][] with an [Android NDK][] makefile project, add the following
lines to your project's `Android.mk` file.
~~~{.mk}
# Add the empty MathFu static library target to configure the project.
LOCAL_STATIC_LIBRARIES += libmathfu
# This is used to build your project's shared library, this should already
# be in your Android.mk makefile.
include $(BUILD_SHARED_LIBRARY)
# Add the directory containing MathFu to the module search path.
$(call import-add-path,$(abspath path/to/mathfu/..))
# Import the MathFu project.
$(call import-module,mathfu/jni)
~~~
[MathFu][] build options (see [Build Configuration][]) can be configured
by linking against the different static libraries the [MathFu][] project
builds:
Library | Build Configuration
-----------------------|--------------------------------------------------
`libmathfu` | Default configuration, SIMD and padding enabled.
`libmathfu_no_padding` | SIMD enabled (if supported), padding disabled.
`libmathfu_no_simd` | SIMD disabled, padding disabled.
<br>
[Android NDK project]: @ref mathfu_guide_building_android_makefiles
[Android NDK]: http://developer.android.com/tools/sdk/ndk/index.html
[Android]: http://www.android.com
[ARM]: http://en.wikipedia.org/wiki/ARM_architecture
[Build Configuration]: @ref mathfu_build_config
[Building for Android]: @ref mathfu_guide_building_android
[Building for Linux]: @ref mathfu_guide_building_linux
[Building for OS X]: @ref mathfu_guide_building_osx
[Building for Windows]: @ref mathfu_guide_building_windows
[CMake project]: @ref mathfu_guide_building_cmake
[CMake]: http://www.cmake.org/
[Linux]: http://en.m.wikipedia.org/wiki/Linux
[Makefiles]: http://www.gnu.org/software/make/
[Manually configure the compiler]: @ref mathfu_guide_building_compiler_config
[MathFu]: @ref mathfu_overview
[OS X]: http://www.apple.com/osx/
[SIMD]: http://en.wikipedia.org/wiki/SIMD
[Visual Studio]: http://www.visualstudio.com/
[Windows]: http://windows.microsoft.com/
[Xcode]: http://developer.apple.com/xcode/
[vectorial]: http://github.com/scoopr/vectorial
[x86]: http://en.wikipedia.org/wiki/X86
[x86_64]: http://en.wikipedia.org/wiki/X86

View File

@ -0,0 +1,159 @@
Building for Android {#mathfu_guide_building_android}
====================
# Version Requirements {#mathfu_guide_building_android_version}
Following are the minimum tested versions of the tools and libraries you
need to build [MathFu][] for Android:
* [Android SDK][]: Android 2.3.3 (API Level 10) or above.
* [Android Developer Tools][] ([ADT][]): 20140702
- NDK plugn for Eclipse (bundled with [ADT][]) if using Eclipse to build.
* [Android NDK][]: android-ndk-r10e
* [fplutil][]: 1.0 or above, if using [fplutil][] to build, install and run.
# Prerequisites {#mathfu_guide_building_android_prerequisites}
Prior to building:
* Install the [Android SDK][].
* Install the [Android NDK][].
* Install [fplutil prerequisites][] if using [fplutil][] to build, install
and run.
# Building {#mathfu_guide_building_android_building}
Each [MathFu][] project for Android has an associated `AndroidManifest.xml`
file and `jni` subdirectory. Unit tests and benchmarks directories contain
projects that each build an Android package ([apk][]) which can be installed
and executed on Android devices.
The following directories in the [MathFu] project contain [Android NDK][]
projects:
* `mathfu/`
- Rules used to build the [MathFu][] library.
* `mathfu/benchmarks`
- Each subdirectory under this directory contains a simple benchmark
used to measure the performance of different build configurations.
* `mathfu/unit_tests`
- Each subdirectory under this directory contains a unit test application
used to test different components of the library in different build
configurations.
## Building with ndk-build {#mathfu_guide_building_android_building_ndk_build}
To build a single [Android NDK][] project (without packaging the native
component in an [apk][]):
* Open a command line window.
* Go to the directory containing the project to build.
* `ndk-build`
For example, to build the matrix test for the default build configuration
without generating an [apk][]:
~~~{.sh}
cd mathfu/unit_tests/matrix_test/default
ndk-build
~~~
## Building with fplutil {#mathfu_guide_building_android_building_fplutil}
To build all [Android NDK][] projects, install and run them on a device:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Execute `dependencies/fplutil/bin/build_all_android.py`
For example:
~~~{.sh}
cd mathfu
./dependencies/fplutil/bin/build_all_android.py
~~~
# Installing and Running Applications {#mathfu_guide_building_android_running}
## Using Eclipse {#mathfu_guide_building_android_eclipse}
Running a sample requires the [Android Developer Tools][] ([ADT][]) plugin and
the [NDK Eclipse plugin][].
* Build a project using `ndk-build`
([see above](@ref mathfu_guide_building_android_building_ndk_build)).
* Open [ADT][] Eclipse.
* Select "File->Import..." from the menu.
* Select "Android > Existing Android Code Into Workspace", and click "Next".
* Click the "Browse..." button next to `Root Directory:` and select the
project folder (e.g. `mathfu/unit_tests/matrix_test/default`).
* Click "Finish". Eclipse imports the project, and displays it in the
Package Explorer pane.
* Right-click the project, and select "Run->Run As->Android Application"
from the menu.
* If you do not have a physical device, you must define a virtual one.
For details about how to define a virtual device, see [managing avds][].
We dont recommend a virtual device for development.
* None of the applications have a visual component so their output is
visible via the log ([adb][] logcat).
## Using fplutil {#mathfu_guide_building_android_fplutil}
To install and run a single application:
* Open a command line window.
* Go to the directory containing the project to install and run.
* Execute `dependencies/fplutil/bin/build_all_android.py` with the `-i`
and `-r` options.
For example:
~~~{.sh}
cd mathfu/unit_tests/matrix_test/default
./dependencies/fplutil/bin/build_all_android.py -i -r
~~~
To install and run all applications:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Execute `dependencies/fplutil/bin/build_all_android.py` with the `-i`
and `-r` options.
For example:
~~~{.sh}
cd mathfu
./dependencies/fplutil/bin/build_all_android.py -i -r
~~~
# Code Generation {#mathfu_guide_building_android_code_generation}
By default, code is generated for devices that support the `armeabi-v7a`
ABI. Alternatively, you can generate a fat `.apk` that includes code for all
ABIs. To do so, override APP\_ABI on ndk-build's command line.
Using `ndk-build`:
~~~{.sh}
ndk-build APP_ABI=all
~~~
Using `fplutil`:
~~~{.sh}
./dependencies/fplutil/bin/build_all_android.py -f APP_ABI=all
~~~
<br>
[MathFu]: @ref mathfu_overview
[adb]: http://developer.android.com/tools/help/adb.html
[ADT]: http://developer.android.com/tools/sdk/eclipse-adt.html
[Android Developer Tools]: http://developer.android.com/sdk/index.html
[Android NDK]: http://developer.android.com/tools/sdk/ndk/index.html
[Android SDK]: http://developer.android.com/sdk/index.html
[NDK Eclipse plugin]: http://developer.android.com/sdk/index.html
[apk]: http://en.wikipedia.org/wiki/Android_application_package
[fplutil]: http://google.github.io/fplutil
[fplutil prerequisites]: http://google.github.io/fplutil/fplutil_prerequisites.html
[managing avds]: http://developer.android.com/tools/devices/managing-avds.html

View File

@ -0,0 +1,106 @@
Building for Linux {#mathfu_guide_building_linux}
==================
# Version Requirements {#mathfu_guide_building_linux_version}
Following are the minimum required versions of tools and libraries you
need to build [MathFu][] for Android:
* [CMake][]: 2.8.12.1
# Prerequisites {#mathfu_guide_building_linux_prerequisites}
Prior to building, install the following components using the [Linux][]
distribution's package manager:
* [CMake][]. You can also manually install packages from
[cmake.org](http://cmake.org).
For example, on [Ubuntu][]:
~~~{.sh}
sudo apt-get install cmake
~~~
# Building {#mathfu_guide_building_linux_building}
* Open a command line window.
* Go to the [MathFu][] project directory.
* Generate [Makefiles][] from the [CMake][] project.
* Execute `make` to build the unit tests and benchmarks.
For example:
~~~{.sh}
cd mathfu
cmake -G'Unix Makefiles' .
make
~~~
To perform a debug build:
~~~{.sh}
cd mathfu
cmake -G'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug .
make
~~~
Build targets can be configured using options exposed in
`mathfu/CMakeLists.txt` by using [CMake]'s `-D` option.
Build configuration set using the `-D` option is sticky across subsequent
builds.
For example, if a build is performed using:
~~~{.sh}
cd mathfu
cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug .
make
~~~
to switch to a release build CMAKE_BUILD_TYPE must be explicitly specified:
~~~{.sh}
cd mathfu
cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .
make
~~~
# Running Applications {#mathfu_guide_building_linux_running}
Each benchmark binaries are located in the `benchmarks/` directory and
unit test binaries are located in the `unit_tests/` directory.
To run all benchmarks:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Run each benchmark binary in the `benchmarks/` directory.
For example:
~~~{.sh}
cd mathfu
for binary in ./benchmarks/*_benchmarks; do ${binary}; done
~~~
To run all unit tests:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Run each unit test binary in the `unit_tests/` directory.
For example:
~~~{.sh}
cd mathfu
for binary in ./unit_tests/*_tests; do ${binary}; done
~~~
<br>
[CMake]: http://www.cmake.org/
[Linux]: http://en.wikipedia.org/wiki/Linux
[Makefiles]: http://www.gnu.org/software/make/
[MathFu]: @ref mathfu_overview
[Ubuntu]: http://www.ubuntu.com

View File

@ -0,0 +1,98 @@
Building for OS X {#mathfu_guide_building_osx}
=================
# Version Requirements {#mathfu_guide_building_osx_version}
Following are the minimum required versions of tools and libraries you
need to build [MathFu][] for [OS X][]:
* [OS X][]: Mavericks 10.9.1.
* [Xcode][]: 5.0.1
* [CMake][]: 2.8.12.1
# Prerequisites {#mathfu_guide_building_osx_prerequisites}
* Install [Xcode][].
* Install [CMake][].
# Building with Xcode {#mathfu_guide_building_osx_building}
Firstly, the [Xcode][] project needs to be generated using [CMake][]:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Use [CMake][] to generate the [Xcode][] project.
~~~{.sh}
cd mathfu
cmake -G Xcode .
~~~
Then the project can be opened in [Xcode][] and built:
* Double-click on `mathfu/MathFu.xcodeproj` to open the project in
[Xcode][].
* Select "Product-->Build" from the menu.
# Running Applications {#mathfu_guide_building_osx_running}
## Running in Xcode {#mathfu_guide_building_osx_run_xcode}
Open [Xcode][] select a build target and run it:
* Double-click on `mathfu/MathFu.xcodeproj` to open the project in
[Xcode][].
* Select an application `Scheme`, for example
"matrix_tests-->My Mac 64-bit", from the combo box to the right of the
"Run" button.
* Click the "Run" button.
## Running from the Command Line {#mathfu_guide_building_osx_cmdline}
To build:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Generate the [Xcode][] project.
* Run xcodebuild.
For example:
~~~{.sh}
cd mathfu
cmake -G Xcode .
xcodebuild
~~~
To run all benchmarks:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Run each benchmark binary in the `benchmarks/` directory.
For example:
~~~{.sh}
cd mathfu
for binary in ./benchmarks/Debug/*_benchmarks; do ${binary}; done
~~~
To run all unit tests:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Run each unit test binary in the `unit_tests/` directory.
For example:
~~~{.sh}
cd mathfu
for binary in ./unit_tests/Debug/*_tests; do ${binary}; done
~~~
<br>
[CMake]: http://www.cmake.org
[MathFu]: @ref mathfu_overview
[OS X]: http://www.apple.com/osx/
[Xcode]: http://developer.apple.com/xcode/

View File

@ -0,0 +1,84 @@
Building for Windows {#mathfu_guide_building_windows}
====================
# Version Requirements {#mathfu_guide_building_windows_version}
Following are the minimum required versions of tools and libraries you
need to build [MathFu][] for Android:
* [Windows][]: 7
* [Visual Studio][]: 2012
* [CMake][]: 2.8.12.1
# Prerequisites {#mathfu_guide_building_windows_prerequisites}
Prior to building, install the following:
* [Visual Studio][]
* [CMake][] from [cmake.org](http://cmake.org).
# Building with Visual Studio {#mathfu_guide_building_windows_building}
Generate the [Visual Studio][] project using [CMake][]:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Use [CMake][] to generate the [Visual Studio][] project.
~~~{.sh}
cd mathfu
cmake -G "Visual Studio 11 2012" .
~~~
Open the [MathFu][] solution in [Visual Studio][].
* Double-click on `mathfu/MathFu.sln` to open the solution.
* Select "Build-->Build Solution" from the menu.
# Running Applications {#mathfu_guide_building_windows_running}
## Running in Visual Studio {#mathfu_guide_building_osx_run_vs}
Open [Visual Studio][] select a build target and run it:
* Double-click on `mathfu/MathFu.sln` to open the solution in
[Visual Studio][].
* Right click on a project, for example `matrix_tests`, select
"Set as StartUp Project" from the menu.
* Select "Debug-->Start Debugging" from the menu.
## Running from the Command Line {#mathfu_guide_building_windows_cmdline}
To run all benchmarks:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Run each benchmark binary in the `benchmarks/` directory.
For example:
~~~{.sh}
cd mathfu
for %a in (benchmarks\Debug\*.exe) do %a
~~~
To run all unit tests:
* Open a command line window.
* Go to the [MathFu][] project directory.
* Run each unit test binary in the `unit_tests/` directory.
For example:
~~~{.sh}
cd mathfu
for %a in (unit_tests\Debug\*.exe) do %a
~~~
<br>
[CMake]: http://www.cmake.org
[MathFu]: @ref mathfu_overview
[Visual Studio]: http://www.visualstudio.com/
[Windows]: http://windows.microsoft.com/

View File

@ -0,0 +1,80 @@
Introduction {#mathfu_guide_introduction}
============
# About MathFu {#mathfu_guide_about_mathfu}
[MathFu][] is a C++ math library developed primarily for games focused on
simplicity and efficiency.
It provides a suite of [vector][], [matrix][] and [quaternion][] classes
to perform basic [geometry][] suitable for game developers. This functionality
can be used to construct geometry for graphics libraries like [OpenGL][] or
perform calculations for animation or physics systems.
# Prerequisites {#mathfu_guide_prerequisites}
[MathFu][] is written in C++, you are expected to be experienced in C++
programming. [MathFu][] should not be your first C++ programming project! You
should be comfortable with compiling, linking, and debugging.
# About This Guide {#mathfu_guide_about_guide}
This guide provides an overview of the [MathFu] API, it does *not* cover
every aspect of functionality provided by the library. The entire API
is documented by the [API reference][]. In addition, the unit tests
(under `mathfu/unit_tests`) provide example usage of each class and function
in the library.
# Concepts {#mathfu_guide_concepts}
The core functionality of [MathFu][] is provided by the following classes:
* [Vector](@ref mathfu::Vector)
* [Matrix](@ref mathfu::Matrix)
* [Quaternion](@ref mathfu::Quaternion)
Each class is described in the following sections of the guide:
* [Vector](@ref mathfu_guide_vectors)
- A geometric concept with a magnitude and direction, defined in any
dimensional space.
* [Matrix](@ref mathfu_guide_matrices)
- A set of data organized in rows and columns.
[MathFu][] matricies may have any number of rows and columns.
* [Quaternion](@ref mathfu_guide_quaternions)
- A specific type of four dimensional vector and defines a rotation in
three dimensional space.
In addition, [MathFu][] provides a suite of general math functions and method
that make it easier to handle the special requirements of [SIMD][] data types
described in the [Utilities](@ref mathfu_guide_utilities) section.
# Optimization {#mathfu_guide_optimization}
[MathFu][] is optimized using [SIMD][] instructions (including [NEON][] for
[ARM][] and [SSE][] for [x86][] architectures). [SIMD][] optimization is
enabled by default based upon the target platform and compiler options used
to build a project. In addition, [MathFu][] provides compile time options to
modify code generation, see [Build Configurations][] for more details.
## Supporting Additional Architectures
[MathFu][]'s [SIMD][] implementation uses [vectorial][] as an abstraction
layer for common [SIMD][] instructions and data types. To support additional
architectures, contributors can add support for new [SIMD][] instructions and
data types to the [vectorial][] project and then modify the code in
mathfu/utilities.h to define the macro <code>MATHFU_COMPILE_WITH_SIMD</code>
for the new architecture.
[ARM]: http://en.wikipedia.org/wiki/ARM_architecture
[API reference]: @ref mathfu_api_reference
[matrix]: http://en.wikipedia.org/wiki/Matrix_(mathematics)
[geometry]: http://en.wikipedia.org/wiki/Geometry
[vector]: http://en.wikipedia.org/wiki/Euclidean_vector
[quaternion]: http://en.wikipedia.org/wiki/Quaternion
[OpenGL]: http://www.opengl.org/
[MathFu]: @ref mathfu_overview
[vectorial]: http://github.com/scoopr/vectorial
[SIMD]: http://en.wikipedia.org/wiki/SIMD
[SSE]: http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions
[x86]: http://en.wikipedia.org/wiki/X86
[NEON]: http://www.arm.com/products/processors/technologies/neon.php
[Build Configurations]: @ref mathfu_build_config

View File

@ -0,0 +1,358 @@
Matrices {#mathfu_guide_matrices}
========
Matrices consist of a set of elements (usually floating point or integer
scalars) arranged in rows and columns. For more information see
[this description](http://en.wikipedia.org/wiki/Matrix_(mathematics))
of matrices.
The [MathFu][] [Matrix][] class is a template declared in
[mathfu/matrix.h](@ref mathfu/matrix.h) which has been specialized and
optimized for the most regularly used case (floating point elements with
4 rows and 4 columns).
Implementing [Matrix][] as a template reduces code duplication, provides
compile time optimization opportunities through specialization and allows
users to use the class with any scalar type.
# Declaration {#mathfu_guide_matrices_declaration}
The [Matrix][] class template takes either 2 or 3 arguments in the form:
* Matrix<type, number_of_rows_and_columns>
* Matrix<type, number_of_rows, number_of_columns>
For example, a floating point 4 row, 4 column (4x4) matrix can be declared
using either:
~~~{.cpp}
mathfu::Matrix<float, 4, 4> matrix;
~~~
or:
~~~{.cpp}
mathfu::Matrix<float, 4> matrix;
~~~
To eliminate the need for explicit template instantiation for common matrices,
[GLSL][] style `typedef`s are provided in
[mathfu/glsl_mappings.h](@ref mathfu/glsl_mappings.h). Using a [GLSL][]
style `typedef` a 4x4 floating point matrix variable is declared
using the following:
~~~{.cpp}
mathfu::mat4 matrix;
~~~
## Initialization {#mathfu_guide_matrices_initialization}
For efficiency, [Matrix][] is uninitialized when constructed. Constructors
are provided for common matrix sizes that allow initialization on construction.
For example, to initialize a 2x2 floating point matrix:
~~~{.cpp}
mathfu::mat2 matrix(1.0f, 2.0f, // column 0
3.0f, 4.0f); // column 1
~~~
It's also possible to initialize a [Matrix][] with another instance:
~~~{.cpp}
const mathfu::mat2 matrix1(1.0f, 2.0f, // column 0
3.0f, 4.0f); // column 1
mathfu::mat2 matrix2(matrix1);
~~~
This can also be achieved with:
~~~{.cpp}
const mathfu::mat2 matrix1(1.0f, 2.0f, // column 0
3.0f, 4.0f); // column 1
mathfu::mat2 matrix2 = matrix1;
~~~
# Accessors {#mathfu_guide_matrices_accessors}
[Matrix][] provides an array operator to retrieve individual elements in a
flattened array and a parenthesis operator to access an element by row and
column index.
When using the array operator, the [Matrix][] is indexed by rows then columns.
For example, a 3x3 matrix will access the following locations:
Array Index | Column | Row
------------|--------|--------
0 | 0 | 0
1 | 0 | 1
2 | 0 | 2
3 | 1 | 0
4 | 1 | 1
5 | 1 | 2
6 | 2 | 0
7 | 2 | 1
8 | 2 | 2
For example, to access column 1, row 2 of a 3x3 matrix using the array
operator, use index "5":
~~~{.cpp}
const mathfu::mat3 matrix(1.0f, 2.0f, 3.0f, // column 0
4.0f, 5.0f, 6.0f, // column 1
7.0f, 8.0f, 9.0f); // column 2
float column1_row2 = matrix[5]; // 6.0f
~~~
The parenthesis operator allows access to an element by specifying the row
and column indices directly. For example, to access column 1, row 2 of a
3x3 matrix:
~~~{.cpp}
const mathfu::mat3 matrix(1.0f, 2.0f, 3.0f, // column 0
4.0f, 5.0f, 6.0f, // column 1
7.0f, 8.0f, 9.0f); // column 2
float column1_row2 = matrix(2, 1);
~~~
## Assignment {#mathfu_guide_matrices_assignment}
[Matrix][] array and parenthesis operators return a reference to an element
which can be modified by the caller.
For example, to update column 1, row 2 of a 3x3 matrix using the array
operator:
~~~{.cpp}
mathfu::mat3 matrix(1.0f, 2.0f, 3.0f, // column 0
4.0f, 5.0f, 0.0f, // column 1
7.0f, 8.0f, 9.0f); // column 2
matrix[5] = 6.0f;
~~~
To update column 1, row 2 of a 3x3 matrix using the parenthesis operator:
~~~{.cpp}
mathfu::mat3 matrix(1.0f, 2.0f, 3.0f, // column 0
4.0f, 5.0f, 6.0f, // column 1
7.0f, 0.0f, 9.0f); // column 2
matrix(2, 1) = 8.0f;
~~~
# Arithmetic {#mathfu_guide_matrices_arithmetic}
[Matrix][] supports in-place and out-of-place addition and subtraction
with other matrices and scalars. Multiplication and division of matrix
elements is supported with scalars.
For example, two matrices can be added together using the following:
~~~{.cpp}
const mathfu::mat2 matrix1(1.0f, 2.0f,
3.0f, 4.0f);
const mathfu::mat2 matrix2(5.0f, 6.0f,
7.0f, 8.0f);
mathfu::mat2 matrix3 = matrix1 + matrix2;
~~~
The above preserves the contents of `matrix1` and `matrix2` with the following
in `matrix3`:
6.0f, 8.0f
10.0f, 12.0f
The same can be achieved with an in-place addition which mutates `matrix1`:
~~~{.cpp}
mathfu::mat2 matrix1(1.0f, 2.0f,
3.0f, 4.0f);
const mathfu::mat2 matrix2(5.0f, 6.0f,
7.0f, 8.0f);
matrix1 += matrix2;
~~~
Addition with a scalar results in the value being added to all elements.
For example:
~~~{.cpp}
mathfu::mat2 matrix1(1.0f, 2.0f,
3.0f, 4.0f);
matrix1 += 1.0f;
~~~
where `matrix1` contains the following:
2.0f, 3.0f,
4.0f, 5.0f
Subtraction is similar to addition:
~~~{.cpp}
const mathfu::mat2 matrix1(1.0f, 2.0f,
3.0f, 4.0f);
const mathfu::mat2 matrix2(5.0f, 6.0f,
7.0f, 8.0f);
mathfu::mat2 matrix3 = matrix2 - matrix1;
~~~
where `matrix3` contains the following:
4.0f, 4.0f,
4.0f, 4.0f
Subtraction with a scalar:
~~~{.cpp}
mathfu::mat2 matrix1(1.0f, 2.0f,
3.0f, 4.0f);
matrix1 -= 1.0f;
~~~
where `matrix1` contains the following:
0.0f, 1.0f
2.0f, 3.0f
Multiplication with a scalar:
~~~{.cpp}
mathfu::mat2 matrix1(1.0f, 2.0f,
3.0f, 4.0f);
matrix1 *= 2.0f;
~~~
where `matrix1` contains the following:
2.0f, 4.0f
6.0f, 8.0f
Division with a scalar:
~~~{.cpp}
mathfu::mat2 matrix1(1.0f, 2.0f,
3.0f, 4.0f);
matrix1 /= 2.0f;
~~~
where `matrix1` contains the following:
0.5f, 1.0f
1.5f, 2.0f
# Matrix Operations {#mathfu_guide_matrices_matrix_ops}
Identity matrices are constructed using
[Matrix::Identity](@ref mathfu::Matrix::Identity):
~~~{.cpp}
mathfu::mat2 identity = mathfu::mat2::Identity();
~~~
[Matrix][] supports matrix multiplication using the `* operator`.
Matrix multiplication is performed using the `* operator`:
~~~{.cpp}
const mathfu::mat2 matrix1(1.0f, 2.0f,
3.0f, 4.0f);
const mathfu::mat2 matrix2(5.0f, 6.0f,
7.0f, 8.0f);
mathfu::mat2 matrix3 = matrix1 * matrix2;
~~~
which preserves `matrix1` and `matrix2` while storing the result in
`matrix3`:
23.0f, 31.0f
34.0f, 46.0f
The [inverse](http://en.wikipedia.org/wiki/Invertible_matrix) of a [Matrix][]
can be calculated using [Matrix::Inverse](@ref mathfu::Matrix::Inverse):
~~~{.cpp}
const mathfu::mat2 matrix(1.0f, 2.0f,
3.0f, 4.0f);
const mathfu::mat2 inverse = matrix.Inverse();
~~~
A [Matrix][] multiplied with its' inverse yields the identity matrix:
~~~{.cpp}
const mathfu::mat2 matrix(1.0f, 2.0f,
3.0f, 4.0f);
const mathfu::mat2 inverse = matrix.Inverse();
const mathfu::mat2 identity = matrix * inverse;
~~~
[Matrix][] provides a set of static methods that construct
[transformation matrices][]:
* [Matrix::FromTranslationVector()](@ref mathfu::Matrix::FromTranslationVector)
* [Matrix::FromScaleVector()](@ref mathfu::Matrix::FromScaleVector)
* [Matrix::RotationX()](@ref mathfu::Matrix::RotationX)
* [Matrix::RotationY()](@ref mathfu::Matrix::RotationY)
* [Matrix::RotationZ()](@ref mathfu::Matrix::RotationZ)
Transformation matrices yielded by these operations can be multiplied with
vector to translate, scale and rotate. For example, to rotate a 3-dimensional
vector around the X axis by PI/2 radians (90 degrees):
~~~{.cpp}
const mathfu::vec3 vector(1.0f, 2.0f, 3.0f);
const mathfu::mat3 rotation_around_x(mathfu::mat3::RotationX(M_PI / 2.0f));
const mathfu::vec3 rotated_vector = vector * rotation_around_x;
~~~
To scale a vector:
~~~{.cpp}
const mathfu::vec3 vector(1.0f, 2.0f, 3.0f);
const mathfu::mat4 scale_by_2(
mathfu::mat4::FromScaleVector(mathfu::vec3(2.0f)));
const mathfu::vec3 scaled_vector = scale_by_2 * vector;
~~~
In addition, a set of static methods are provided to construct
[camera matrices][]:
* [Matrix::Perspective()](@ref mathfu::Matrix::Perspective)
* [Matrix::Ortho()](@ref mathfu::Matrix::Ortho)
* [Matrix::LookAt()](@ref mathfu::Matrix::LookAt)
For example, to construct a perspective matrix:
~~~{.cpp}
const mathfu::mat4 perspective_matrix_ = mathfu::mat4::Perspective(
1.0f, 16.0f / 9.0f, 1.0f, 100.0f, -1.0f);
~~~
# Packing {#mathfu_guide_matrices_packing}
The size of the class can change based upon the [Build Configuration][] so it
should *not* be treated like a C style array. To serialize the class to a
flat array see [VectorPacked][].
For example, to pack (store) a [Matrix] to an array of packed vectors:
~~~{.cpp}
mathfu::mat4 matrix(1.0f);
mathfu::vec4_packed packed[4];
matrix.Pack(packed);
~~~
To unpack an array of packed vectors:
~~~{.cpp}
mathfu::vec4_packed packed[4];
mathfu::mat4 matrix(packed);
~~~
<br>
[Build Configuration]: @ref mathfu_build_config
[GLSL]: http://www.opengl.org/documentation/glsl/
[MathFu]: @ref mathfu_overview
[Matrix]: @ref mathfu::Matrix
[camera matrices]: http://en.wikipedia.org/wiki/3D_projection
[transformation matrices]: http://en.wikipedia.org/wiki/Transformation_matrix
[transformation matrix]: http://en.wikipedia.org/wiki/Transformation_matrix
[VectorPacked]: @ref mathfu::VectorPacked

View File

@ -0,0 +1,220 @@
Quaternions {#mathfu_guide_quaternions}
===========
[Quaternions] provide a representation of a 3-dimensional orientation or
rotation. [Quaternions] are especially useful when interpolating between
angles to avoid [Gimbal lock][]. For more information, see [this description].
[MathFu] implements a quaternion as the [Quaternion][] class template which is
constructed from one 3-dimensional [Vector][] and scalar component. The
[Quaternion][] template is intended to be instanced with `float` or `double`
floating point scalar types.
# Declaration {#mathfu_guide_quaternions_declaration}
The [Quaternions][] template takes a single argument which specifies the
floating point type of each element in the class:
~~~{.cpp}
mathfu::Quaternion<float> quaternion;
~~~
## Initialization {#mathfu_guide_quaternions_initialization}
For efficiency, [Quaternion][] is uninitialized when constructed. Constructors
are provided to initialize the class from a set of scalars, a 3-dimensional
[Vector][] and a scalar or another [Quaternion][].
For example, to initialize a [Quaternion][] using a set of scalars:
~~~{.cpp}
mathfu::Quaternion<float> quaternion(0.71f, 0.0f, 0.71f, 0.0f);
~~~
To initialize a [Quaternion][] from a scalar and 3-dimensional vector
component:
~~~{.cpp}
mathfu::Quaternion<float> quaternion(
0.50f, mathfu::vec3(0.76f, 0.38f, 0.19f));
~~~
# Accessors {#mathfu_guide_quaternions_accessors}
[Quaternion][] provides an array operator to retrieve elements of the object.
The first index is the scalar component with the remaining 3 indices referring
to elements in the vector component.
~~~{.cpp}
const mathfu::Quaternion<float> quaternion(
0.50f, mathfu::vec3(0.76f, 0.38f, 0.19f));
float s = quaternion[0];
float x = quaternion[1];
float y = quaternion[2];
float z = quaternion[3];
~~~
## Assignment {#mathfu_guide_quaternions_assignment}
The array operator returns a reference to an element in the [Quaternion][]
which can be updated:
~~~{.cpp}
mathfu::Quaternion<float> quaternion;
quaternion[0] = 0.5f;
quaternion[1] = 0.76f;
quaternion[2] = 0.38f;
quaternion[3] = 0.19f;
~~~
# Converting Between Representations {#mathfu_guide_quaternions_repr}
[Quaternion][] provides a number of ways to create a rotation or orientation:
* [Quaternion::FromAngleAxis()](@ref mathfu::Quaternion::FromAngleAxis)
* [Quaternion::FromEulerAngles()](@ref mathfu::Quaternion::FromEulerAngles)
* [Quaternion::FromMatrix()](@ref mathfu::Quaternion::FromMatrix)
For example, to create a [Quaternion][] which rotates PI / 2 radians around
the X-axis:
~~~{.cpp}
mathfu::Quaternion<float> quaternion =
mathfu::Quaternion<float>::FromAngleAxis(
M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
~~~
The rotation of PI / 2 radians around the X-axis can also be achieved with:
~~~{.cpp}
mathfu::Quaternion<float> quaternion =
mathfu::Quaternion<float>::FromEulerAngles(
mathfu::vec3(M_PI / 2.0f, 0.0f, 0.0f));
~~~
Similarly, a quaternion can be constructed from an existing rotation matrix
using:
~~~{.cpp}
// Assuming rotation_matrix is an existing matrix.
mathfu::Quaternion<float> quaternion =
mathfu::Quaternion<float>::FromMatrix(rotation_matrix);
~~~
In addition, methods are provided to calculate an angle / axis pair,
Euler angles, or rotation matrix from a [Quaternion][]:
* [Quaternion::ToAngleAxis()](@ref mathfu::Quaternion::ToAngleAxis)
* [Quaternion::ToEulerAngles()](@ref mathfu::Quaternion::ToEulerAngles)
* [Quaternion::ToMatrix()](@ref mathfu::Quaternion::ToMatrix)
For example, to calculate the angle and axis from a [Quaternion][]:
~~~{.cpp}
// Assuming "quaternion" is an existing float quaternion.
float angle;
mathfu::vec3 axis;
quaternion.ToAngleAxis(&angle, &axis);
~~~
To calculate a vector of Euler angles from a [Quaternion][]
~~~{.cpp}
// Assuming "quaternion" is an existing float quaternion.
mathfu::vec3 euler_angles = quaternion.ToEulerAngles();
~~~
Finally, to convert a [Quaternion][] to a rotation matrix:
~~~{.cpp}
// Assuming "quaternion" is an existing float quaternion.
mathfu::Matrix<float, 3> rotation_matrix = quaternion.ToMatrix();
~~~
# Manipulation {#mathfu_guide_quaternions_manipulation}
[Quaternion][] objects can be multiplied with each other to combine their
rotations.
For example, if a quaternion that rotates by PI / 2 radians around
the X axis is multiplied by itself it will result in a quaternion that rotates
by PI radians around the X axis:
~~~{.cpp}
mathfu::Quaternion<float> quaternion_pi_by_2_around_x =
mathfu::Quaternion<float>::FromAngleAxis(
M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
mathfu::Quaternion<float> quaternion_pi_around_x =
quaternion_pi_by_2_around_x * quaternion_pi_by_2_around_x;
~~~
It's also possible to multiply a [Quaternion][] with a scalar to scale the
existing rotation expressed by the object.
For example, if a quaternion that rotates by PI / 2 radians around
the X axis is multiplied by 2 it will result in a quaternion that rotates
by PI radians around the X axis:
~~~{.cpp}
mathfu::Quaternion<float> quaternion_pi_by_2_around_x =
mathfu::Quaternion<float>::FromAngleAxis(
M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
mathfu::Quaternion<float> quaternion_pi_around_x =
quaternion_pi_by_2_around_x * 2.0f;
~~~
In addition, [Quaternion][] provides the ability to perform
[spherical linear interpolation][] between two [Quaternion][] objects enabling
smooth transitions between rotations while avoiding [Gimbal lock][].
For example, the rotation half way between two quaternions can be calculated
by the following:
~~~{.cpp}
// Assuming "quaternion1" and "quaternion2" represent arbitrary rotations.
mathfu::Quaternion<float> quaternion3 =
mathfu::Quaternion<float>(quaternion1, quaternion2, 0.5f);
~~~
Finally, the inverse (opposite rotation) of a [Quaternion][] is calculated
using [Quaternion::Inverse()](@ref mathfu::Quaternion::Inverse). For example,
if a [Quaternion][] represents a rotation PI / 2 radians around the X axis
the rotation -PI / 2 degrees around the X axis can be calculated by:
~~~{.cpp}
const mathfu::Quaternion<float> quaternion =
mathfu::Quaternion<float>::FromAngleAxis(
M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
mathfu::Quaternion<float> inverse_rotation = quaternion.Inverse();
~~~
# Application {#mathfu_guide_quaternions_application}
A rotation expressed by a [Quaternion][] is applied to a [Vector][] by
multiplying the [Quaternion][] with the [Vector][].
For example, to rotate a [Vector][] by PI / 2 radians around the X axis:
~~~{.cpp}
const mathfu::vec3 vector(0.0f, 1.0f, 0.0f);
const mathfu::Quaternion<float> quaternion =
mathfu::Quaternion<float>::FromAngleAxis(
M_PI / 2.0f, mathfu::vec3(1.0f, 0.0f, 0.0f));
mathfu::vec3 rotated_vector = quaternion * vector;
~~~
When applying rotations to a large number of vectors or points
(e.g transforming a set of vertices) it is easier to use
[Quaternion::ToMatrix()](@ref mathfu::Quaternion::ToMatrix) to calculate
the rotation matrix and apply the same transform to the set of vectors.
<br>
[Quaternions]: http://en.wikipedia.org/wiki/Quaternion
[this description]: http://en.wikipedia.org/wiki/Quaternion
[Gimbal lock]: http://en.wikipedia.org/wiki/Gimbal_lock
[spherical linear interpolation]: http://en.wikipedia.org/wiki/Slerp
[Quaternion]: @ref mathfu::Quaternion
[MathFu]: @ref mathfu_overview
[Matrix]: @ref mathfu::Matrix
[Vector]: @ref mathfu::Vector

View File

@ -0,0 +1,113 @@
Utilities {#mathfu_guide_utilities}
=========
# Memory Allocation {#mathfu_guide_utilities_allocation}
[MathFu][]'s use of [SIMD][] instructions provides significant performance
gains in many use cases. However, some architectures have memory
alignment requirements for data used by [SIMD][] operations (e.g [SIMD][]
data structures must be 16-byte aligned on x86). Some STL implementations do
not respect data type alignment which makes it more difficult to respect the
[SIMD][] memory alignment requirements.
In order to adhere to [SIMD][] alignment requirements, [MathFu][] provides a
dynamic memory allocator [AllocateAligned()][] which ensures data is correctly
aligned. Memory allocated by [AllocateAligned()][] **must** be deallocated
using [FreeAligned()][], for example:
~~~{.cpp}
void *memory = mathfu::AllocateAligned(32);
mathfu::FreeAligned(memory);
~~~
The [simd_allocator](@ref mathfu::simd_allocator) class is provided to perform
aligned memory allocation with STL classes like std::vector. For example, the
following constructs a vector of `vec4` which uses the aligned memory
allocator:
~~~{.cpp}
std::vector<vec4, mathfu::simd_allocator<mathfu::vec4>> myvector;
~~~
The aligned memory allocator uses [MATHFU_ALIGNMENT](@ref MATHFU_ALIGNMENT)
bytes of additional memory per allocation. If the additional memory usage
per allocation is acceptable for an application, the most simple solution
is to override the global `new` and `delete` operators by adding
[MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE](@ref MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE)
to the source file containing an application's entry point (e.g `main.cpp`):
~~~{.cpp}
#include "mathfu/utilities.h"
MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
int main(int argc, char *argv[]) {
// The application.
return 0;
}
~~~
# Miscellaneous Functions {#mathfu_guide_utilities_misc}
[Clamp](@ref mathfu_Clamp) is used to clamp a value within a specified
range. For example:
~~~{.cpp}
float x = 1.0f;
z = mathfu::Clamp(x, 1.0f, 2.0f); // z = 1.0
z = mathfu::Clamp(x, 1.5f, 2.0f); // z = 1.5
z = mathfu::Clamp(x, 0.0f, 0.5f); // z = 0.5
~~~
[Lerp](@ref mathfu_Lerp) linearly interpolates between two values of an
arbitrary type in a specified range. For example, an object whose position is
specified by a [Vector][] could be moved over a range as time elapses:
~~~{.cpp}
const mathfu::vec2 start(2.0f, 3.0f);
const mathfu::vec2 end(10.0f, 0.0f);
// Update the position of an object every 100ms.
for (float time = 0.0f; time < 1.1f; time += 0.1f) {
mathfu::vec2 position = mathfu::Lerp(start, end, time);
// Draw object.
// Wait 100ms.
}
~~~
## Random Number Generation {#mathfu_guide_utilities_random}
[Random()][] generates pseudo random floating point numbers using `rand()`
from the C standard library. For example, the following generates 3 random
numbers:
~~~{.cpp}
float value1, value2, value2;
value1 = mathfu::Random<float>();
value2 = mathfu::Random<float>();
value3 = mathfu::Random<float>();
~~~
[Random()][] is used by [RandomRange()](@ref mathfu_RandomRange) to generate
a random number within a symmetric range. For example, to generate a random
value between -10.0f..10.0f:
~~~{.cpp}
float random_value = mathfu::RandomRange(10.0f);
~~~
Finally, [RandomInRange](@ref mathfu_RandomInRange) can be used to generate
a random number within an arbitrary range. For example, to generate a random
value between 5.0f..7.0f:
~~~{.cpp}
float random_value = mathfu::RandomInRange(5.0f, 7.0f);
~~~
<br>
[AllocateAligned()]: @ref mathfu_AllocateAligned
[FreeAligned()]: @ref mathfu_FreeAligned
[MathFu]: @ref mathfu_overview
[Random()]: @ref mathfu_Random
[SIMD]: http://en.wikipedia.org/wiki/SIMD
[Vector]: @ref mathfu::Vector

View File

@ -0,0 +1,272 @@
Vectors {#mathfu_guide_vectors}
=======
Vectors consist of a set of elements (usually floating point or integer
scalars) that are regularly used to describe a point in space or a direction.
For more information see this description of
[Euclidiean Vectors](http://en.wikipedia.org/wiki/Euclidean_vector).
The [MathFu][] [Vector][] class is a template declared in
[mathfu/vector.h](@ref mathfu/vector.h) which has been specialized and
optimized for regularly used cases. Implementing [Vector][] as a template
reduces code duplication, provides compile time optimization opportunities
through specialization and allows users to use the class with any scalar
type.
# Declaration {#mathfu_guide_vectors_declaration}
[Vector][] template takes two arguments: the type and number of elements in
the [Vector][].
For example, a 2-dimensional floating point vector variable is declared using
the following:
~~~{.cpp}
mathfu::Vector<float, 2> vector;
~~~
To eliminate the need for explicit template instantiation, [GLSL][] style
`typedef`s are provided in
[mathfu/glsl_mappings.h](@ref mathfu/glsl_mappings.h). Using a [GLSL][]
style `typedef` a 2-dimensional floating point vector variable is declared
using the following:
~~~{.cpp}
math::vec2 vector;
~~~
## Initialization {#mathfu_guide_vectors_initialization}
For efficiency, [Vector][] is uninitialized when constructed. Constructors
are provided for common vector sizes that allow initialization on construction:
~~~{.cpp}
mathfu::vec2 vector(1.0f, 2.0f);
~~~
It's also possible to initialize a [Vector][] with another instance:
~~~{.cpp}
mathfu::vec2 vector1(1.0f, 2.0f);
mathfu::vec2 vector2(vector1);
~~~
This can also be achieved with:
~~~{.cpp}
mathfu::vec2 vector1(1.0f, 2.0f);
mathfu::vec2 vector2 = vector1;
~~~
# Accessors {#mathfu_guide_vectors_accessors}
[Vector][] provides array and [GLSL][] style accessors. For example, to
read two elements from a 2-dimensional vector using array accessors:
~~~{.cpp}
const mathfu::vec2 vector(1.0f, 2.0f);
float x = vector[0];
float y = vector[1];
~~~
It's also possible to read elements from 2, 3 and 4-dimensional vectors using
[GLSL][] style accessors:
~~~{.cpp}
const mathfu::vec4 vector(1.0f, 2.0f, 3.0f, 4.0f);
float x = vector.x();
float y = vector.y();
float z = vector.z();
float w = vector.w();
~~~
Similar to [GLSL][], [Vector][] provides accessors which allow a subset of
elements to be accessed:
~~~{.cpp}
const mathfu::vec3 vector1(1.0f, 2.0f, 3.0f);
mathfu::vec3 xy = vector1.xy();
~~~
## Assignment {#mathfu_guide_vectors_assignment}
Individual elements returned by [Vector][]'s array accessors are references
that can be assigned values to update the contents of the class:
~~~{.cpp}
mathfu::vec2 vector(1.0f, 2.0f);
vector[0] = 3.0f;
vector[1] = 4.0f;
~~~
# Arithmetic {#mathfu_guide_vectors_arithmetic}
[Vector][] supports in-place and out-of-place arithmetic operators
(addition, subtraction, multiplication, division) that perform
component-wise operations.
For example, two vectors can be added together using the following:
~~~{.cpp}
const mathfu::vec2 vector1(1.0f, 2.0f), vector2(3.0f, 4.0f);
mathfu::vec2 vector3 = vector1 + vector2;
~~~
The above results in the values `(4.0f, 6.0f)` stored in `vector3` while
preserving the values of `vector1` and `vector2`.
The same can be achieved with an in-place addition which mutates `vector1`:
~~~{.cpp}
mathfu::vec2 vector1(1.0f, 2.0f);
const mathfu::vec2 vector2(3.0f, 4.0f);
vector1 += vector2;
~~~
Subtraction is similar to addition:
~~~{.cpp}
const mathfu::vec2 vector1(4.0f, 6.0f), vector2(3.0f, 4.0f);
mathfu::vec2 vector3 = vector2 - vector1;
~~~
Multiplication is performed component-wise, which means that each component
is multiplied with the same index component in the other [Vector][] involved
in the operation:
~~~{.cpp}
const mathfu::vec2 vector1(2.0f, 0.5f), vector2(3.0f, 10.0f);
vector3 = vector1 * vector2;
~~~
The above results in the values `(6.0f, 5.0f)` stored in `vector3` while
preserving the values of `vector1` and `vector2`.
Similar to the other operators, multiplication can be performed in place:
~~~{.cpp}
mathfu::vec2 vector1(2.0f, 0.5f);
const mathfu::vec2 vector2(3.0f, 10.0f);
vector1 *= vector2;
~~~
Division is also a component-wise operation:
~~~{.cpp}
const mathfu::vec2 vector1(4.0f, 4.0f), vector2(2.0f, 4.0f);
vector3 = vector1 / vector2;
~~~
The above results in the values `(2.0f, 1.0f)` stored in `vector3` while
preserving the values of `vector1` and `vector2`.
# Constants {#mathfu_guide_vectors_constants}
Commonly used constants are provided by
[mathfu/constants.h](@ref mathfu/constants.h). These values eliminate the need
to construct [Vector][] objects for common values like cardinal axes.
For example, the following initializes a 2-dimensional vector with the X-axis:
~~~{.cpp}
const mathfu::vec2 vector = mathfu::kAxisX2f;
~~~
# Geometric Operations {#mathfu_guide_vectors_geometric}
[Vector][] also provides functions for commonly used geometric operations
that are utilized by graphics and games developers.
For example, the length of a [Vector][] is calculated using
[Length()](@ref mathfu::Vector::Length):
~~~{.cpp}
const mathfu::vec2 vector(3.0f, 4.0f);
float length = vector.Length();
~~~
The projection of one [Vector][] onto another (dot product) can be calculated
using [DotProduct()](@ref mathfu::Vector::DotProduct). For example, the
following calculates the projection of a vector onto the X-axis:
~~~{.cpp}
float projection = mathfu::vec2::DotProduct(mathfu::vec2(5.0f, 2.0f),
mathfu::kAxisX2f);
~~~
It's possible to normalize (scale to a length of 1) a vector in-place using
[Normalize()](@ref mathfu::Vector::Normalize) or out-of-place using
[Normalized()](@ref mathfu::Vector::Normalized). For example, the following
normalizes the vector in-place:
~~~{.cpp}
mathfu::vec2 vector(3.0f, 4.0f);
vector.Normalize();
~~~
The cross product of two 3-dimensional [Vectors][] (the vector perpendicular
to two vectors) can be calculated using
[CrossProduct()](@ref mathfu::Vector::CrossProduct), for example:
~~~{.cpp}
mathfu::vec3 zaxis = mathfu::vec3::CrossProduct(mathfu::kAxisX3f,
mathfu::kAxisY3f);
~~~
Alternatively, to create three points and compute the normal of the plane
defined by the points use:
~~~{.cpp}
mathfu::vec3 point1(0.5f, 0.4f, 0.1f);
mathfu::vec3 point2(0.4f, 0.9f, 0.1f);
mathfu::vec3 point3(0.1f, 0.8f, 0.6f);
mathfu::vec3 vector1 = point2 - point1;
mathfu::vec3 vector2 = point3 - point1;
mathfu::vec3 normal = Vector<float, 3>::CrossProduct(vector2, vector1);
~~~
# Other Operations {#mathfu_guide_vectors_other}
In addition, to basic arithmetic and geometric operations, [Vector][] also
implements functions to perform the following:
* [Lerp](@ref mathfu::Vector::Lerp) to linearly interpolate between two
vectors.
* [RandomInRange](@ref mathfu::Vector::RandomInRange) to generate a vector
with random value for elements.
# Packing {#mathfu_guide_vectors_packing}
The size of the class can change based upon the [Build Configuration][] so it
should *not* be treated like a C style array. To serialize the class to a
flat array see [VectorPacked](@ref mathfu::VectorPacked).
For example, to pack (store) an unpacked to packed vector:
~~~{.cpp}
mathfu::vec3 vector(3.0f, 2.0f, 1.0f);
mathfu::vec3_packed packed = vector;
~~~
Since [VectorPacked][] is plain-old-data (POD) it can be cast to an array
of elements of the same type used by the [Vector][] so it's possible to use
an array of [VectorPacked][] data structures to contiguous arrays of data like
vertex buffers.
Similarly, [VectorPacked][] can be used to deserialize (load) data into
[Vector][]:
~~~{.cpp}
VectorPacked<float, 3> packed = { 3, 2, 1 };
Vector<float, 3> vector(packed);
~~~
<br>
[Build Configuration]: @ref mathfu_build_config
[MathFu]: @ref mathfu_overview
[GLSL]: http://www.opengl.org/documentation/glsl/
[Vector]: @ref mathfu::Vector
[VectorPacked]: @ref mathfu::VectorPacked

View File

@ -0,0 +1 @@
../../readme.md

View File

@ -0,0 +1,165 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_CONSTANTS_H
#define MATHFU_CONSTANTS_H
#include "mathfu/matrix.h"
#include "mathfu/quaternion.h"
#include "mathfu/vector.h"
namespace mathfu {
/// @file mathfu/constants.h
/// @brief Vector constants for specific dimensions.
/// @addtogroup mathfu_constants
///
/// It is preferable to use these constants rather than constructing them
/// when they're required. Construction most-likely slower than loading them
/// from memory.
/// <p>
/// For example, the following:<br>
/// <code>
/// lookat = mat4::LookAt(target, position, mathfu::kAxisY3f);
/// </code>
/// <br>is preferable to:<br>
/// <code>
/// lookat = mat4::LookAt(target, position,
/// mathfu::Vector<float, 3>(0.0f, 1.0f, 0.0f));
/// </code>
/// <br> in terms of efficiency and in addition to resulting in more concise
/// code.
/// </p>
///
/// Depending on your linker's sophistication and settings, these constants may
/// be duplicated in every compilation unit in which they're used. However,
/// most linkers should be able to detect and eliminate this duplication.
/// @addtogroup mathfu_constants
/// @{
/// 2-dimensional <code>float</code> Vector of zeros.
static const Vector<float, 2> kZeros2f(0.0f, 0.0f);
/// 2-dimensional <code>float</code> Vector of ones.
static const Vector<float, 2> kOnes2f(1.0f, 1.0f);
/// 2-dimensional <code>float</code> unit Vector pointing along the X axis.
static const Vector<float, 2> kAxisX2f(1.0f, 0.0f);
/// 2-dimensional <code>float</code> unit Vector pointing along the Y axis.
static const Vector<float, 2> kAxisY2f(0.0f, 1.0f);
/// 3-dimensional <code>float</code> Vector of zeros.
static const Vector<float, 3> kZeros3f(0.0f, 0.0f, 0.0f);
/// 3-dimensional <code>float</code> Vector of ones.
static const Vector<float, 3> kOnes3f(1.0f, 1.0f, 1.0f);
/// 3-dimensional <code>float</code> unit Vector pointing along the X axis.
static const Vector<float, 3> kAxisX3f(1.0f, 0.0f, 0.0f);
/// 3-dimensional <code>float</code> unit Vector pointing along the Y axis.
static const Vector<float, 3> kAxisY3f(0.0f, 1.0f, 0.0f);
/// 3-dimensional <code>float</code> unit Vector pointing along the Z axis.
static const Vector<float, 3> kAxisZ3f(0.0f, 0.0f, 1.0f);
/// 4-dimensional <code>float</code> Vector of zeros.
static const Vector<float, 4> kZeros4f(0.0f, 0.0f, 0.0f, 0.0f);
/// 4-dimensional <code>float</code> Vector of ones.
static const Vector<float, 4> kOnes4f(1.0f, 1.0f, 1.0f, 1.0f);
/// 4-dimensional <code>float</code> unit Vector pointing along the X axis.
static const Vector<float, 4> kAxisX4f(1.0f, 0.0f, 0.0f, 0.0f);
/// 4-dimensional <code>float</code> unit Vector pointing along the Y axis.
static const Vector<float, 4> kAxisY4f(0.0f, 1.0f, 0.0f, 0.0f);
/// 4-dimensional <code>float</code> unit Vector pointing along the Z axis.
static const Vector<float, 4> kAxisZ4f(0.0f, 0.0f, 1.0f, 0.0f);
/// 4-dimensional <code>float</code> unit Vector pointing along the W axis.
static const Vector<float, 4> kAxisW4f(0.0f, 0.0f, 0.0f, 1.0f);
/// 2-dimensional <code>double</code> Vector of zeros.
static const Vector<double, 2> kZeros2d(0.0, 0.0);
/// 2-dimensional <code>double</code> Vector of ones.
static const Vector<double, 2> kOnes2d(1.0, 1.0);
/// 2-dimensional <code>double</code> unit Vector pointing along the X axis.
static const Vector<double, 2> kAxisX2d(1.0, 0.0);
/// 2-dimensional <code>double</code> unit Vector pointing along the Y axis.
static const Vector<double, 2> kAxisY2d(0.0, 1.0);
/// 3-dimensional <code>double</code> Vector of zeros.
static const Vector<double, 3> kZeros3d(0.0, 0.0, 0.0);
/// 3-dimensional <code>double</code> Vector of ones.
static const Vector<double, 3> kOnes3d(1.0, 1.0, 1.0);
/// 3-dimensional <code>double</code> unit Vector pointing along the X axis.
static const Vector<double, 3> kAxisX3d(1.0, 0.0, 0.0);
/// 3-dimensional <code>double</code> unit Vector pointing along the Y axis.
static const Vector<double, 3> kAxisY3d(0.0, 1.0, 0.0);
/// 3-dimensional <code>double</code> unit Vector pointing along the Z axis.
static const Vector<double, 3> kAxisZ3d(0.0, 0.0, 1.0);
/// 4-dimensional <code>double</code> Vector of zeros.
static const Vector<double, 4> kZeros4d(0.0, 0.0, 0.0, 0.0);
/// 4-dimensional <code>double</code> Vector of ones.
static const Vector<double, 4> kOnes4d(1.0, 1.0, 1.0, 1.0);
/// 4-dimensional <code>double</code> unit Vector pointing along the X axis.
static const Vector<double, 4> kAxisX4d(1.0, 0.0, 0.0, 0.0);
/// 4-dimensional <code>double</code> unit Vector pointing along the Y axis.
static const Vector<double, 4> kAxisY4d(0.0, 1.0, 0.0, 0.0);
/// 4-dimensional <code>double</code> unit Vector pointing along the Z axis.
static const Vector<double, 4> kAxisZ4d(0.0, 0.0, 1.0, 0.0);
/// 4-dimensional <code>double</code> unit Vector pointing along the W axis.
static const Vector<double, 4> kAxisW4d(0.0, 0.0, 0.0, 1.0);
/// 2-dimensional <code>int</code> Vector of zeros.
static const Vector<int, 2> kOnes2i(1, 1);
/// 2-dimensional <code>int</code> Vector of ones.
static const Vector<int, 2> kZeros2i(0, 0);
/// 2-dimensional <code>int</code> unit Vector pointing along the X axis.
static const Vector<int, 2> kAxisX2i(1, 0);
/// 2-dimensional <code>int</code> unit Vector pointing along the Y axis.
static const Vector<int, 2> kAxisY2i(0, 1);
/// 3-dimensional <code>int</code> Vector of zeros.
static const Vector<int, 3> kZeros3i(0, 0, 0);
/// 3-dimensional <code>int</code> Vector of ones.
static const Vector<int, 3> kOnes3i(1, 1, 1);
/// 3-dimensional <code>int</code> unit Vector pointing along the X axis.
static const Vector<int, 3> kAxisX3i(1, 0, 0);
/// 3-dimensional <code>int</code> unit Vector pointing along the Y axis.
static const Vector<int, 3> kAxisY3i(0, 1, 0);
/// 3-dimensional <code>int</code> unit Vector pointing along the Z axis.
static const Vector<int, 3> kAxisZ3i(0, 0, 1);
/// 4-dimensional <code>int</code> Vector of zeros.
static const Vector<int, 4> kZeros4i(0, 0, 0, 0);
/// 4-dimensional <code>int</code> Vector of ones.
static const Vector<int, 4> kOnes4i(1, 1, 1 ,1);
/// 4-dimensional <code>int</code> unit Vector pointing along the X axis.
static const Vector<int, 4> kAxisX4i(1, 0, 0, 0);
/// 4-dimensional <code>int</code> unit Vector pointing along the Z axis.
static const Vector<int, 4> kAxisY4i(0, 1, 0, 0);
/// 4-dimensional <code>int</code> unit Vector pointing along the Y axis.
static const Vector<int, 4> kAxisZ4i(0, 0, 1, 0);
/// 4-dimensional <code>int</code> unit Vector pointing along the W axis.
static const Vector<int, 4> kAxisW4i(0, 0, 0, 1);
/// Quaternion Identity
static const Quaternion<float> kQuatIdentityf(1.0f, 0.0f, 0.0f, 0.0f);
/// Quaternion Identity
static const Quaternion<double> kQuatIdentityd(1.0, 0.0, 0.0, 0.0);
// An AffineTransform versoin of the mat4 Identity matrix.
static const AffineTransform kAffineIdentity(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f);
/// @}
} // namespace mathfu
#endif // MATHFU_CONSTANTS_H

View File

@ -0,0 +1,119 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_GLSL_MAPPINGS_H_
#define MATHFU_GLSL_MAPPINGS_H_
#include "mathfu/matrix.h"
#include "mathfu/quaternion.h"
#include "mathfu/rect.h"
#include "mathfu/vector.h"
/// @file mathfu/glsl_mappings.h
/// @brief GLSL compatible data types.
/// @addtogroup mathfu_glsl
///
/// To simplify the use of MathFu template classes and make it possible to
/// write code that looks similar to
/// <a href="http://www.opengl.org/documentation/glsl/">GLSL</a> in C++,
/// MathFu provides a set of data types that are similar in style to
/// GLSL Vector and Matrix data types.
/// @brief Namespace for MathFu library.
namespace mathfu {
/// @addtogroup mathfu_glsl
/// @{
/// 2-dimensional <code>float</code> Vector.
typedef Vector<float, 2> vec2;
/// 3-dimensional <code>float</code> Vector.
typedef Vector<float, 3> vec3;
/// 4-dimensional <code>float</code> Vector.
typedef Vector<float, 4> vec4;
/// 2-dimensional <code>int</code> Vector.
typedef Vector<int, 2> vec2i;
/// 3-dimensional <code>int</code> Vector.
typedef Vector<int, 3> vec3i;
/// 4-dimensional <code>int</code> Vector.
typedef Vector<int, 4> vec4i;
/// 2x2 <code>float</code> Matrix.
typedef Matrix<float, 2, 2> mat2;
/// 3x3 <code>float</code> Matrix.
typedef Matrix<float, 3, 3> mat3;
/// 3x3 <code>float</code> Matrix.
typedef Matrix<float, 4, 4> mat4;
/// 2-dimensional <code>float</code> packed Vector (VectorPacked).
typedef VectorPacked<float, 2> vec2_packed;
/// 3-dimensional <code>float</code> packed Vector (VectorPacked).
typedef VectorPacked<float, 3> vec3_packed;
/// 4-dimensional <code>float</code> packed Vector (VectorPacked).
typedef VectorPacked<float, 4> vec4_packed;
/// 2-dimensional <code>int</code> packed Vector (VectorPacked).
typedef VectorPacked<int, 2> vec2i_packed;
/// 3-dimensional <code>int</code> packed Vector (VectorPacked).
typedef VectorPacked<int, 3> vec3i_packed;
/// 4-dimensional <code>int</code> packed Vector (VectorPacked).
typedef VectorPacked<int, 4> vec4i_packed;
/// Float-based quaternion. Note that this is not technically
/// a GLES type, but is included for convenience.
typedef mathfu::Quaternion<float> quat;
/// Rect composed of type <code>float</code>.
typedef Rect<float> rectf;
/// Rect composed of type <code>double</code>.
typedef Rect<double> rectd;
/// Rect composed of type <code>int</code>.
typedef Rect<int> recti;
/// @brief Calculate the cross product of two 3-dimensional Vectors.
///
/// @param v1 Vector to multiply
/// @param v2 Vector to multiply
/// @return 3-dimensional vector that contains the result.
template<class T>
inline Vector<T, 3> cross(const Vector<T, 3>& v1, const Vector<T, 3>& v2) {
return Vector<T, 3>::CrossProduct(v1,v2);
}
/// @brief Calculate the dot product of two N-dimensional Vectors of any type.
///
/// @param v1 Vector to multiply
/// @param v2 Vector to multiply
/// @return Scalar dot product result.
template<class TV>
inline typename TV::Scalar dot(const TV& v1, const TV& v2) {
return TV::DotProduct(v1,v2);
}
/// @brief Normalize an N-dimensional Vector of an arbitrary type.
///
/// @param v1 Vector to normalize.
/// @return Normalized vector.
template<class TV>
inline TV normalize(const TV& v1) {
return v1.Normalized();
}
/// @}
} // namespace mathfu
#endif // MATHFU_GLSL_MAPPINGS_H_

View File

@ -0,0 +1,134 @@
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_HLSL_MAPPINGS_H_
#define MATHFU_HLSL_MAPPINGS_H_
#include "mathfu/matrix.h"
#include "mathfu/quaternion.h"
#include "mathfu/vector.h"
/// @file mathfu/hlsl_mappings.h
/// @brief HLSL compatible data types.
/// @addtogroup mathfu_hlsl
///
/// To simplify the use of MathFu template classes and make it possible to
/// write code that looks similar to
/// <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb509587(v=vs.85).aspx">HLSL</a> data types in C++,
/// MathFu provides a set of data types that are similar in style to
/// HLSL Vector and Matrix data types.
/// @brief Namespace for MathFu library.
namespace mathfu {
/// @addtogroup mathfu_hlsl
/// @{
/// Scalar unsigned integer
typedef unsigned int uint;
typedef unsigned int dword;
typedef unsigned short half;
/// 2-dimensional <code>float</code> Vector.
typedef Vector<float, 2> float2;
/// 3-dimensional <code>float</code> Vector.
typedef Vector<float, 3> float3;
/// 4-dimensional <code>float</code> Vector.
typedef Vector<float, 4> float4;
/// 2-dimensional <code>int</code> Vector.
typedef Vector<int, 2> int2;
/// 3-dimensional <code>int</code> Vector.
typedef Vector<int, 3> int3;
/// 4-dimensional <code>int</code> Vector.
typedef Vector<int, 4> int4;
/// 2-dimensional <code>uint</code> Vector.
typedef Vector<uint, 2> uint2;
/// 3-dimensional <code>uint</code> Vector.
typedef Vector<uint, 3> uint3;
/// 4-dimensional <code>uint</code> Vector.
typedef Vector<uint, 4> uint4;
/// 1x1 <code>float</code> Matrix.
typedef Matrix<float, 2, 2> float1x1;
/// 2x2 <code>float</code> Matrix.
typedef Matrix<float, 2, 2> float2x2;
/// 3x3 <code>float</code> Matrix.
typedef Matrix<float, 3, 3> float3x3;
/// 3x3 <code>float</code> Matrix.
typedef Matrix<float, 4, 4> float4x4;
/// 1x1 <code>double</code> Matrix.
typedef Matrix<double, 2, 2> double1x1;
/// 2x2 <code>double</code> Matrix.
typedef Matrix<double, 2, 2> double2x2;
/// 3x3 <code>double</code> Matrix.
typedef Matrix<double, 3, 3> double3x3;
/// 3x3 <code>double</code> Matrix.
typedef Matrix<double, 4, 4> double4x4;
/// 1x1 <code>int</code> Matrix.
typedef Matrix<int, 2, 2> int1x1;
/// 2x2 <code>int</code> Matrix.
typedef Matrix<int, 2, 2> int2x2;
/// 3x3 <code>int</code> Matrix.
typedef Matrix<int, 3, 3> int3x3;
/// 3x3 <code>int</code> Matrix.
typedef Matrix<int, 4, 4> int4x4;
/// 1x1 <code>int</code> Matrix.
typedef Matrix<int, 2, 2> uint1x1;
/// 2x2 <code>int</code> Matrix.
typedef Matrix<int, 2, 2> uint2x2;
/// 3x3 <code>int</code> Matrix.
typedef Matrix<int, 3, 3> uint3x3;
/// 3x3 <code>int</code> Matrix.
typedef Matrix<int, 4, 4> uint4x4;
/// @brief Calculate the cross product of two 3-dimensional Vectors.
///
/// @param v1 Vector to multiply
/// @param v2 Vector to multiply
/// @return 3-dimensional vector that contains the result.
template<class T>
inline Vector<T, 3> cross(const Vector<T, 3>& v1, const Vector<T, 3>& v2) {
return Vector<T, 3>::CrossProduct(v1,v2);
}
/// @brief Calculate the dot product of two N-dimensional Vectors of any type.
///
/// @param v1 Vector to multiply
/// @param v2 Vector to multiply
/// @return Scalar dot product result.
template<class TV>
inline typename TV::Scalar dot(const TV& v1, const TV& v2) {
return TV::DotProduct(v1,v2);
}
/// @brief Normalize an N-dimensional Vector of an arbitrary type.
///
/// @param v1 Vector to normalize.
/// @return Normalized vector.
template<class TV>
inline TV normalize(const TV& v1) {
return v1.Normalized();
}
/// @}
} // namespace mathfu
#endif // MATHFU_HLSL_MAPPINGS_H_

View File

@ -0,0 +1,35 @@
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Suppress pedantic warnings.
// To re-enable, include "mathfu/internal/disable_warnings_end.h".
//
// We need this to use anonymous unions and structs, which generate the
// the following warning in GCC and Clang,
// error: ISO C++ prohibits anonymous structs [-Werror=pedantic]
// The only way to suppress this warning is to turn off all pedantic warnings.
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
#endif // defined(__GNUC__)
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpedantic"
#pragma clang diagnostic ignored "-Wignored-qualifiers"
#endif // defined(__clang__)

View File

@ -0,0 +1,23 @@
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined(__clang__)
#pragma clang diagnostic pop
#endif // defined(__clang__)
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif // defined(__GNUC__)

View File

@ -0,0 +1,441 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_MATRIX_4X4_SIMD_H_
#define MATHFU_MATRIX_4X4_SIMD_H_
#include "mathfu/matrix.h"
#ifdef MATHFU_COMPILE_WITH_SIMD
#include "vectorial/simd4x4f.h"
#endif
/// @file mathfu/internal/matrix_4x4_simd.h MathFu Matrix<T, 4, 4>
/// Specialization
/// @brief 4x4 specialization of mathfu::Matrix for SIMD optimized builds.
/// @see mathfu::Matrix
namespace mathfu {
#ifdef MATHFU_COMPILE_WITH_SIMD
static const Vector<float, 4> kAffineWColumn(0.0f, 0.0f, 0.0f, 1.0f);
/// @cond MATHFU_INTERNAL
template <>
class Matrix<float, 4> {
public:
Matrix<float, 4>() {}
inline Matrix<float, 4>(const Matrix<float, 4>& m) {
data_.simd_matrix.x = m.data_.simd_matrix.x;
data_.simd_matrix.y = m.data_.simd_matrix.y;
data_.simd_matrix.z = m.data_.simd_matrix.z;
data_.simd_matrix.w = m.data_.simd_matrix.w;
}
explicit inline Matrix<float, 4>(const float& s) {
simd4f v = simd4f_create(s, s, s, s);
data_.simd_matrix = simd4x4f_create(v, v, v, v);
}
inline Matrix<float, 4>(const float& s00, const float& s10, const float& s20,
const float& s30, const float& s01, const float& s11,
const float& s21, const float& s31, const float& s02,
const float& s12, const float& s22, const float& s32,
const float& s03, const float& s13, const float& s23,
const float& s33) {
data_.simd_matrix = simd4x4f_create(
simd4f_create(s00, s10, s20, s30), simd4f_create(s01, s11, s21, s31),
simd4f_create(s02, s12, s22, s32), simd4f_create(s03, s13, s23, s33));
}
explicit inline Matrix<float, 4>(const float* m) {
data_.simd_matrix =
simd4x4f_create(simd4f_create(m[0], m[1], m[2], m[3]),
simd4f_create(m[4], m[5], m[6], m[7]),
simd4f_create(m[8], m[9], m[10], m[11]),
simd4f_create(m[12], m[13], m[14], m[15]));
}
inline Matrix<float, 4>(const Vector<float, 4>& column0,
const Vector<float, 4>& column1,
const Vector<float, 4>& column2,
const Vector<float, 4>& column3) {
#if defined(MATHFU_COMPILE_WITH_PADDING)
data_.simd_matrix = simd4x4f_create(column0.data_.simd, column1.data_.simd,
column2.data_.simd, column3.data_.simd);
#else
data_.simd_matrix = simd4x4f_create(
simd4f_create(column0[0], column0[1], column0[2], column0[3]),
simd4f_create(column1[0], column1[1], column1[2], column1[3]),
simd4f_create(column2[0], column2[1], column2[2], column2[3]),
simd4f_create(column3[0], column3[1], column3[2], column3[3]));
#endif // defined(MATHFU_COMPILE_WITH_PADDING)
}
explicit inline Matrix(const VectorPacked<float, 4>* const vectors) {
data_.simd_matrix.x = simd4f_uload4(vectors[0].data);
data_.simd_matrix.y = simd4f_uload4(vectors[1].data);
data_.simd_matrix.z = simd4f_uload4(vectors[2].data);
data_.simd_matrix.w = simd4f_uload4(vectors[3].data);
}
inline const float& operator()(const int i, const int j) const {
return FindElem(i, FindColumn(j));
}
inline float& operator()(const int i, const int j) {
return FindElem(i, FindColumn(j));
}
inline const float& operator()(const int i) const {
return this->operator[](i);
}
inline float& operator()(const int i) { return this->operator[](i); }
inline const float& operator[](const int i) const {
const int col = i / 4;
const int row = i % 4;
return FindElem(row, FindColumn(col));
}
inline float& operator[](const int i) {
const int col = i / 4;
const int row = i % 4;
return FindElem(row, FindColumn(col));
}
inline void Pack(VectorPacked<float, 4>* const vector) const {
simd4f_ustore4(data_.simd_matrix.x, vector[0].data);
simd4f_ustore4(data_.simd_matrix.y, vector[1].data);
simd4f_ustore4(data_.simd_matrix.z, vector[2].data);
simd4f_ustore4(data_.simd_matrix.w, vector[3].data);
}
inline Matrix<float, 4> operator-() const {
Matrix<float, 4> m(0.f);
simd4x4f_sub(&m.data_.simd_matrix, &data_.simd_matrix,
&m.data_.simd_matrix);
return m;
}
inline Matrix<float, 4> operator+(const Matrix<float, 4>& m) const {
Matrix<float, 4> return_m;
simd4x4f_add(&data_.simd_matrix, &m.data_.simd_matrix,
&return_m.data_.simd_matrix);
return return_m;
}
inline Matrix<float, 4> operator-(const Matrix<float, 4>& m) const {
Matrix<float, 4> return_m;
simd4x4f_sub(&data_.simd_matrix, &m.data_.simd_matrix,
&return_m.data_.simd_matrix);
return return_m;
}
inline Matrix<float, 4> operator*(const float& s) const {
Matrix<float, 4> m(s);
simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix,
&m.data_.simd_matrix);
return m;
}
inline Matrix<float, 4> operator/(const float& s) const {
Matrix<float, 4> m(1 / s);
simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix,
&m.data_.simd_matrix);
return m;
}
inline Vector<float, 3> operator*(const Vector<float, 3>& v) const {
Vector<float, 3> return_v;
Simd4fUnion temp_v;
#ifdef MATHFU_COMPILE_WITH_PADDING
temp_v.simd = v.data_.simd;
temp_v.float_array[3] = 1;
simd4x4f_matrix_vector_mul(&data_.simd_matrix, &temp_v.simd,
&return_v.data_.simd);
return_v *= (1 / return_v.data_.float_array[3]);
#else
temp_v.simd = simd4f_create(v[0], v[1], v[2], 1.0f);
simd4x4f_matrix_vector_mul(&data_.simd_matrix, &temp_v.simd, &temp_v.simd);
simd4f_mul(temp_v.simd, simd4f_splat(temp_v.float_array[3]));
MATHFU_VECTOR3_STORE3(temp_v.simd, return_v.data_);
#endif // MATHFU_COMPILE_WITH_PADDING
return return_v;
}
inline Vector<float, 4> operator*(const Vector<float, 4>& v) const {
Vector<float, 4> return_v;
simd4x4f_matrix_vector_mul(&data_.simd_matrix, &v.data_.simd,
&return_v.data_.simd);
return return_v;
}
inline Vector<float, 4> VecMatTimes(const Vector<float, 4>& v) const {
return Vector<float, 4>(
simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.x),
simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.y),
simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.z),
simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.w));
}
inline Matrix<float, 4> operator*(const Matrix<float, 4>& m) const {
Matrix<float, 4> return_m;
simd4x4f_matrix_mul(&data_.simd_matrix, &m.data_.simd_matrix,
&return_m.data_.simd_matrix);
return return_m;
}
inline Matrix<float, 4> Inverse() const {
Matrix<float, 4> return_m;
simd4x4f_inverse(&data_.simd_matrix, &return_m.data_.simd_matrix);
return return_m;
}
inline bool InverseWithDeterminantCheck(
Matrix<float, 4, 4>* const inverse) const {
return fabs(simd4f_get_x(simd4x4f_inverse(&data_.simd_matrix,
&inverse->data_.simd_matrix))) >=
Constants<float>::GetDeterminantThreshold();
}
/// Calculate the transpose of matrix.
/// @return The transpose of the specified matrix.
inline Matrix<float, 4, 4> Transpose() const {
Matrix<float, 4, 4> transpose;
simd4x4f_transpose(&data_.simd_matrix, &transpose.data_.simd_matrix);
return transpose;
}
inline Vector<float, 3> TranslationVector3D() const {
Vector<float, 3> return_v;
MATHFU_VECTOR3_STORE3(FindColumn(3).simd, return_v.data_);
return return_v;
}
inline Matrix<float, 4>& operator+=(const Matrix<float, 4>& m) {
simd4x4f_add(&data_.simd_matrix, &m.data_.simd_matrix, &data_.simd_matrix);
return *this;
}
inline Matrix<float, 4>& operator-=(const Matrix<float, 4>& m) {
simd4x4f_sub(&data_.simd_matrix, &m.data_.simd_matrix, &data_.simd_matrix);
return *this;
}
inline Matrix<float, 4>& operator*=(const float& s) {
Matrix<float, 4> m(s);
simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix, &data_.simd_matrix);
return *this;
}
inline Matrix<float, 4>& operator/=(const float& s) {
Matrix<float, 4> m(1 / s);
simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix, &data_.simd_matrix);
return *this;
}
inline Matrix<float, 4> operator*=(const Matrix<float, 4>& m) {
Matrix<float, 4> copy_of_this(*this);
simd4x4f_matrix_mul(&copy_of_this.data_.simd_matrix, &m.data_.simd_matrix,
&data_.simd_matrix);
return *this;
}
template <typename CompatibleT>
static inline Matrix<float, 4> FromType(const CompatibleT& compatible) {
return FromTypeHelper<float, 4, 4, CompatibleT>(compatible);
}
template <typename CompatibleT>
static inline CompatibleT ToType(const Matrix<float, 4>& m) {
return ToTypeHelper<float, 4, 4, CompatibleT>(m);
}
static inline Matrix<float, 4> OuterProduct(const Vector<float, 4>& v1,
const Vector<float, 4>& v2) {
Matrix<float, 4> m;
m.data_.simd_matrix =
simd4x4f_create(simd4f_mul(v1.data_.simd, simd4f_splat(v2[0])),
simd4f_mul(v1.data_.simd, simd4f_splat(v2[1])),
simd4f_mul(v1.data_.simd, simd4f_splat(v2[2])),
simd4f_mul(v1.data_.simd, simd4f_splat(v2[3])));
return m;
}
static inline Matrix<float, 4> HadamardProduct(const Matrix<float, 4>& m1,
const Matrix<float, 4>& m2) {
Matrix<float, 4> return_m;
simd4x4f_mul(&m1.data_.simd_matrix, &m2.data_.simd_matrix,
&return_m.data_.simd_matrix);
return return_m;
}
static inline Matrix<float, 4> Identity() {
Matrix<float, 4> return_m;
simd4x4f_identity(&return_m.data_.simd_matrix);
return return_m;
}
static inline Matrix<float, 4> FromTranslationVector(
const Vector<float, 3>& v) {
return Matrix<float, 4>(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, v[0], v[1],
v[2], 1);
}
static inline Matrix<float, 4> FromScaleVector(const Vector<float, 3>& v) {
return Matrix<float, 4>(v[0], 0, 0, 0, 0, v[1], 0, 0, 0, 0, v[2], 0, 0, 0,
0, 1);
}
static inline Matrix<float, 4> FromRotationMatrix(const Matrix<float, 3>& m) {
return Matrix<float, 4>(m[0], m[1], m[2], 0, m[3], m[4], m[5], 0, m[6],
m[7], m[8], 0, 0, 0, 0, 1);
}
/// @brief Constructs a Matrix<float, 4> from an AffineTransform.
///
/// @param affine An AffineTransform reference to be used to construct
/// a Matrix<float, 4> by adding in the 'w' row of [0, 0, 0, 1].
static inline Matrix<float, 4> FromAffineTransform(
const AffineTransform& affine) {
Matrix<float, 4> m;
m.data_.simd_matrix.x = simd4f_uload4(&affine[0]);
m.data_.simd_matrix.y = simd4f_uload4(&affine[4]);
m.data_.simd_matrix.z = simd4f_uload4(&affine[8]);
m.data_.simd_matrix.w = simd4f_uload4(&kAffineWColumn[0]);
return m.Transpose();
}
/// @brief Converts a Matrix<float, 4> into an AffineTransform.
///
/// @param m A Matrix<float, 4> reference to be converted into an
/// AffineTransform by dropping the fixed 'w' row.
///
/// @return Returns an AffineTransform that contains the essential
/// transformation data from the Matrix<float, 4>.
static inline AffineTransform ToAffineTransform(const Matrix<float, 4>& m) {
AffineTransform affine;
const Matrix<float, 4> mt = m.Transpose();
simd4f_ustore4(mt.data_.simd_matrix.x, &affine[0]);
simd4f_ustore4(mt.data_.simd_matrix.y, &affine[4]);
simd4f_ustore4(mt.data_.simd_matrix.z, &affine[8]);
return affine;
}
/// Create a 4x4 perpective matrix.
/// @handedness: 1.0f for RH, -1.0f for LH
static inline Matrix<float, 4, 4> Perspective(float fovy, float aspect,
float znear, float zfar,
float handedness = 1.0f) {
return PerspectiveHelper(fovy, aspect, znear, zfar, handedness);
}
/// Create a 4x4 orthographic matrix.
/// @param handedness 1.0f for RH, -1.0f for LH
static inline Matrix<float, 4, 4> Ortho(float left, float right, float bottom,
float top, float znear, float zfar,
float handedness = 1.0f) {
return OrthoHelper(left, right, bottom, top, znear, zfar, handedness);
}
/// Create a 3-dimensional camera matrix.
/// @param at The look-at target of the camera.
/// @param eye The position of the camera.
/// @param up The up vector in the world, for example (0, 1, 0) if the
/// @handedness: 1.0f for RH, -1.0f for LH
/// TODO: Change default handedness to 1.0f, to match Perspective().
/// y-axis is up.
static inline Matrix<float, 4, 4> LookAt(const Vector<float, 3>& at,
const Vector<float, 3>& eye,
const Vector<float, 3>& up,
float handedness = -1.0f) {
return LookAtHelper(at, eye, up, handedness);
}
/// @brief Get the 3D position in object space from a window coordinate.
///
/// @param window_coord The window coordinate. The z value is for depth.
/// A window coordinate on the near plane will have 0 as the z value.
/// And a window coordinate on the far plane will have 1 as the z value.
/// z value should be with in [0, 1] here.
/// @param model_view The Model View matrix.
/// @param projection The projection matrix.
/// @param window_width Width of the window.
/// @param window_height Height of the window.
/// @return the mapped 3D position in object space.
static inline Vector<float, 3> UnProject(
const Vector<float, 3>& window_coord,
const Matrix<float, 4, 4>& model_view,
const Matrix<float, 4, 4>& projection, const float window_width,
const float window_height) {
Vector<float, 3> result;
UnProjectHelper(window_coord, model_view, projection, window_width,
window_height, result);
return result;
}
// Dimensions of the matrix.
/// Number of rows in the matrix.
static const int kRows = 4;
/// Number of columns in the matrix.
static const int kColumns = 4;
/// Total number of elements in the matrix.
static const int kElements = 4 * 4;
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
private:
inline const Simd4fUnion& FindColumn(const int i) const {
return data_.simd4f_union_array[i];
}
inline Simd4fUnion& FindColumn(const int i) {
return data_.simd4f_union_array[i];
}
static inline const float& FindElem(const int i, const Simd4fUnion& column) {
return column.float_array[i];
}
static inline float& FindElem(const int i, Simd4fUnion& column) {
return column.float_array[i];
}
// Contents of the Matrix in different representations to work around
// strict aliasing rules.
union {
simd4x4f simd_matrix;
Simd4fUnion simd4f_union_array[4];
float float_array[16];
} data_;
};
inline Matrix<float, 4> operator*(const float& s, const Matrix<float, 4>& m) {
return m * s;
}
inline Vector<float, 4> operator*(const Vector<float, 4>& v,
const Matrix<float, 4>& m) {
return m.VecMatTimes(v);
}
/// @endcond
#endif // MATHFU_COMPILE_WITH_SIMD
} // namespace mathfu
#endif // MATHFU_MATRIX_4X4_SIMD_H_

View File

@ -0,0 +1,166 @@
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_INTERNAL_VECTOR_2_H_
#define MATHFU_INTERNAL_VECTOR_2_H_
#include "mathfu/vector.h"
namespace mathfu {
template <class T>
class Vector<T, 2> {
public:
typedef T Scalar;
static const int d = 2;
inline Vector() {}
inline Vector(const Vector<T, 2>& v) {
MATHFU_VECTOR_OPERATION(data_[i] = v.data_[i]);
}
template <typename U>
explicit inline Vector(const Vector<U, 2>& v) {
MATHFU_VECTOR_OPERATION(data_[i] = static_cast<T>(v[i]));
}
explicit inline Vector(const T& s) { MATHFU_VECTOR_OPERATION(data_[i] = s); }
explicit inline Vector(const T* a) {
MATHFU_VECTOR_OPERATION(data_[i] = a[i]);
}
inline Vector(const T& s1, const T& s2) {
x = s1;
y = s2;
}
explicit inline Vector(const VectorPacked<T, 2>& vector) {
MATHFU_VECTOR_OPERATION(data_[i] = vector.data[i]);
}
inline T& operator()(const int i) { return data_[i]; }
inline const T& operator()(const int i) const { return data_[i]; }
inline T& operator[](const int i) { return data_[i]; }
inline const T& operator[](const int i) const { return data_[i]; }
inline Vector<T, 2> xy() { return Vector<T, 2>(x, y); }
inline const Vector<T, 2> xy() const { return Vector<T, 2>(x, y); }
inline void Pack(VectorPacked<T, 2>* const vector) const {
MATHFU_VECTOR_OPERATION(vector->data[i] = data_[i]);
}
inline T LengthSquared() const { return LengthSquaredHelper(*this); }
inline T Length() const { return LengthHelper(*this); }
inline T Normalize() { return NormalizeHelper(*this); }
inline Vector<T, 2> Normalized() const { return NormalizedHelper(*this); }
template <typename CompatibleT>
static inline Vector<T, 2> FromType(const CompatibleT& compatible) {
return FromTypeHelper<T, d, CompatibleT>(compatible);
}
template <typename CompatibleT>
static inline CompatibleT ToType(const Vector<T, 2>& v) {
return ToTypeHelper<T, d, CompatibleT>(v);
}
static inline T DotProduct(const Vector<T, 2>& v1, const Vector<T, 2>& v2) {
return DotProductHelper(v1, v2);
}
static inline Vector<T, 2> HadamardProduct(const Vector<T, 2>& v1,
const Vector<T, 2>& v2) {
return HadamardProductHelper(v1, v2);
}
static inline Vector<T, 2> Lerp(const Vector<T, 2>& v1,
const Vector<T, 2>& v2, const T percent) {
return LerpHelper(v1, v2, percent);
}
static inline Vector<T, 2> RandomInRange(const Vector<T, 2>& min,
const Vector<T, 2>& max) {
return RandomInRangeHelper(min, max);
}
static inline Vector<T, 2> Max(const Vector<T, 2>& v1,
const Vector<T, 2>& v2) {
return MaxHelper(v1, v2);
}
static inline Vector<T, 2> Min(const Vector<T, 2>& v1,
const Vector<T, 2>& v2) {
return MinHelper(v1, v2);
}
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
#include "mathfu/internal/disable_warnings_begin.h"
union {
T data_[2];
struct {
T x;
T y;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
template <class T>
struct VectorPacked<T, 2> {
/// Create an uninitialized VectorPacked.
VectorPacked() {}
/// Create a VectorPacked from a Vector.
///
/// Both VectorPacked and Vector must have the same number of dimensions.
/// @param vector Vector to create the VectorPacked from.
explicit VectorPacked(const Vector<T, 2>& vector) { vector.Pack(this); }
/// Copy a Vector to a VectorPacked.
///
/// Both VectorPacked and Vector must have the same number of dimensions.
/// @param vector Vector to copy to the VectorPacked.
/// @returns A reference to this VectorPacked.
VectorPacked& operator=(const Vector<T, 2>& vector) {
vector.Pack(this);
return *this;
}
#include "mathfu/internal/disable_warnings_begin.h"
/// Elements of the packed vector one per dimension.
union {
T data[2];
struct {
T x;
T y;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
} // namespace mathfu
#endif // MATHFU_INTERNAL_VECTOR_2_H_

View File

@ -0,0 +1,253 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_VECTOR_2_SIMD_H_
#define MATHFU_VECTOR_2_SIMD_H_
#include "mathfu/internal/vector_2.h"
#include "mathfu/utilities.h"
#include <math.h>
/// @file mathfu/internal/vector_2_simd.h MathFu Vector<T, 2> Specialization
/// @brief 2-dimensional specialization of mathfu::Vector for SIMD optimized
/// builds.
/// @see mathfu::Vector
#if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) && defined(__ARM_NEON__)
#include <vectorial/simd2f.h>
#endif
namespace mathfu {
#if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) && defined(__ARM_NEON__)
/// @cond MATHFU_INTERNAL
template <>
class Vector<float, 2> {
public:
typedef float Scalar;
inline Vector() {}
inline Vector(const Vector<float, 2>& v) { simd = v.simd; }
explicit inline Vector(const Vector<int, 2>& v) {
data_[0] = static_cast<float>(v[0]);
data_[1] = static_cast<float>(v[1]);
}
explicit inline Vector(const simd2f& v) { simd = v; }
explicit inline Vector(const float& s) { simd = simd2f_create(s, s); }
inline Vector(const float& s1, const float& s2) {
simd = simd2f_create(s1, s2);
}
explicit inline Vector(const float* v) { simd = simd2f_uload2(v); }
explicit inline Vector(const VectorPacked<float, 2>& vector) {
simd = simd2f_uload2(vector.data);
}
inline float& operator()(const int i) { return data_[i]; }
inline const float& operator()(const int i) const { return data_[i]; }
inline float& operator[](const int i) { return data_[i]; }
inline const float& operator[](const int i) const { return data_[i]; }
inline void Pack(VectorPacked<float, 2>* const vector) const {
simd2f_ustore2(simd, vector->data);
}
inline Vector<float, 2> operator-() const {
return Vector<float, 2>(simd2f_sub(simd2f_zero(), simd));
}
inline Vector<float, 2> operator*(const Vector<float, 2>& v) const {
return Vector<float, 2>(simd2f_mul(simd, v.simd));
}
inline Vector<float, 2> operator/(const Vector<float, 2>& v) const {
return Vector<float, 2>(simd2f_div(simd, v.simd));
}
inline Vector<float, 2> operator+(const Vector<float, 2>& v) const {
return Vector<float, 2>(simd2f_add(simd, v.simd));
}
inline Vector<float, 2> operator-(const Vector<float, 2>& v) const {
return Vector<float, 2>(simd2f_sub(simd, v.simd));
}
inline Vector<float, 2> operator*(const float& s) const {
return Vector<float, 2>(simd2f_mul(simd, simd2f_splat(s)));
}
inline Vector<float, 2> operator/(const float& s) const {
return Vector<float, 2>(simd2f_div(simd, simd2f_splat(s)));
}
inline Vector<float, 2> operator+(const float& s) const {
return Vector<float, 2>(simd2f_add(simd, simd2f_splat(s)));
}
inline Vector<float, 2> operator-(const float& s) const {
return Vector<float, 2>(simd2f_sub(simd, simd2f_splat(s)));
}
inline Vector<float, 2>& operator*=(const Vector<float, 2>& v) {
simd = simd2f_mul(simd, v.simd);
return *this;
}
inline Vector<float, 2>& operator/=(const Vector<float, 2>& v) {
simd = simd2f_div(simd, v.simd);
return *this;
}
inline Vector<float, 2>& operator+=(const Vector<float, 2>& v) {
simd = simd2f_add(simd, v.simd);
return *this;
}
inline Vector<float, 2>& operator-=(const Vector<float, 2>& v) {
simd = simd2f_sub(simd, v.simd);
return *this;
}
inline Vector<float, 2>& operator*=(const float& s) {
simd = simd2f_mul(simd, simd2f_splat(s));
return *this;
}
inline Vector<float, 2>& operator/=(const float& s) {
simd = simd2f_div(simd, simd2f_splat(s));
return *this;
}
inline Vector<float, 2>& operator+=(const float& s) {
simd = simd2f_add(simd, simd2f_splat(s));
return *this;
}
inline Vector<float, 2>& operator-=(const float& s) {
simd = simd2f_sub(simd, simd2f_splat(s));
return *this;
}
inline bool operator==(const Vector<float, 2>& v) const {
for (int i = 0; i < 2; ++i) {
if ((*this)[i] != v[i]) return false;
}
return true;
}
inline bool operator!=(const Vector<float, 2>& v) const {
return !operator==(v);
}
inline float LengthSquared() const {
return simd2f_get_x(simd2f_dot2(simd, simd));
}
inline float Length() const { return simd2f_get_x(simd2f_length2(simd)); }
inline float Normalize() {
const float length = Length();
simd = simd2f_mul(simd, simd2f_splat(1 / length));
return length;
}
inline Vector<float, 2> Normalized() const {
return Vector<float, 2>(simd2f_normalize2(simd));
}
template <typename CompatibleT>
static inline Vector<float, 2> FromType(const CompatibleT& compatible) {
return FromTypeHelper<float, 2, CompatibleT>(compatible);
}
template <typename CompatibleT>
static inline CompatibleT ToType(const Vector<float, 2>& v) {
return ToTypeHelper<float, 2, CompatibleT>(v);
}
static inline float DotProduct(const Vector<float, 2>& v1,
const Vector<float, 2>& v2) {
return simd2f_get_x(simd2f_dot2(v1.simd, v2.simd));
}
static inline Vector<float, 2> HadamardProduct(const Vector<float, 2>& v1,
const Vector<float, 2>& v2) {
return Vector<float, 2>(simd2f_mul(v1.simd, v2.simd));
}
static inline Vector<float, 2> Lerp(const Vector<float, 2>& v1,
const Vector<float, 2>& v2,
float percent) {
const Vector<float, 2> percentv(percent);
const Vector<float, 2> one_minus_percent(
simd2f_sub(simd2f_splat(1.0f), percentv.simd));
return Vector<float, 2>(
simd2f_add(simd2f_mul(one_minus_percent.simd, v1.simd),
simd2f_mul(percentv.simd, v2.simd)));
}
/// Generates a random vector, where the range for each component is
/// bounded by min and max.
static inline Vector<float, 2> RandomInRange(const Vector<float, 2>& min,
const Vector<float, 2>& max) {
return Vector<float, 2>(mathfu::RandomInRange<float>(min[0], max[0]),
mathfu::RandomInRange<float>(min[1], max[1]));
}
static inline Vector<float, 2> Max(const Vector<float, 2>& v1,
const Vector<float, 2>& v2) {
return Vector<float, 2>(std::max(v1[0], v2[0]), std::max(v1[1], v2[1]));
}
static inline Vector<float, 2> Min(const Vector<float, 2>& v1,
const Vector<float, 2>& v2) {
return Vector<float, 2>(std::min(v1[0], v2[0]), std::min(v1[1], v2[1]));
}
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpedantic"
#endif // defined(__clang__)
union {
simd2f simd;
float data_[2];
struct {
float x;
float y;
};
};
#if defined(__clang__)
#pragma clang diagnostic pop
#endif // defined(__clang__)
};
/// @endcond
#endif // !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) &&
// defined(__ARM_NEON__)
} // namespace mathfu
#endif // MATHFU_VECTOR_2_SIMD_H_

View File

@ -0,0 +1,184 @@
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_INTERNAL_VECTOR_3_H_
#define MATHFU_INTERNAL_VECTOR_3_H_
#include "mathfu/vector.h"
namespace mathfu {
template <class T>
class Vector<T, 3> {
public:
typedef T Scalar;
static const int d = 3;
inline Vector() {}
inline Vector(const Vector<T, 3>& v) {
MATHFU_VECTOR_OPERATION(data_[i] = v.data_[i]);
}
template <typename U>
explicit inline Vector(const Vector<U, 3>& v) {
MATHFU_VECTOR_OPERATION(data_[i] = static_cast<T>(v[i]));
}
explicit inline Vector(const T& s) { MATHFU_VECTOR_OPERATION(data_[i] = s); }
explicit inline Vector(const T* a) {
MATHFU_VECTOR_OPERATION(data_[i] = a[i]);
}
inline Vector(const T& s1, const T& s2, const T& s3) {
x = s1;
y = s2;
z = s3;
}
inline Vector(const Vector<T, 2>& v12, const T& s3) {
x = v12[0];
y = v12[1];
z = s3;
}
explicit inline Vector(const VectorPacked<T, 3>& vector) {
MATHFU_VECTOR_OPERATION(data_[i] = vector.data[i]);
}
inline T& operator()(const int i) { return data_[i]; }
inline const T& operator()(const int i) const { return data_[i]; }
inline T& operator[](const int i) { return data_[i]; }
inline const T& operator[](const int i) const { return data_[i]; }
inline Vector<T, 3> xyz() { return Vector<T, 3>(x, y, z); }
inline const Vector<T, 3> xyz() const { return Vector<T, 3>(x, y, z); }
inline Vector<T, 2> xy() { return Vector<T, 2>(x, y); }
inline const Vector<T, 2> xy() const { return Vector<T, 2>(x, y); }
inline void Pack(VectorPacked<T, 3>* const vector) const {
MATHFU_VECTOR_OPERATION(vector->data[i] = data_[i]);
}
inline T LengthSquared() const { return LengthSquaredHelper(*this); }
inline T Length() const { return LengthHelper(*this); }
inline T Normalize() { return NormalizeHelper(*this); }
inline Vector<T, 3> Normalized() const { return NormalizedHelper(*this); }
template <typename CompatibleT>
static inline Vector<T, 3> FromType(const CompatibleT& compatible) {
return FromTypeHelper<T, d, CompatibleT>(compatible);
}
template <typename CompatibleT>
static inline CompatibleT ToType(const Vector<T, 3>& v) {
return ToTypeHelper<T, d, CompatibleT>(v);
}
static inline T DotProduct(const Vector<T, 3>& v1, const Vector<T, 3>& v2) {
return DotProductHelper(v1, v2);
}
static inline Vector<T, 3> HadamardProduct(const Vector<T, 3>& v1,
const Vector<T, 3>& v2) {
return HadamardProductHelper(v1, v2);
}
static inline Vector<T, 3> CrossProduct(const Vector<T, 3>& v1,
const Vector<T, 3>& v2) {
return CrossProductHelper(v1, v2);
}
static inline Vector<T, 3> Lerp(const Vector<T, 3>& v1,
const Vector<T, 3>& v2, const T percent) {
return LerpHelper(v1, v2, percent);
}
static inline Vector<T, 3> RandomInRange(const Vector<T, 3>& min,
const Vector<T, 3>& max) {
return RandomInRangeHelper(min, max);
}
static inline Vector<T, 3> Max(const Vector<T, 3>& v1,
const Vector<T, 3>& v2) {
return MaxHelper(v1, v2);
}
static inline Vector<T, 3> Min(const Vector<T, 3>& v1,
const Vector<T, 3>& v2) {
return MinHelper(v1, v2);
}
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
#include "mathfu/internal/disable_warnings_begin.h"
union {
T data_[3];
struct {
T x;
T y;
T z;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
template <class T>
struct VectorPacked<T, 3> {
/// Create an uninitialized VectorPacked.
VectorPacked() {}
/// Create a VectorPacked from a Vector.
///
/// Both VectorPacked and Vector must have the same number of dimensions.
/// @param vector Vector to create the VectorPacked from.
explicit VectorPacked(const Vector<T, 3>& vector) { vector.Pack(this); }
/// Copy a Vector to a VectorPacked.
///
/// Both VectorPacked and Vector must have the same number of dimensions.
/// @param vector Vector to copy to the VectorPacked.
/// @returns A reference to this VectorPacked.
VectorPacked& operator=(const Vector<T, 3>& vector) {
vector.Pack(this);
return *this;
}
#include "mathfu/internal/disable_warnings_begin.h"
/// Elements of the packed vector one per dimension.
union {
T data[3];
struct {
T x;
T y;
T z;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
} // namespace mathfu
#endif // MATHFU_INTERNAL_VECTOR_3_H_

View File

@ -0,0 +1,352 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_VECTOR_3_SIMD_H_
#define MATHFU_VECTOR_3_SIMD_H_
#include "mathfu/internal/vector_3.h"
#include "mathfu/utilities.h"
#include <math.h>
#ifdef MATHFU_COMPILE_WITH_SIMD
#include "vectorial/simd4f.h"
#endif
/// @file mathfu/internal/vector_3_simd.h MathFu Vector<T, 3> Specialization
/// @brief 3-dimensional specialization of mathfu::Vector for SIMD optimized
/// builds.
/// @see mathfu::Vector
/// @cond MATHFU_INTERNAL
/// Add macros to account for both the case where the vector is stored as a
/// simd intrinsic using 4 elements or as 3 values of type T.
/// MATHFU_VECTOR3_STORE3/MATHFU_VECTOR3_LOAD3 are additional operations used
/// to load/store the non simd values from and to simd datatypes. If intrinsics
/// are used these amount to essentially noops. MATHFU_VECTOR3_INIT3 either
/// creates a simd datatype if the intrinsic is used or sets the T values if
/// not.
#ifdef MATHFU_COMPILE_WITH_PADDING
#define MATHFU_VECTOR3_STORE3(simd_to_store, data) \
{ (data).simd = simd_to_store; }
#define MATHFU_VECTOR3_LOAD3(data) (data).simd
#define MATHFU_VECTOR3_INIT3(data, v1, v2, v3) \
{ (data).simd = simd4f_create(v1, v2, v3, 0); }
#else
#define MATHFU_VECTOR3_STORE3(simd_to_store, data) \
{ simd4f_ustore3(simd_to_store, (data).data_); }
#define MATHFU_VECTOR3_LOAD3(data) simd4f_uload3((data).data_)
#define MATHFU_VECTOR3_INIT3(data, v1, v2, v3) \
{ \
(data).data_[0] = v1; \
(data).data_[1] = v2; \
(data).data_[2] = v3; \
}
#endif // MATHFU_COMPILE_WITH_PADDING
/// @endcond
namespace mathfu {
#ifdef MATHFU_COMPILE_WITH_SIMD
/// @cond MATHFU_INTERNAL
// This class should remain plain old data.
template <>
class Vector<float, 3> {
public:
typedef float Scalar;
inline Vector() {}
inline Vector(const Vector<float, 3>& v) {
#ifdef MATHFU_COMPILE_WITH_PADDING
simd = v.simd;
#else
MATHFU_VECTOR3_INIT3(*this, v[0], v[1], v[2]);
#endif // MATHFU_COMPILE_WITH_PADDING
}
explicit inline Vector(const Vector<int, 3>& v) {
MATHFU_VECTOR3_INIT3(*this, static_cast<float>(v[0]),
static_cast<float>(v[1]), static_cast<float>(v[2]));
}
inline Vector(const simd4f& v) { MATHFU_VECTOR3_STORE3(v, *this); }
explicit inline Vector(const float& s) {
MATHFU_VECTOR3_INIT3(*this, s, s, s);
}
inline Vector(const float& v1, const float& v2, const float& v3) {
MATHFU_VECTOR3_INIT3(*this, v1, v2, v3);
}
inline Vector(const Vector<float, 2>& v12, const float& v3) {
MATHFU_VECTOR3_INIT3(*this, v12[0], v12[1], v3);
}
explicit inline Vector(const float* v) {
#ifdef MATHFU_COMPILE_WITH_PADDING
simd = simd4f_uload3(v);
#else
MATHFU_VECTOR3_INIT3(*this, v[0], v[1], v[2]);
#endif // MATHFU_COMPILE_WITH_PADDING
}
explicit inline Vector(const VectorPacked<float, 3>& vector) {
#ifdef MATHFU_COMPILE_WITH_PADDING
simd = simd4f_uload3(vector.data);
#else
MATHFU_VECTOR3_INIT3(*this, vector.data[0], vector.data[1], vector.data[2]);
#endif // MATHFU_COMPILE_WITH_PADDING
}
inline float& operator()(const int i) { return data_[i]; }
inline const float& operator()(const int i) const { return data_[i]; }
inline float& operator[](const int i) { return data_[i]; }
inline const float& operator[](const int i) const { return data_[i]; }
/// GLSL style multi-component accessors.
inline Vector<float, 2> xy() { return Vector<float, 2>(x, y); }
inline const Vector<float, 2> xy() const { return Vector<float, 2>(x, y); }
inline void Pack(VectorPacked<float, 3>* const vector) const {
#ifdef MATHFU_COMPILE_WITH_PADDING
simd4f_ustore3(simd, vector->data);
#else
vector->data[0] = data_[0];
vector->data[1] = data_[1];
vector->data[2] = data_[2];
#endif // MATHFU_COMPILE_WITH_PADDING
}
inline Vector<float, 3> operator-() const {
return Vector<float, 3>(
simd4f_sub(simd4f_zero(), MATHFU_VECTOR3_LOAD3(*this)));
}
inline Vector<float, 3> operator*(const Vector<float, 3>& v) const {
return Vector<float, 3>(
simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v)));
}
inline Vector<float, 3> operator/(const Vector<float, 3>& v) const {
return Vector<float, 3>(
simd4f_div(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v)));
}
inline Vector<float, 3> operator+(const Vector<float, 3>& v) const {
return Vector<float, 3>(
simd4f_add(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v)));
}
inline Vector<float, 3> operator-(const Vector<float, 3>& v) const {
return Vector<float, 3>(
simd4f_sub(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v)));
}
inline Vector<float, 3> operator*(const float& s) const {
return Vector<float, 3>(
simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s)));
}
inline Vector<float, 3> operator/(const float& s) const {
return Vector<float, 3>(
simd4f_div(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s)));
}
inline Vector<float, 3> operator+(const float& s) const {
return Vector<float, 3>(
simd4f_add(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s)));
}
inline Vector<float, 3> operator-(const float& s) const {
return Vector<float, 3>(
simd4f_sub(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s)));
}
inline Vector<float, 3>& operator*=(const Vector<float, 3>& v) {
*this = simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v));
return *this;
}
inline Vector<float, 3>& operator/=(const Vector<float, 3>& v) {
*this = simd4f_div(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v));
return *this;
}
inline Vector<float, 3>& operator+=(const Vector<float, 3>& v) {
*this = simd4f_add(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v));
return *this;
}
inline Vector<float, 3>& operator-=(const Vector<float, 3>& v) {
*this = simd4f_sub(MATHFU_VECTOR3_LOAD3(*this), MATHFU_VECTOR3_LOAD3(v));
return *this;
}
inline Vector<float, 3>& operator*=(const float& s) {
*this = simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s));
return *this;
}
inline Vector<float, 3>& operator/=(const float& s) {
*this = simd4f_div(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s));
return *this;
}
inline Vector<float, 3>& operator+=(const float& s) {
*this = simd4f_add(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s));
return *this;
}
inline Vector<float, 3>& operator-=(const float& s) {
*this = simd4f_sub(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(s));
return *this;
}
inline bool operator==(const Vector<float, 3>& v) const {
for (int i = 0; i < 3; ++i) {
if ((*this)[i] != v[i]) return false;
}
return true;
}
inline bool operator!=(const Vector<float, 3>& v) const {
return !operator==(v);
}
inline float LengthSquared() const {
return simd4f_dot3_scalar(MATHFU_VECTOR3_LOAD3(*this),
MATHFU_VECTOR3_LOAD3(*this));
}
inline float Length() const {
return simd4f_get_x(simd4f_length3(MATHFU_VECTOR3_LOAD3(*this)));
}
inline float Normalize() {
const float length = Length();
*this = simd4f_mul(MATHFU_VECTOR3_LOAD3(*this), simd4f_splat(1 / length));
return length;
}
inline Vector<float, 3> Normalized() const {
return Vector<float, 3>(simd4f_normalize3(MATHFU_VECTOR3_LOAD3(*this)));
}
template <typename CompatibleT>
static inline Vector<float, 3> FromType(const CompatibleT& compatible) {
return FromTypeHelper<float, 3, CompatibleT>(compatible);
}
template <typename CompatibleT>
static inline CompatibleT ToType(const Vector<float, 3>& v) {
return ToTypeHelper<float, 3, CompatibleT>(v);
}
static inline float DotProduct(const Vector<float, 3>& v1,
const Vector<float, 3>& v2) {
return simd4f_dot3_scalar(MATHFU_VECTOR3_LOAD3(v1),
MATHFU_VECTOR3_LOAD3(v2));
}
static inline Vector<float, 3> CrossProduct(const Vector<float, 3>& v1,
const Vector<float, 3>& v2) {
return Vector<float, 3>(
simd4f_cross3(MATHFU_VECTOR3_LOAD3(v1), MATHFU_VECTOR3_LOAD3(v2)));
}
static inline Vector<float, 3> HadamardProduct(const Vector<float, 3>& v1,
const Vector<float, 3>& v2) {
return Vector<float, 3>(
simd4f_mul(MATHFU_VECTOR3_LOAD3(v1), MATHFU_VECTOR3_LOAD3(v2)));
}
static inline Vector<float, 3> Lerp(const Vector<float, 3>& v1,
const Vector<float, 3>& v2,
float percent) {
const Vector<float, 3> percentv(percent);
const Vector<float, 3> one(1.0f);
const Vector<float, 3> one_minus_percent = one - percentv;
return Vector<float, 3>(simd4f_add(
simd4f_mul(MATHFU_VECTOR3_LOAD3(one_minus_percent),
MATHFU_VECTOR3_LOAD3(v1)),
simd4f_mul(MATHFU_VECTOR3_LOAD3(percentv), MATHFU_VECTOR3_LOAD3(v2))));
}
/// Generates a random vector, where the range for each component is
/// bounded by min and max.
static inline Vector<float, 3> RandomInRange(const Vector<float, 3>& min,
const Vector<float, 3>& max) {
return Vector<float, 3>(mathfu::RandomInRange<float>(min[0], max[0]),
mathfu::RandomInRange<float>(min[1], max[1]),
mathfu::RandomInRange<float>(min[2], max[2]));
}
static inline Vector<float, 3> Max(const Vector<float, 3>& v1,
const Vector<float, 3>& v2) {
#ifdef MATHFU_COMPILE_WITH_PADDING
return Vector<float, 3>(
simd4f_max(MATHFU_VECTOR3_LOAD3(v1), MATHFU_VECTOR3_LOAD3(v2)));
#else
return Vector<float, 3>(std::max(v1[0], v2[0]), std::max(v1[1], v2[1]),
std::max(v1[2], v2[2]));
#endif // MATHFU_COMPILE_WITH_PADDING
}
static inline Vector<float, 3> Min(const Vector<float, 3>& v1,
const Vector<float, 3>& v2) {
#ifdef MATHFU_COMPILE_WITH_PADDING
return Vector<float, 3>(
simd4f_min(MATHFU_VECTOR3_LOAD3(v1), MATHFU_VECTOR3_LOAD3(v2)));
#else
return Vector<float, 3>(std::min(v1[0], v2[0]), std::min(v1[1], v2[1]),
std::min(v1[2], v2[2]));
#endif // MATHFU_COMPILE_WITH_PADDING
}
template <class T, int rows, int cols>
friend class Matrix;
template <class T, int d>
friend class Vector;
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
#include "mathfu/internal/disable_warnings_begin.h"
union {
#ifdef MATHFU_COMPILE_WITH_PADDING
simd4f simd;
float data_[4];
#else
float data_[3];
#endif // MATHFU_COMPILE_WITH_PADDING
struct {
float x;
float y;
float z;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
/// @endcond
#endif // MATHFU_COMPILE_WITH_SIMD
} // namespace mathfu
#endif // MATHFU_VECTOR_3_SIMD_H_

View File

@ -0,0 +1,195 @@
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_INTERNAL_VECTOR_4_H_
#define MATHFU_INTERNAL_VECTOR_4_H_
// Prefer including vector.h directly, since it includes specializations.
#include "mathfu/vector.h"
namespace mathfu {
template <class T>
class Vector<T, 4> {
public:
typedef T Scalar;
static const int d = 4;
inline Vector() {}
inline Vector(const Vector<T, 4>& v) {
MATHFU_VECTOR_OPERATION(data_[i] = v.data_[i]);
}
template <typename U>
explicit inline Vector(const Vector<U, 4>& v) {
MATHFU_VECTOR_OPERATION(data_[i] = static_cast<T>(v[i]));
}
explicit inline Vector(const T& s) { MATHFU_VECTOR_OPERATION(data_[i] = s); }
explicit inline Vector(const T* a) {
MATHFU_VECTOR_OPERATION(data_[i] = a[i]);
}
inline Vector(const T& s1, const T& s2, const T& s3, const T& s4) {
x = s1;
y = s2;
z = s3;
w = s4;
}
inline Vector(const Vector<T, 3>& vector3, const T& value) {
x = vector3[0];
y = vector3[1];
z = vector3[2];
w = value;
}
inline Vector(const Vector<T, 2>& v12, const Vector<T, 2>& v34) {
x = v12[0];
y = v12[1];
z = v34[0];
w = v34[1];
}
explicit inline Vector(const VectorPacked<T, 4>& vector) {
MATHFU_VECTOR_OPERATION(data_[i] = vector.data[i]);
}
inline T& operator()(const int i) { return data_[i]; }
inline const T& operator()(const int i) const { return data_[i]; }
inline T& operator[](const int i) { return data_[i]; }
inline const T& operator[](const int i) const { return data_[i]; }
inline Vector<T, 3> xyz() { return Vector<T, 3>(x, y, z); }
inline const Vector<T, 3> xyz() const { return Vector<T, 3>(x, y, z); }
inline Vector<T, 2> xy() { return Vector<T, 2>(x, y); }
inline const Vector<T, 2> xy() const { return Vector<T, 2>(x, y); }
inline Vector<T, 2> zw() { return Vector<T, 2>(z, w); }
inline const Vector<T, 2> zw() const { return Vector<T, 2>(z, w); }
inline void Pack(VectorPacked<T, 4>* const vector) const {
MATHFU_VECTOR_OPERATION(vector->data[i] = data_[i]);
}
inline T LengthSquared() const { return LengthSquaredHelper(*this); }
inline T Length() const { return LengthHelper(*this); }
inline T Normalize() { return NormalizeHelper(*this); }
inline Vector<T, 4> Normalized() const { return NormalizedHelper(*this); }
template <typename CompatibleT>
static inline Vector<T, 4> FromType(const CompatibleT& compatible) {
return FromTypeHelper<T, d, CompatibleT>(compatible);
}
template <typename CompatibleT>
static inline CompatibleT ToType(const Vector<T, 4>& v) {
return ToTypeHelper<T, d, CompatibleT>(v);
}
static inline T DotProduct(const Vector<T, 4>& v1, const Vector<T, 4>& v2) {
return DotProductHelper(v1, v2);
}
static inline Vector<T, 4> HadamardProduct(const Vector<T, 4>& v1,
const Vector<T, 4>& v2) {
return HadamardProductHelper(v1, v2);
}
static inline Vector<T, 4> Lerp(const Vector<T, 4>& v1,
const Vector<T, 4>& v2, const T percent) {
return LerpHelper(v1, v2, percent);
}
static inline Vector<T, 4> RandomInRange(const Vector<T, 4>& min,
const Vector<T, 4>& max) {
return RandomInRangeHelper(min, max);
}
static inline Vector<T, 4> Max(const Vector<T, 4>& v1,
const Vector<T, 4>& v2) {
return MaxHelper(v1, v2);
}
static inline Vector<T, 4> Min(const Vector<T, 4>& v1,
const Vector<T, 4>& v2) {
return MinHelper(v1, v2);
}
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
#include "mathfu/internal/disable_warnings_begin.h"
union {
T data_[4];
struct {
T x;
T y;
T z;
T w;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
template <class T>
struct VectorPacked<T, 4> {
/// Create an uninitialized VectorPacked.
VectorPacked() {}
/// Create a VectorPacked from a Vector.
///
/// Both VectorPacked and Vector must have the same number of dimensions.
/// @param vector Vector to create the VectorPacked from.
explicit VectorPacked(const Vector<T, 4>& vector) { vector.Pack(this); }
/// Copy a Vector to a VectorPacked.
///
/// Both VectorPacked and Vector must have the same number of dimensions.
/// @param vector Vector to copy to the VectorPacked.
/// @returns A reference to this VectorPacked.
VectorPacked& operator=(const Vector<T, 4>& vector) {
vector.Pack(this);
return *this;
}
#include "mathfu/internal/disable_warnings_begin.h"
/// Elements of the packed vector one per dimension.
union {
T data[4];
struct {
T x;
T y;
T z;
T w;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
} // namespace mathfu
#endif // MATHFU_INTERNAL_VECTOR_4_H_

View File

@ -0,0 +1,283 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_VECTOR_4_SIMD_H_
#define MATHFU_VECTOR_4_SIMD_H_
#include "mathfu/internal/vector_4.h"
#include "mathfu/utilities.h"
#include <math.h>
#ifdef MATHFU_COMPILE_WITH_SIMD
#include "vectorial/simd4f.h"
#endif
/// @file mathfu/internal/vector_4_simd.h MathFu Vector<T, 4> Specialization
/// @brief 4-dimensional specialization of mathfu::Vector for SIMD optimized
/// builds.
/// @see mathfu::Vector
namespace mathfu {
#ifdef MATHFU_COMPILE_WITH_SIMD
template <>
class Vector<float, 4> {
public:
typedef float Scalar;
inline Vector() {}
inline Vector(const Vector<float, 4>& v) { simd = v.simd; }
explicit inline Vector(const Vector<int, 4>& v) {
data_[0] = static_cast<float>(v[0]);
data_[1] = static_cast<float>(v[1]);
data_[2] = static_cast<float>(v[2]);
data_[3] = static_cast<float>(v[3]);
}
explicit inline Vector(const simd4f& v) { simd = v; }
explicit inline Vector(const float& s) { simd = simd4f_splat(s); }
inline Vector(const float& s1, const float& s2, const float& s3,
const float& s4) {
simd = simd4f_create(s1, s2, s3, s4);
}
explicit inline Vector(const float* v) { simd = simd4f_uload4(v); }
inline Vector(const Vector<float, 3>& vector3, const float& value) {
#ifdef MATHFU_COMPILE_WITH_PADDING
simd = vector3.simd;
(*this)[3] = value;
#else
simd = simd4f_create(vector3[0], vector3[1], vector3[2], value);
#endif // MATHFU_COMPILE_WITH_PADDING
}
inline Vector(const Vector<float, 2>& vector12,
const Vector<float, 2>& vector34) {
simd = simd4f_create(vector12[0], vector12[1], vector34[0], vector34[1]);
}
explicit inline Vector(const VectorPacked<float, 4>& vector) {
simd = simd4f_uload4(vector.data);
}
inline float& operator()(const int i) { return data_[i]; }
inline const float& operator()(const int i) const { return data_[i]; }
inline float& operator[](const int i) { return data_[i]; }
inline const float& operator[](const int i) const { return data_[i]; }
/// GLSL style multi-component accessors.
inline Vector<float, 3> xyz() { return Vector<float, 3>(x, y, z); }
inline const Vector<float, 3> xyz() const {
return Vector<float, 3>(x, y, z);
}
inline Vector<float, 2> xy() { return Vector<float, 2>(x, y); }
inline const Vector<float, 2> xy() const { return Vector<float, 2>(x, y); }
inline Vector<float, 2> zw() { return Vector<float, 2>(z, w); }
inline const Vector<float, 2> zw() const { return Vector<float, 2>(z, w); }
inline void Pack(VectorPacked<float, 4>* const vector) const {
simd4f_ustore4(simd, vector->data);
}
inline Vector<float, 4> operator-() const {
return Vector<float, 4>(simd4f_sub(simd4f_zero(), simd));
}
inline Vector<float, 4> operator*(const Vector<float, 4>& v) const {
return Vector<float, 4>(simd4f_mul(simd, v.simd));
}
inline Vector<float, 4> operator/(const Vector<float, 4>& v) const {
return Vector<float, 4>(simd4f_div(simd, v.simd));
}
inline Vector<float, 4> operator+(const Vector<float, 4>& v) const {
return Vector<float, 4>(simd4f_add(simd, v.simd));
}
inline Vector<float, 4> operator-(const Vector<float, 4>& v) const {
return Vector<float, 4>(simd4f_sub(simd, v.simd));
}
inline Vector<float, 4> operator*(const float& s) const {
return Vector<float, 4>(simd4f_mul(simd, simd4f_splat(s)));
}
inline Vector<float, 4> operator/(const float& s) const {
return Vector<float, 4>(simd4f_div(simd, simd4f_splat(s)));
}
inline Vector<float, 4> operator+(const float& s) const {
return Vector<float, 4>(simd4f_add(simd, simd4f_splat(s)));
}
inline Vector<float, 4> operator-(const float& s) const {
return Vector<float, 4>(simd4f_sub(simd, simd4f_splat(s)));
}
inline Vector<float, 4>& operator*=(const Vector<float, 4>& v) {
simd = simd4f_mul(simd, v.simd);
return *this;
}
inline Vector<float, 4>& operator/=(const Vector<float, 4>& v) {
simd = simd4f_div(simd, v.simd);
return *this;
}
inline Vector<float, 4>& operator+=(const Vector<float, 4>& v) {
simd = simd4f_add(simd, v.simd);
return *this;
}
inline Vector<float, 4>& operator-=(const Vector<float, 4>& v) {
simd = simd4f_sub(simd, v.simd);
return *this;
}
inline Vector<float, 4>& operator*=(const float& s) {
simd = simd4f_mul(simd, simd4f_splat(s));
return *this;
}
inline Vector<float, 4>& operator/=(const float& s) {
simd = simd4f_div(simd, simd4f_splat(s));
return *this;
}
inline Vector<float, 4>& operator+=(const float& s) {
simd = simd4f_add(simd, simd4f_splat(s));
return *this;
}
inline Vector<float, 4>& operator-=(const float& s) {
simd = simd4f_sub(simd, simd4f_splat(s));
return *this;
}
inline bool operator==(const Vector<float, 4>& v) const {
for (int i = 0; i < 4; ++i) {
if ((*this)[i] != v[i]) return false;
}
return true;
}
inline bool operator!=(const Vector<float, 4>& v) const {
return !operator==(v);
}
inline float LengthSquared() const {
return simd4f_get_x(simd4f_dot4(simd, simd));
}
inline float Length() const { return simd4f_get_x(simd4f_length4(simd)); }
inline float Normalize() {
const float length = Length();
simd = simd4f_mul(simd, simd4f_splat(1 / length));
return length;
}
inline Vector<float, 4> Normalized() const {
return Vector<float, 4>(simd4f_normalize4(simd));
}
template <typename CompatibleT>
static inline Vector<float, 4> FromType(const CompatibleT& compatible) {
return FromTypeHelper<float, 4, CompatibleT>(compatible);
}
template <typename CompatibleT>
static inline CompatibleT ToType(const Vector<float, 4>& v) {
return ToTypeHelper<float, 4, CompatibleT>(v);
}
static inline float DotProduct(const Vector<float, 4>& v1,
const Vector<float, 4>& v2) {
return simd4f_get_x(simd4f_dot4(v1.simd, v2.simd));
}
static inline Vector<float, 4> HadamardProduct(const Vector<float, 4>& v1,
const Vector<float, 4>& v2) {
return Vector<float, 4>(simd4f_mul(v1.simd, v2.simd));
}
static inline Vector<float, 4> Lerp(const Vector<float, 4>& v1,
const Vector<float, 4>& v2,
float percent) {
const Vector<float, 4> percentv(percent);
const Vector<float, 4> one(1.0f);
const Vector<float, 4> one_minus_percent = one - percentv;
return Vector<float, 4>(
simd4f_add(simd4f_mul(one_minus_percent.simd, v1.simd),
simd4f_mul(percentv.simd, v2.simd)));
}
/// Generates a random vector, where the range for each component is
/// bounded by min and max.
static inline Vector<float, 4> RandomInRange(const Vector<float, 4>& min,
const Vector<float, 4>& max) {
return Vector<float, 4>(mathfu::RandomInRange<float>(min[0], max[0]),
mathfu::RandomInRange<float>(min[1], max[1]),
mathfu::RandomInRange<float>(min[2], max[2]),
mathfu::RandomInRange<float>(min[3], max[3]));
}
static inline Vector<float, 4> Max(const Vector<float, 4>& v1,
const Vector<float, 4>& v2) {
return Vector<float, 4>(simd4f_max(v1.simd, v2.simd));
}
static inline Vector<float, 4> Min(const Vector<float, 4>& v1,
const Vector<float, 4>& v2) {
return Vector<float, 4>(simd4f_min(v1.simd, v2.simd));
}
template <class T, int rows, int cols>
friend class Matrix;
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
#include "mathfu/internal/disable_warnings_begin.h"
union {
simd4f simd;
float data_[4];
struct {
float x;
float y;
float z;
float w;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
/// @endcond
#endif // MATHFU_COMPILE_WITH_SIMD
} // namespace mathfu
#endif // MATHFU_VECTOR_4_SIMD_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_MATRIX_4X4_H_
#define MATHFU_MATRIX_4X4_H_
// Prefer including matrix.h directly, since it includes specializations.
#include "mathfu/matrix.h"
#endif // MATHFU_MATRIX_4X4_H_

View File

@ -0,0 +1,526 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_QUATERNION_H_
#define MATHFU_QUATERNION_H_
#ifdef _WIN32
#if !defined(_USE_MATH_DEFINES)
#define _USE_MATH_DEFINES // For M_PI.
#endif // !defined(_USE_MATH_DEFINES)
#endif // _WIN32
#include "mathfu/matrix.h"
#include "mathfu/vector.h"
#include <math.h>
/// @file mathfu/quaternion.h
/// @brief Quaternion class and functions.
/// @addtogroup mathfu_quaternion
///
/// MathFu provides a Quaternion class that utilizes SIMD optimized
/// Matrix and Vector classes.
namespace mathfu {
/// @addtogroup mathfu_quaternion
/// @{
/// @class Quaternion
///
/// @brief Stores a Quaternion of type T and provides a set of utility
/// operations on each Quaternion.
/// @tparam T Type of each element in the Quaternion.
template <class T>
class Quaternion {
public:
/// @brief Construct an uninitialized Quaternion.
inline Quaternion() {}
/// @brief Construct a Quaternion from a copy.
/// @param q Quaternion to copy.
inline Quaternion(const Quaternion<T>& q) {
s_ = q.s_;
v_ = q.v_;
}
/// @brief Construct a Quaternion using scalar values to initialize each
/// element.
///
/// @param s1 Scalar component.
/// @param s2 First element of the Vector component.
/// @param s3 Second element of the Vector component.
/// @param s4 Third element of the Vector component.
inline Quaternion(const T& s1, const T& s2, const T& s3, const T& s4) {
s_ = s1;
v_ = Vector<T, 3>(s2, s3, s4);
}
/// @brief Construct a quaternion from a scalar and 3-dimensional Vector.
///
/// @param s1 Scalar component.
/// @param v1 Vector component.
inline Quaternion(const T& s1, const Vector<T, 3>& v1) {
s_ = s1;
v_ = v1;
}
/// @brief Return the scalar component of the quaternion.
///
/// @return The scalar component
inline T& scalar() { return s_; }
/// @brief Return the scalar component of the quaternion.
///
/// @return The scalar component
inline const T& scalar() const { return s_; }
/// @brief Set the scalar component of the quaternion.
///
/// @param s Scalar component.
inline void set_scalar(const T& s) { s_ = s; }
/// @brief Return the vector component of the quaternion.
///
/// @return The scalar component
inline Vector<T, 3>& vector() { return v_; }
/// @brief Return the vector component of the quaternion.
///
/// @return The scalar component
inline const Vector<T, 3>& vector() const { return v_; }
/// @brief Set the vector component of the quaternion.
///
/// @param v Vector component.
inline void set_vector(const Vector<T, 3>& v) { v_ = v; }
/// @brief Calculate the inverse Quaternion.
///
/// This calculates the inverse such that <code>(q * q).Inverse()</code>
/// is the identity.
///
/// @return Quaternion containing the result.
inline Quaternion<T> Inverse() const { return Quaternion<T>(s_, -v_); }
/// @brief Multiply this Quaternion with another Quaternion.
///
/// @note This is equivalent to
/// <code>FromMatrix(ToMatrix() * q.ToMatrix()).</code>
/// @param q Quaternion to multiply with.
/// @return Quaternion containing the result.
inline Quaternion<T> operator*(const Quaternion<T>& q) const {
return Quaternion<T>(
s_ * q.s_ - Vector<T, 3>::DotProduct(v_, q.v_),
s_ * q.v_ + q.s_ * v_ + Vector<T, 3>::CrossProduct(v_, q.v_));
}
/// @brief Multiply this Quaternion by a scalar.
///
/// This multiplies the angle of the rotation by a scalar factor.
/// @param s1 Scalar to multiply with.
/// @return Quaternion containing the result.
inline Quaternion<T> operator*(const T& s1) const {
T angle;
Vector<T, 3> axis;
ToAngleAxis(&angle, &axis);
angle *= s1;
return Quaternion<T>(cos(0.5f * angle),
axis.Normalized() * static_cast<T>(sin(0.5f * angle)));
}
/// @brief Multiply a Vector by this Quaternion.
///
/// This will rotate the specified vector by the rotation specified by this
/// Quaternion.
///
/// @param v1 Vector to multiply by this Quaternion.
/// @return Rotated Vector.
inline Vector<T, 3> operator*(const Vector<T, 3>& v1) const {
T ss = s_ + s_;
return ss * Vector<T, 3>::CrossProduct(v_, v1) + (ss * s_ - 1) * v1 +
2 * Vector<T, 3>::DotProduct(v_, v1) * v_;
}
/// @brief Normalize this quaterion (in-place).
///
/// @return Length of the quaternion.
inline T Normalize() {
T length = sqrt(s_ * s_ + Vector<T, 3>::DotProduct(v_, v_));
T scale = (1 / length);
s_ *= scale;
v_ *= scale;
return length;
}
/// @brief Calculate the normalized version of this quaternion.
///
/// @return The normalized quaternion.
inline Quaternion<T> Normalized() const {
Quaternion<T> q(*this);
q.Normalize();
return q;
}
/// @brief Convert this Quaternion to an Angle and axis.
///
/// The returned angle is the size of the rotation in radians about the
/// axis represented by this Quaternion.
///
/// @param angle Receives the angle.
/// @param axis Receives the normalized axis.
inline void ToAngleAxis(T* angle, Vector<T, 3>* axis) const {
*axis = s_ > 0 ? v_ : -v_;
*angle = 2 * atan2(axis->Normalize(), s_ > 0 ? s_ : -s_);
}
/// @brief Convert this Quaternion to 3 Euler Angles.
///
/// @return 3-dimensional Vector where each element is a angle of rotation
/// (in radians) around the x, y, and z axes.
inline Vector<T, 3> ToEulerAngles() const {
Matrix<T, 3> m(ToMatrix());
T cos2 = m[0] * m[0] + m[1] * m[1];
if (cos2 < 1e-6f) {
return Vector<T, 3>(
0,
m[2] < 0 ? static_cast<T>(0.5 * M_PI) : static_cast<T>(-0.5 * M_PI),
-std::atan2(m[3], m[4]));
} else {
return Vector<T, 3>(std::atan2(m[5], m[8]),
std::atan2(-m[2], std::sqrt(cos2)),
std::atan2(m[1], m[0]));
}
}
/// @brief Convert to a 3x3 Matrix.
///
/// @return 3x3 rotation Matrix.
inline Matrix<T, 3> ToMatrix() const {
const T x2 = v_[0] * v_[0], y2 = v_[1] * v_[1], z2 = v_[2] * v_[2];
const T sx = s_ * v_[0], sy = s_ * v_[1], sz = s_ * v_[2];
const T xz = v_[0] * v_[2], yz = v_[1] * v_[2], xy = v_[0] * v_[1];
return Matrix<T, 3>(1 - 2 * (y2 + z2), 2 * (xy + sz), 2 * (xz - sy),
2 * (xy - sz), 1 - 2 * (x2 + z2), 2 * (sx + yz),
2 * (sy + xz), 2 * (yz - sx), 1 - 2 * (x2 + y2));
}
/// @brief Convert to a 4x4 Matrix.
///
/// @return 4x4 transform Matrix.
inline Matrix<T, 4> ToMatrix4() const {
const T x2 = v_[0] * v_[0], y2 = v_[1] * v_[1], z2 = v_[2] * v_[2];
const T sx = s_ * v_[0], sy = s_ * v_[1], sz = s_ * v_[2];
const T xz = v_[0] * v_[2], yz = v_[1] * v_[2], xy = v_[0] * v_[1];
return Matrix<T, 4>(1 - 2 * (y2 + z2), 2 * (xy + sz), 2 * (xz - sy), 0.0f,
2 * (xy - sz), 1 - 2 * (x2 + z2), 2 * (sx + yz), 0.0f,
2 * (sy + xz), 2 * (yz - sx), 1 - 2 * (x2 + y2), 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
}
/// @brief Create a Quaternion from an angle and axis.
///
/// @param angle Angle in radians to rotate by.
/// @param axis Axis in 3D space to rotate around.
/// @return Quaternion containing the result.
static Quaternion<T> FromAngleAxis(const T& angle, const Vector<T, 3>& axis) {
const T halfAngle = static_cast<T>(0.5) * angle;
Vector<T, 3> localAxis(axis);
return Quaternion<T>(
cos(halfAngle),
localAxis.Normalized() * static_cast<T>(sin(halfAngle)));
}
/// @brief Create a quaternion from 3 euler angles.
///
/// @param angles 3-dimensional Vector where each element contains an
/// angle in radius to rotate by about the x, y and z axes.
/// @return Quaternion containing the result.
static Quaternion<T> FromEulerAngles(const Vector<T, 3>& angles) {
const Vector<T, 3> halfAngles(static_cast<T>(0.5) * angles[0],
static_cast<T>(0.5) * angles[1],
static_cast<T>(0.5) * angles[2]);
const T sinx = std::sin(halfAngles[0]);
const T cosx = std::cos(halfAngles[0]);
const T siny = std::sin(halfAngles[1]);
const T cosy = std::cos(halfAngles[1]);
const T sinz = std::sin(halfAngles[2]);
const T cosz = std::cos(halfAngles[2]);
return Quaternion<T>(cosx * cosy * cosz + sinx * siny * sinz,
sinx * cosy * cosz - cosx * siny * sinz,
cosx * siny * cosz + sinx * cosy * sinz,
cosx * cosy * sinz - sinx * siny * cosz);
}
/// @brief Create a quaternion from a rotation Matrix.
///
/// @param m 3x3 rotation Matrix.
/// @return Quaternion containing the result.
static Quaternion<T> FromMatrix(const Matrix<T, 3>& m) {
const T trace = m(0, 0) + m(1, 1) + m(2, 2);
if (trace > 0) {
const T s = sqrt(trace + 1) * 2;
const T oneOverS = 1 / s;
return Quaternion<T>(static_cast<T>(0.25) * s, (m[5] - m[7]) * oneOverS,
(m[6] - m[2]) * oneOverS, (m[1] - m[3]) * oneOverS);
} else if (m[0] > m[4] && m[0] > m[8]) {
const T s = sqrt(m[0] - m[4] - m[8] + 1) * 2;
const T oneOverS = 1 / s;
return Quaternion<T>((m[5] - m[7]) * oneOverS, static_cast<T>(0.25) * s,
(m[3] + m[1]) * oneOverS, (m[6] + m[2]) * oneOverS);
} else if (m[4] > m[8]) {
const T s = sqrt(m[4] - m[0] - m[8] + 1) * 2;
const T oneOverS = 1 / s;
return Quaternion<T>((m[6] - m[2]) * oneOverS, (m[3] + m[1]) * oneOverS,
static_cast<T>(0.25) * s, (m[5] + m[7]) * oneOverS);
} else {
const T s = sqrt(m[8] - m[0] - m[4] + 1) * 2;
const T oneOverS = 1 / s;
return Quaternion<T>((m[1] - m[3]) * oneOverS, (m[6] + m[2]) * oneOverS,
(m[5] + m[7]) * oneOverS, static_cast<T>(0.25) * s);
}
}
/// @brief Calculate the dot product of two Quaternions.
///
/// @param q1 First quaternion.
/// @param q2 Second quaternion
/// @return The scalar dot product of both Quaternions.
static inline T DotProduct(const Quaternion<T>& q1, const Quaternion<T>& q2) {
return q1.s_ * q2.s_ + Vector<T, 3>::DotProduct(q1.v_, q2.v_);
}
/// @brief Calculate the spherical linear interpolation between two
/// Quaternions.
///
/// @param q1 Start Quaternion.
/// @param q2 End Quaternion.
/// @param s1 The scalar value determining how far from q1 and q2 the
/// resulting quaternion should be. A value of 0 corresponds to q1 and a
/// value of 1 corresponds to q2.
/// @result Quaternion containing the result.
static inline Quaternion<T> Slerp(const Quaternion<T>& q1,
const Quaternion<T>& q2, const T& s1) {
if (q1.s_ * q2.s_ + Vector<T, 3>::DotProduct(q1.v_, q2.v_) > 0.999999f)
return Quaternion<T>(q1.s_ * (1 - s1) + q2.s_ * s1,
q1.v_ * (1 - s1) + q2.v_ * s1);
return q1 * ((q1.Inverse() * q2) * s1);
}
/// @brief Access an element of the quaternion.
///
/// @param i Index of the element to access.
/// @return A reference to the accessed data that can be modified by the
/// caller.
inline T& operator[](const int i) {
if (i == 0) return s_;
return v_[i - 1];
}
/// @brief Access an element of the quaternion.
///
/// @param i Index of the element to access.
/// @return A const reference to the accessed.
inline const T& operator[](const int i) const {
return const_cast<Quaternion<T>*>(this)->operator[](i);
}
/// @brief Returns a vector that is perpendicular to the supplied vector.
///
/// @param v1 An arbitrary vector
/// @return A vector perpendicular to v1. Normally this will just be
/// the cross product of v1, v2. If they are parallel or opposite though,
/// the routine will attempt to pick a vector.
static inline Vector<T, 3> PerpendicularVector(const Vector<T, 3>& v) {
// We start out by taking the cross product of the vector and the x-axis to
// find something parallel to the input vectors. If that cross product
// turns out to be length 0 (i. e. the vectors already lie along the x axis)
// then we use the y-axis instead.
Vector<T, 3> axis = Vector<T, 3>::CrossProduct(
Vector<T, 3>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0)),
v);
// We use a fairly high epsilon here because we know that if this number
// is too small, the axis we'll get from a cross product with the y axis
// will be much better and more numerically stable.
if (axis.LengthSquared() < static_cast<T>(0.05)) {
axis = Vector<T, 3>::CrossProduct(
Vector<T, 3>(static_cast<T>(0), static_cast<T>(1), static_cast<T>(0)),
v);
}
return axis;
}
/// @brief Returns the a Quaternion that rotates from start to end.
///
/// @param v1 The starting vector
/// @param v2 The vector to rotate to
/// @param preferred_axis the axis to use, if v1 and v2 are parallel.
/// @return A Quaternion describing the rotation from v1 to v2
/// See the comment on RotateFromToWithAxis for an explanation of the math.
static inline Quaternion<T> RotateFromToWithAxis(
const Vector<T, 3>& v1, const Vector<T, 3>& v2,
const Vector<T, 3>& preferred_axis) {
Vector<T, 3> start = v1.Normalized();
Vector<T, 3> end = v2.Normalized();
T dot_product = Vector<T, 3>::DotProduct(start, end);
// Any rotation < 0.1 degrees is treated as no rotation
// in order to avoid division by zero errors.
// So we early-out in cases where it's less then 0.1 degrees.
// cos( 0.1 degrees) = 0.99999847691
if (dot_product >= static_cast<T>(0.99999847691)) {
return Quaternion<T>::identity;
}
// If the vectors point in opposite directions, return a 180 degree
// rotation, on the axis that they asked for.
if (dot_product <= static_cast<T>(-0.99999847691)) {
return Quaternion<T>(static_cast<T>(0), preferred_axis);
}
// Degenerate cases have been handled, so if we're here, we have to
// actually compute the angle we want:
Vector<T, 3> cross_product = Vector<T, 3>::CrossProduct(start, end);
return Quaternion<T>(static_cast<T>(1.0) + dot_product, cross_product)
.Normalized();
}
/// @brief Returns the a Quaternion that rotates from start to end.
///
/// @param v1 The starting vector
/// @param v2 The vector to rotate to
/// @return A Quaternion describing the rotation from v1 to v2. In the case
/// where the vectors are parallel, it returns the identity. In the case
/// where
/// they point in opposite directions, it picks an arbitrary axis. (Since
/// there
/// are technically infinite possible quaternions to represent a 180 degree
/// rotation.)
///
/// The final equation used here is fairly elegant, but its derivation is
/// not obvious: We want to find the quaternion that represents the angle
/// between Start and End.
///
/// The angle can be expressed as a quaternion with the values:
/// angle: ArcCos(dotproduct(start, end) / (|start|*|end|)
/// axis: crossproduct(start, end).normalized * sin(angle/2)
///
/// or written as:
/// quaternion(cos(angle/2), axis * sin(angle/2))
///
/// Using the trig identity:
/// sin(angle * 2) = 2 * sin(angle) * cos*angle)
/// Via substitution, we can turn this into:
/// sin(angle/2) = 0.5 * sin(angle)/cos(angle/2)
///
/// Using this substitution, we get:
/// quaternion( cos(angle/2),
/// 0.5 * crossproduct(start, end).normalized
/// * sin(angle) / cos(angle/2))
///
/// If we scale the whole thing up by 2 * cos(angle/2) then we get:
/// quaternion(2 * cos(angle/2) * cos(angle/2),
/// crossproduct(start, end).normalized * sin(angle))
///
/// (Note that the quaternion is no longer normalized after this scaling)
///
/// Another trig identity:
/// cos(angle/2) = sqrt((1 + cos(angle) / 2)
///
/// Substituting this in, we can simplify the quaternion scalar:
///
/// quaternion(1 + cos(angle),
/// crossproduct(start, end).normalized * sin(angle))
///
/// Because cross(start, end) has a magnitude of |start|*|end|*sin(angle),
/// crossproduct(start,end).normalized
/// is equivalent to
/// crossproduct(start,end) / |start| * |end| * sin(angle)
/// So after that substitution:
///
/// quaternion(1 + cos(angle),
/// crossproduct(start, end) / (|start| * |end|))
///
/// dotproduct(start, end) has the value of |start| * |end| * cos(angle),
/// so by algebra,
/// cos(angle) = dotproduct(start, end) / (|start| * |end|)
/// we can replace our quaternion scalar here also:
///
/// quaternion(1 + dotproduct(start, end) / (|start| * |end|),
/// crossproduct(start, end) / (|start| * |end|))
///
/// If start and end are normalized, then |start| * |end| = 1, giving us a
/// final quaternion of:
///
/// quaternion(1 + dotproduct(start, end), crossproduct(start, end))
static inline Quaternion<T> RotateFromTo(const Vector<T, 3>& v1,
const Vector<T, 3>& v2) {
Vector<T, 3> start = v1.Normalized();
Vector<T, 3> end = v2.Normalized();
T dot_product = Vector<T, 3>::DotProduct(start, end);
// Any rotation < 0.1 degrees is treated as no rotation
// in order to avoid division by zero errors.
// So we early-out in cases where it's less then 0.1 degrees.
// cos( 0.1 degrees) = 0.99999847691
if (dot_product >= static_cast<T>(0.99999847691)) {
return Quaternion<T>::identity;
}
// If the vectors point in opposite directions, return a 180 degree
// rotation, on an arbitrary axis.
if (dot_product <= static_cast<T>(-0.99999847691)) {
return Quaternion<T>(0, PerpendicularVector(start));
}
// Degenerate cases have been handled, so if we're here, we have to
// actually compute the angle we want:
Vector<T, 3> cross_product = Vector<T, 3>::CrossProduct(start, end);
return Quaternion<T>(static_cast<T>(1.0) + dot_product, cross_product)
.Normalized();
}
/// @brief Contains a quaternion doing the identity transform.
static Quaternion<T> identity;
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
private:
T s_;
Vector<T, 3> v_;
};
template <typename T>
Quaternion<T> Quaternion<T>::identity = Quaternion<T>(1, 0, 0, 0);
/// @}
/// @addtogroup mathfu_quaternion
/// @{
/// @brief Multiply a Quaternion by a scalar.
///
/// This multiplies the angle of the rotation of the specified Quaternion
/// by a scalar factor.
/// @param s Scalar to multiply with.
/// @param q Quaternion to scale.
/// @return Quaternion containing the result.
///
/// @related Quaternion
template <class T>
inline Quaternion<T> operator*(const T& s, const Quaternion<T>& q) {
return q * s;
}
/// @}
} // namespace mathfu
#endif // MATHFU_QUATERNION_H_

View File

@ -0,0 +1,82 @@
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_RECT_H_
#define MATHFU_RECT_H_
#include "mathfu/vector.h"
namespace mathfu {
/// @addtogroup mathfu_rect
/// @{
/// @class Rect "mathfu/rect.h"
/// @brief Rect of type T containing position (pos) and width.
///
/// Rect contains two 2D <b>Vector</b>s of type <b>T</b> representing position
/// (pos) and size.
///
/// @tparam T type of Rect elements.
template <class T>
struct Rect {
Vector<T, 2> pos;
Vector<T, 2> size;
/// @brief Create a rect from a vector4 of the same type.
///
/// @param v Vector that the data will be copied from.
explicit Rect(const Vector<T, 4>& v)
: pos(v.x, v.y), size(v.z, v.w) {}
/// @brief Create a rect from x, y, width and height values.
///
/// @param x the given x value.
/// @param y the given y value.
/// @param width the given width value.
/// @param height the given height value.
inline Rect(T x = static_cast<T>(0), T y = static_cast<T>(0),
T width = static_cast<T>(0), T height = static_cast<T>(0))
: pos(x, y), size(width, height) {}
/// @brief Create a rect from two vector2 representing position and size.
///
/// @param pos Vector representing the position vector (x and y values).
/// @param size Vector represening the size vector (width and height values).
inline Rect(const Vector<T, 2>& pos, const Vector<T, 2>& size)
: pos(pos), size(size) {}
};
/// @}
/// @brief Check if two rects are identical.
///
/// @param r1 Rect to be tested.
/// @param r2 Other rect to be tested.
template <class T>
bool operator==(const Rect<T>& r1, const Rect<T>& r2) {
return (r1.pos == r2.pos && r1.size == r2.size);
}
/// @brief Check if two rects are <b>not</b> identical.
///
/// @param r1 Rect to be tested.
/// @param r2 Other rect to be tested.
template <class T>
bool operator!=(const Rect<T>& r1, const Rect<T>& r2) {
return !(r1 == r2);
}
} // namespace mathfu
#endif // MATHFU_RECT_H_

View File

@ -0,0 +1,618 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_UTILITIES_H_
#define MATHFU_UTILITIES_H_
#include <assert.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <algorithm>
#include <memory>
/// @file mathfu/utilities.h Utilities
/// @brief Utility macros and functions.
/// @addtogroup mathfu_build_config
///
/// By default MathFu will attempt to build with SIMD optimizations enabled
/// based upon the target architecture and compiler options. However, it's
/// possible to change the default build configuration using the following
/// macros:
///
/// @li @ref MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
/// @li @ref MATHFU_COMPILE_FORCE_PADDING
///
/// <table>
/// <tr>
/// <th>MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT</th>
/// <th>MATHFU_COMPILE_FORCE_PADDING</th>
/// <th>Configuration</th>
/// </tr>
/// <tr>
/// <td><em>undefined</em></td>
/// <td><em>undefined</em> or 1</td>
/// <td>Default build configuration, SIMD optimization is enabled based upon
/// the target architecture, compiler options and MathFu library
/// support.</td>
/// </tr>
/// <tr>
/// <td><em>undefined</em></td>
/// <td>0</td>
/// <td>If SIMD is supported, padding of data structures is disabled. See
/// @ref MATHFU_COMPILE_FORCE_PADDING for more information.</td>
/// </tr>
/// <tr>
/// <td><em>defined</em></td>
/// <td><em>undefined/0/1</em></td>
/// <td>Builds MathFu with explicit SIMD optimization disabled. The compiler
/// could still potentially optimize some code paths with SIMD
/// instructions based upon the compiler options.</td>
/// </tr>
/// </table>
#ifdef DOXYGEN
/// @addtogroup mathfu_build_config
/// @{
/// @def MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
/// @brief Disable SIMD build configuration.
///
/// When defined, this macro <b>disables</b> the default behavior of trying to
/// build the library with SIMD enabled based upon the target architecture
/// and compiler options.
///
/// To use this build option, this macro <b>must</b> be defined in all modules
/// of the project.
#define MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
/// @}
#endif // DOXYGEN
#if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT)
#if defined(__SSE__)
#define MATHFU_COMPILE_WITH_SIMD
#elif defined(__ARM_NEON__)
#define MATHFU_COMPILE_WITH_SIMD
#elif defined(_M_IX86_FP) // MSVC
#if _M_IX86_FP >= 1 // SSE enabled
#define MATHFU_COMPILE_WITH_SIMD
#endif // _M_IX86_FP >= 1
#endif
#endif // !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT)
#ifdef DOXYGEN
/// @addtogroup mathfu_build_config
/// @{
/// @def MATHFU_COMPILE_FORCE_PADDING
/// @brief Enable / disable padding of data structures.
///
/// By default, when @ref MATHFU_COMPILE_FORCE_PADDING is <b>not</b> defined,
/// data structures are padded when SIMD is enabled
/// (i.e when @ref MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT is also not defined).
///
/// If @ref MATHFU_COMPILE_FORCE_PADDING is defined as <b>1</b>, all data
/// structures are padded to a power of 2 size which enables more efficient
/// SIMD operations. This is the default build configuration when SIMD is
/// enabled.
///
/// If @ref MATHFU_COMPILE_FORCE_PADDING is defined as <b>0</b>, all data
/// structures are packed by the compiler (with no padding) even when the SIMD
/// build configuration is enabled. This build option can be useful in the
/// rare occasion an application is CPU memory bandwidth constrained, at the
/// expense of additional instructions to copy to / from SIMD registers.
///
/// To use this build option, this macro <b>must</b> be defined in all modules
/// of the project.
///
/// @see MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
#define MATHFU_COMPILE_FORCE_PADDING
/// @}
#endif // DOXYGEN
#ifdef MATHFU_COMPILE_WITH_SIMD
/// @cond MATHFU_INTERNAL
/// @addtogroup mathfu_build_config
/// @{
/// @def MATHFU_COMPILE_WITH_PADDING
/// @brief Enable padding of data structures to be efficient with SIMD.
///
/// When defined, this option enables padding of some data structures (e.g
/// @ref vec3) to be more efficient with SIMD operations. This option is
/// only applicable when @ref MATHFU_COMPILE_WITHOUT_SIMD is not defined and
/// the target architecture and compiler support SIMD.
///
/// To use this build option, this macro <b>must</b> be defined in all modules
/// of the project.
/// @see MATHFU_COMPILE_FORCE_PADDING
#define MATHFU_COMPILE_WITH_PADDING
/// @}
#if defined(MATHFU_COMPILE_FORCE_PADDING)
#if MATHFU_COMPILE_FORCE_PADDING == 1
#if !defined(MATHFU_COMPILE_WITH_PADDING)
#define MATHFU_COMPILE_WITH_PADDING
#endif // !defined(MATHFU_COMPILE_WITH_PADDING)
#else
#if defined(MATHFU_COMPILE_WITH_PADDING)
#undef MATHFU_COMPILE_WITH_PADDING
#endif // MATHFU_COMPILE_WITH_PADDING
#endif // MATHFU_COMPILE_FORCE_PADDING == 1
#endif // MATHFU_COMPILE_FORCE_PADDING
/// @endcond
#endif // MATHFU_COMPILE_WITH_SIMD
/// @addtogroup mathfu_version
/// @{
/// @def MATHFU_VERSION_MAJOR
/// @brief Major version number of the library.
/// @see kMathFuVersionString
#define MATHFU_VERSION_MAJOR 1
/// @def MATHFU_VERSION_MINOR
/// @brief Minor version number of the library.
/// @see kMathFuVersionString
#define MATHFU_VERSION_MINOR 1
/// @def MATHFU_VERSION_REVISION
/// @brief Revision number of the library.
/// @see kMathFuVersionString
#define MATHFU_VERSION_REVISION 0
/// @}
/// @cond MATHFU_INTERNAL
#define MATHFU_STRING_EXPAND(X) #X
#define MATHFU_STRING(X) MATHFU_STRING_EXPAND(X)
/// @endcond
/// @cond MATHFU_INTERNAL
// Generate string which contains build options for the library.
#if defined(MATHFU_COMPILE_WITH_SIMD)
#define MATHFU_BUILD_OPTIONS_SIMD "[simd]"
#else
#define MATHFU_BUILD_OPTIONS_SIMD "[no simd]"
#endif // defined(MATHFU_COMPILE_WITH_SIMD)
#if defined(MATHFU_COMPILE_WITH_PADDING)
#define MATHFU_BUILD_OPTIONS_PADDING "[padding]"
#else
#define MATHFU_BUILD_OPTIONS_PADDING "[no padding]"
#endif // defined(MATHFU_COMPILE_WITH_PADDING)
/// @endcond
/// @addtogroup mathfu_version
/// @{
/// @def MATHFU_BUILD_OPTIONS_STRING
/// @brief String that describes the library's build configuration.
#define MATHFU_BUILD_OPTIONS_STRING \
(MATHFU_BUILD_OPTIONS_SIMD " " MATHFU_BUILD_OPTIONS_PADDING)
/// @}
// Weak linkage is culled by VS & doesn't work on cygwin.
#if !defined(_WIN32) && !defined(__CYGWIN__)
extern volatile __attribute__((weak)) const char *kMathFuVersionString;
/// @addtogroup mathfu_version
/// @{
/// @var kMathFuVersionString
/// @brief String which identifies the current version of MathFu.
///
/// @ref kMathFuVersionString is used by Google developers to identify which
/// applications uploaded to Google Play are using this library. This allows
/// the development team at Google to determine the popularity of the library.
/// How it works: Applications that are uploaded to the Google Play Store are
/// scanned for this version string. We track which applications are using it
/// to measure popularity. You are free to remove it (of course) but we would
/// appreciate if you left it in.
///
/// @see MATHFU_VERSION_MAJOR
/// @see MATHFU_VERSION_MINOR
/// @see MATHFU_VERSION_REVISION
volatile __attribute__((weak)) const char *kMathFuVersionString =
"MathFu " MATHFU_STRING(MATHFU_VERSION_MAJOR) "." MATHFU_STRING(
MATHFU_VERSION_MINOR) "." MATHFU_STRING(MATHFU_VERSION_REVISION);
/// @}
#endif // !defined(_WIN32) && !defined(__CYGWIN__)
/// @cond MATHFU_INTERNAL
template <bool>
struct static_assert_util;
template <>
struct static_assert_util<true> {};
/// @endcond
/// @addtogroup mathfu_utilities
/// @{
/// @def MATHFU_STATIC_ASSERT
/// @brief Compile time assert for pre-C++11 compilers.
///
/// For example:
/// <blockquote><code>
/// MATHFU_STATIC_ASSERT(0 == 1);
/// </code></blockquote> will result in a compile error.
#define MATHFU_STATIC_ASSERT(x) static_assert_util<(x)>()
/// @}
/// @cond MATHFU_INTERNAL
/// Unroll an loop up to 4 iterations, where iterator is the identifier
/// used in each operation (e.g "i"), number_of_iterations is a constant which
/// specifies the number of times to perform the operation and "operation" is
/// the statement to execute for each iteration of the loop (e.g data[i] = v).
#define MATHFU_UNROLLED_LOOP(iterator, number_of_iterations, operation) \
{ \
const int iterator = 0; \
{ operation; } \
if ((number_of_iterations) > 1) { \
const int iterator = 1; \
{ operation; } \
if ((number_of_iterations) > 2) { \
const int iterator = 2; \
{ operation; } \
if ((number_of_iterations) > 3) { \
const int iterator = 3; \
{ operation; } \
if ((number_of_iterations) > 4) { \
for (int iterator = 4; iterator < (number_of_iterations); \
++iterator) { \
operation; \
} \
} \
} \
} \
} \
}
/// @endcond
namespace mathfu {
/// @addtogroup mathfu_utilities
/// @{
/// @brief Clamp x within [lower, upper].
/// @anchor mathfu_Clamp
///
/// @note Results are undefined if lower > upper.
///
/// @param x Value to clamp.
/// @param lower Lower value of the range.
/// @param upper Upper value of the range.
/// @returns Clamped value.
template <class T>
T Clamp(const T &x, const T &lower, const T &upper) {
return std::max<T>(lower, std::min<T>(x, upper));
}
/// @brief Linearly interpolate between range_start and range_end, based on
/// percent.
/// @anchor mathfu_Lerp
///
/// @param range_start Start of the range.
/// @param range_end End of the range.
/// @param percent Value between 0.0 and 1.0 used to interpolate between
/// range_start and range_end. Where a value of 0.0 results in a return
/// value of range_start and 1.0 results in a return value of range_end.
/// @return Value between range_start and range_end.
///
/// @tparam T Type of the range to interpolate over.
/// @tparam T2 Type of the value used to perform interpolation
/// (e.g float or double).
template <class T, class T2>
T Lerp(const T &range_start, const T &range_end, const T2 &percent) {
const T2 one_minus_percent = static_cast<T2>(1.0) - percent;
return range_start * one_minus_percent + range_end * percent;
}
/// @brief Linearly interpolate between range_start and range_end, based on
/// percent.
/// @anchor mathfu_Lerp2
///
/// @param range_start Start of the range.
/// @param range_end End of the range.
/// @param percent Value between 0.0 and 1.0 used to interpolate between
/// range_start and range_end. Where a value of 0.0 results in a return
/// value of range_start and 1.0 results in a return value of range_end.
/// @return Value between range_start and range_end.
///
/// @tparam T Type of the range to interpolate over.
template <class T>
T Lerp(const T &range_start, const T &range_end, const T &percent) {
return Lerp<T, T>(range_start, range_end, percent);
}
/// @brief Check if val is within [range_start..range_end).
/// @anchor mathfu_InRange
///
/// @param val Value to be tested.
/// @param range_start Starting point of the range (inclusive).
/// @param range_end Ending point of the range (non-inclusive).
/// @return Bool indicating success.
///
/// @tparam T Type of values to test.
template <class T>
bool InRange(T val, T range_start, T range_end) {
return val >= range_start && val < range_end;
}
/// @brief Generate a random value of type T.
/// @anchor mathfu_Random
///
/// This method generates a random value of type T, greater than or equal to
/// 0.0 and less than 1.0.
///
/// This function uses the standard C library function rand() from math.h to
/// generate the random number.
///
/// @returns Random number greater than or equal to 0.0 and less than 1.0.
///
/// @see RandomRange()
/// @see RandomInRange()
template <class T>
inline T Random() {
return static_cast<T>(rand()) / static_cast<T>(RAND_MAX);
}
/// @cond MATHFU_INTERNAL
template <>
inline float Random() {
return static_cast<float>(rand() >> 8) /
(static_cast<float>((RAND_MAX >> 8) + 1));
}
/// @endcond
/// @cond MATHFU_INTERNAL
template <>
inline double Random() {
return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX + 1LL));
}
/// @endcond
/// @brief Generate a random value of type T in the range -range...+range
/// @anchor mathfu_RandomRange
///
/// This function uses the standard C library function rand() from math.h to
/// generate the random number.
///
/// @param range Range of the random value to generate.
/// @return Random value in the range -range to +range
///
/// @see Random()
template <class T>
inline T RandomRange(T range) {
return (Random<T>() * range * 2) - range;
}
/// @brief Generate a random number between [range_start, range_end]
/// @anchor mathfu_RandomInRange
///
/// This function uses the standard C library function rand() from math.h to
/// generate the random number.
///
/// @param range_start Minimum value.
/// @param range_end Maximum value.
/// @return Random value in the range [range_start, range_end].
///
/// @see Lerp()
/// @see Random()
template <class T>
inline T RandomInRange(T range_start, T range_end) {
return Lerp(range_start, range_end, Random<T>());
}
/// @cond MATHFU_INTERNAL
template <>
inline int RandomInRange<int>(int range_start, int range_end) {
return static_cast<int>(RandomInRange<float>(static_cast<float>(range_start),
static_cast<float>(range_end)));
}
/// @endcond
/// @brief Round a value up to the nearest power of 2.
///
/// @param x Value to round up.
/// @returns Value rounded up to the nearest power of 2.
template <class T>
T RoundUpToPowerOf2(T x) {
return static_cast<T>(
pow(static_cast<T>(2), ceil(log(x) / log(static_cast<T>(2)))));
}
/// @brief Specialized version of RoundUpToPowerOf2 for int32_t.
template <>
inline int32_t RoundUpToPowerOf2<>(int32_t x) {
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x++;
return x;
}
/// @brief Round a value up to the type's size boundary.
///
/// @param v Value to round up.
/// @returns Value rounded up to the type's size boundary.
template <typename T>
uint32_t RoundUpToTypeBoundary(uint32_t v) {
return (v + sizeof(T) - 1) & ~(sizeof(T) - 1);
}
/// @}
/// @addtogroup mathfu_allocator
///
/// If you use MathFu with SIMD (SSE in particular), you need to have all
/// your allocations be 16-byte aligned (which isn't the case with the default
/// allocators on most platforms except OS X).
///
/// You can either use simd_allocator, which solves the problem for
/// any STL containers, but not for manual dynamic allocations or the
/// new/delete override MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE will
/// solve it for all allocations, at the cost of MATHFU_ALIGNMENT bytes per
/// allocation.
/// @addtogroup mathfu_allocator
/// @{
/// @def MATHFU_ALIGNMENT
/// @brief Alignment (in bytes) of memory allocated by AllocateAligned.
///
/// @see mathfu::AllocateAligned()
/// @see mathfu::simd_allocator
#define MATHFU_ALIGNMENT 16
/// @brief Allocate an aligned block of memory.
/// @anchor mathfu_AllocateAligned
///
/// This function allocates a block of memory aligned to MATHFU_ALIGNMENT
/// bytes.
///
/// @param n Size of memory to allocate.
/// @return Pointer to aligned block of allocated memory or NULL if
/// allocation failed.
inline void *AllocateAligned(size_t n) {
#if defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
return _aligned_malloc(n, MATHFU_ALIGNMENT);
#else
// We need to allocate extra bytes to guarantee alignment,
// and to store the pointer to the original buffer.
uint8_t *buf = reinterpret_cast<uint8_t *>(malloc(n + MATHFU_ALIGNMENT));
if (!buf) return NULL;
// Align to next higher multiple of MATHFU_ALIGNMENT.
uint8_t *aligned_buf = reinterpret_cast<uint8_t *>(
(reinterpret_cast<size_t>(buf) + MATHFU_ALIGNMENT) &
~(MATHFU_ALIGNMENT - 1));
// Write out original buffer pointer before aligned buffer.
// The assert will fail if the allocator granularity is less than the pointer
// size, or if MATHFU_ALIGNMENT doesn't fit two pointers.
assert(static_cast<size_t>(aligned_buf - buf) > sizeof(void *));
*(reinterpret_cast<uint8_t **>(aligned_buf) - 1) = buf;
return aligned_buf;
#endif // defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
}
/// @brief Deallocate a block of memory allocated with AllocateAligned().
/// @anchor mathfu_FreeAligned
///
/// @param p Pointer to memory to deallocate.
inline void FreeAligned(void *p) {
#if defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
_aligned_free(p);
#else
if (p == NULL) return;
free(*(reinterpret_cast<uint8_t **>(p) - 1));
#endif // defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
}
/// @brief SIMD-safe memory allocator, for use with STL types like std::vector.
///
/// For example:
/// <blockquote><code><pre>
/// std::vector<vec4, mathfu::simd_allocator<vec4>> myvector;
/// </pre></code></blockquote>
///
/// @see MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
/// @tparam T type allocated by this object.
template <typename T>
class simd_allocator : public std::allocator<T> {
public:
/// Size type.
typedef size_t size_type;
/// Pointer of type T.
typedef T *pointer;
/// Const pointer of type T.
typedef const T *const_pointer;
/// Constructs a simd_allocator.
simd_allocator() throw() : std::allocator<T>() {}
/// @brief Constructs and copies a simd_allocator.
///
/// @param a Allocator to copy.
simd_allocator(const simd_allocator &a) throw() : std::allocator<T>(a) {}
/// @brief Constructs and copies a simd_allocator.
///
/// @param a Allocator to copy.
/// @tparam U type of the object allocated by the allocator to copy.
template <class U>
simd_allocator(const simd_allocator<U> &a) throw() : std::allocator<T>(a) {}
/// @brief Destructs a simd_allocator.
~simd_allocator() throw() {}
/// @brief Obtains an allocator of a different type.
///
/// @tparam _Tp1 type of the new allocator.
template <typename _Tp1>
struct rebind {
/// @brief Allocator of type _Tp1.
typedef simd_allocator<_Tp1> other;
};
/// @brief Allocate memory for object T.
///
/// @param n Number of types to allocate.
/// @return Pointer to the newly allocated memory.
pointer allocate(size_type n) {
return reinterpret_cast<pointer>(AllocateAligned(n * sizeof(T)));
}
/// Deallocate memory referenced by pointer p.
///
/// @param p Pointer to memory to deallocate.
void deallocate(pointer p, size_type) { FreeAligned(p); }
};
#if defined(_MSC_VER)
#if _MSC_VER <= 1800 // MSVC 2013
#if !defined(noexcept)
#define noexcept
#endif // !defined(noexcept)
#endif // _MSC_VER <= 1800
#endif // defined(_MSC_VER)
/// @def MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
/// @brief Macro which overrides the default new and delete allocators.
///
/// To globally override new and delete, simply add the line:
/// <blockquote><code><pre>
/// MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
/// </pre></code></blockquote>
/// to the end of your main .cpp file.
#define MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE \
void *operator new(std::size_t n) { return mathfu::AllocateAligned(n); } \
void *operator new[](std::size_t n) { return mathfu::AllocateAligned(n); } \
void operator delete(void *p) noexcept { mathfu::FreeAligned(p); } \
void operator delete[](void *p) noexcept { mathfu::FreeAligned(p); }
/// @def MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
/// @brief Macro which defines the new and delete for MathFu classes.
#define MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE \
static void *operator new(std::size_t n) { \
return mathfu::AllocateAligned(n); \
} \
static void *operator new[](std::size_t n) { \
return mathfu::AllocateAligned(n); \
} \
static void *operator new(std::size_t /*n*/, void *p) { return p; } \
static void *operator new[](std::size_t /*n*/, void *p) { return p; } \
static void operator delete(void *p) { mathfu::FreeAligned(p); } \
static void operator delete[](void *p) { mathfu::FreeAligned(p); } \
static void operator delete(void * /*p*/, void * /*place*/) {} \
static void operator delete[](void * /*p*/, void * /*place*/) {}
/// @}
} // namespace mathfu
#endif // MATHFU_UTILITIES_H_

File diff suppressed because it is too large Load Diff

110
third_party/mathfu-1.1.0/jni/Android.mk vendored Normal file
View File

@ -0,0 +1,110 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)/..
MATHFU_DIR?=$(LOCAL_PATH)
include $(LOCAL_PATH)/android_config.mk
# Conditionally include libstlport (so include path is added to CFLAGS) if
# it's not being built using the NDK build process.
define add-stlport-includes
$(eval \
ifeq ($(NDK_PROJECT_PATH),)
include external/stlport/libstlport.mk
endif)
endef
# mathfu-cflags: disable_simd force_padding debug
# Expands to the compiler flags for applications or libraries that use MathFu.
# Where disable_simd specifies whether SIMD code should be disabled,
# force_padding specifies whether padding should be added to data structures
# in SIMD mode (-1 = default, 0 = padding off, 1 = padding on).
#
# NOTE: armeabi-v7a-hard has been deprecated. For more information see,
# https://android.googlesource.com/platform/ndk/+/master/docs/HardFloatAbi.md
define mathfu-cflags
$(if $(subst 0,,$(strip $(1))),-DMATHFU_COMPILE_WITHOUT_SIMD_SUPPORT,\
$(if $(subst -1,,$(strip $(2))),\
-DMATHFU_COMPILE_FORCE_PADDING=$(strip $(2)),)) \
$(if $(APP_DEBUG),-DDEBUG=1,-DDEBUG=0) \
$(if $(filter armeabi-v7a-hard,$(TARGET_ARCH_ABI)),\
-mfpu=neon -mhard-float -mfloat-abi=hard) \
$(if $(filter x86,$(TARGET_ARCH_ABI)),-msse) \
$(if $(filter x86_64,$(TARGET_ARCH_ABI)),-msse4.1)
endef
# Configure common local variables to build mathfu adding $(1) to the end of
# the build target's name.
define mathfu-module
$(eval \
LOCAL_MODULE:=libmathfu$(1)
LOCAL_MODULE_TAGS:=optional
LOCAL_COPY_HEADERS_TO:=mathfu$(1))
endef
# Configure local variables to build mathfu adding $(1) to the end of the
# build target's name, disabling SIMD depending upon the value of $(2) (see
# mathfu-cflags $(1)) and configuring padding (see mathfu-cflags $(2))
# with $(3).
define mathfu-build
$(eval \
$$(call mathfu-module,$(1))
LOCAL_SRC_FILES:=
LOCAL_COPY_HEADERS:=\
$(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/include/mathfu/*.h))
LOCAL_CFLAGS:=$$(call mathfu-cflags,$(2),$(3))
LOCAL_EXPORT_CFLAGS:=$$(LOCAL_CFLAGS)
LOCAL_EXPORT_C_INCLUDES:=\
$(LOCAL_PATH)/include \
$(DEPENDENCIES_VECTORIAL_DIR)/include
LOCAL_EXPORT_LDLIBS:=-lm
LOCAL_ARM_MODE:=arm
LOCAL_ARM_NEON:=$(if $(filter \
armeabi-v7a armeabi-v7a-hard,$(TARGET_ARCH_ABI)),true,)
$$(call add-stlport-includes))
endef
# --- libmathfu ---
# Target which builds an empty static library so that it's possible for
# projects using this module to add the appropriate flags and includes to
# their compile command line. This builds mathfu using the default build
# configuration specified in ${mathfu}/android_config.mk
include $(CLEAR_VARS)
$(call mathfu-build,,$(MATHFU_DISABLE_SIMD),$(MATHFU_FORCE_PADDING))
include $(BUILD_STATIC_LIBRARY)
# --- libmathfu_no_simd ---
# Builds an empty static library (similar to libmathfu).
# This build configuration has SIMD disabled.
include $(CLEAR_VARS)
$(call mathfu-build,_no_simd,1,-1)
include $(BUILD_STATIC_LIBRARY)
# --- libmathfu_simd ---
# Builds an empty static library (similar to libmathfu).
# This build configuration has SIMD enabled and padding enabled.
include $(CLEAR_VARS)
$(call mathfu-build,_simd_padding,0,1)
include $(BUILD_STATIC_LIBRARY)
# --- libmathfu_simd_no_padding ---
# Builds an empty static library (similar to libmathfu).
# This build configuration has SIMD enabled and padding disabled.
include $(CLEAR_VARS)
$(call mathfu-build,_simd_no_padding,0,0)
include $(BUILD_STATIC_LIBRARY)
mathfu_cflags:=

View File

@ -0,0 +1,21 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:=$(call my-dir)
APP_PLATFORM:=android-10
APP_ABI:=armeabi-v7a armeabi x86 x86_64 mips mips64
APP_STL:=c++_static
APP_MODULES:=libmathfu

Some files were not shown because too many files have changed in this diff Show More