├── .gitmodules
├── swift3D.xcodeproj
├── xcuserdata
│ └── adrian.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ ├── swift3D-iOS.xcscheme
│ │ └── swift3D-Mac.xcscheme
└── project.pbxproj
├── Tests
├── swift3DTests-Bridging-Header.h
├── Info.plist
├── glm-to-swift-quat.h
├── glm-to-swift.h
├── glm-to-swift-quat.mm
└── swift3DQuaterionTests.swift
├── .travis.yml
├── Source
├── swift3D.h
├── Info.plist
├── Geometric.swift
├── Vector.swift
├── Matrix.swift
├── Trigonometric.swift
├── Exponential.swift
├── Matrix_Transform.swift
├── Common.swift
└── Quaternion.swift
├── Swift3D.podspec
├── LICENSE
├── README.md
└── .gitignore
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Tests/glm"]
2 | path = Tests/glm
3 | url = https://github.com/g-truc/glm.git
4 |
--------------------------------------------------------------------------------
/swift3D.xcodeproj/xcuserdata/adrian.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Tests/swift3DTests-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #import "glm-to-swift.h"
6 | #import "glm-to-swift-quat.h"
--------------------------------------------------------------------------------
/swift3D.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 |
3 | xcode_project: swift3D.xcodeproj
4 | xcode_scheme: swift3D-Mac
5 | osx_image: xcode7.1
6 | xcode_sdk: macosx10.11
7 |
8 | script:
9 | - xcodebuild test -project swift3D.xcodeproj -scheme swift3D-Mac \
10 | GCC_GENERATE_DEBUGGING_SYMBOLS=YES \
11 | GCC_GENERATE_TEST_COVERAGE_FILES=YES \
12 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES
13 |
--------------------------------------------------------------------------------
/Source/swift3D.h:
--------------------------------------------------------------------------------
1 | //
2 | // swift3D.h
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 01.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for swift3D.
12 | FOUNDATION_EXPORT double swift3DVersionNumber;
13 |
14 | //! Project version string for swift3D.
15 | FOUNDATION_EXPORT const unsigned char swift3DVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Swift3D.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "Swift3D"
3 | s.version = "0.3.0"
4 | s.summary = "Swift3D implements handy function for 3D programming"
5 | s.homepage = "https://github.com/adriankrupa/swift3D"
6 | s.license = { :type => "MIT" }
7 | s.authors = { "adriankrupa" => "adrian.krupa91@gmail.com", }
8 |
9 | s.requires_arc = true
10 | s.osx.deployment_target = "10.9"
11 | s.ios.deployment_target = "8.0"
12 | s.watchos.deployment_target = "2.0"
13 | s.tvos.deployment_target = "9.0"
14 | s.source = { :git => "https://github.com/adriankrupa/swift3D.git", :tag => "0.3.0"}
15 | s.source_files = "Source/*.swift"
16 | end
17 |
--------------------------------------------------------------------------------
/Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Source/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c)
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
10 |
--------------------------------------------------------------------------------
/Source/Geometric.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Geometric.swift
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 15.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import simd
11 |
12 | // MARK: faceforward
13 |
14 | /// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
15 | @warn_unused_result
16 | public func faceforward(N: float2, _ I: float2, _ Nref: float2) -> float2 {
17 | return dot(Nref, I) < 0 ? N : -N
18 | }
19 |
20 | /// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
21 | @warn_unused_result
22 | public func faceforward(N: float3, _ I: float3, _ Nref: float3) -> float3 {
23 | return dot(Nref, I) < 0 ? N : -N
24 | }
25 |
26 | /// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
27 | @warn_unused_result
28 | public func faceforward(N: float4, _ I: float4, _ Nref: float4) -> float4 {
29 | return dot(Nref, I) < 0 ? N : -N
30 | }
31 |
32 | /// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
33 | @warn_unused_result
34 | public func faceforward(N: double2, _ I: double2, _ Nref: double2) -> double2 {
35 | return dot(Nref, I) < 0 ? N : -N
36 | }
37 |
38 | /// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
39 | @warn_unused_result
40 | public func faceforward(N: double3, _ I: double3, _ Nref: double3) -> double3 {
41 | return dot(Nref, I) < 0 ? N : -N
42 | }
43 |
44 | /// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
45 | @warn_unused_result
46 | public func faceforward(N: double4, _ I: double4, _ Nref: double4) -> double4 {
47 | return dot(Nref, I) < 0 ? N : -N
48 | }
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Swift3D
2 | [](https://raw.githubusercontent.com/adriankrupa/Swift3D/master/LICENSE)
3 | 
4 | [](https://github.com/adriankrupa/Swift3D/releases)
5 | [](https://github.com/Carthage/Carthage)
6 | [](https://travis-ci.org/adriankrupa/swift3D)
7 |
8 | A set of Swift functions useful for 3D programming. It expand common mathematical functions on SIMD data types. There are also handy functions for projection matrices, quaternions, matrices and vectors conversions. Everything is tested using [glm](https://github.com/g-truc/glm).
9 |
10 |
11 | # Setup #
12 |
13 | ## Using [Carthage](https://github.com/Carthage/Carthage)
14 |
15 | Add `github "adriankrupa/Swift3D"` to your `Cartfile` and run `carthage update`. If unfamiliar with Carthage then checkout their [Getting Started section](https://github.com/Carthage/Carthage#getting-started)
16 |
17 | ## Using [cocoapods](http://cocoapods.org/) version 0.36.x or greater
18 |
19 | Add `pod 'Swift3D'` to your `Podfile` and run `pod install`. Add `use_frameworks!` to the end of the `Podfile`. Requires cocoapod version 0.36.x or greater.
20 |
21 | ## Using `git submodule`
22 |
23 | 1. If you are using git then add Dollar as a submodule using `git submodule add https://github.com/adriankrupa/Swift3D.git`. If not using git download the project using `git clone https://github.com/adriankrupa/Swift3D.git` in your project folder.
24 | 2. Open the Swift3D folder. Drag Swift3D.xcodeproj, inside the Swift3D folder, into the file navigator of your Xcode project.
25 | 3. In Xcode, navigate to the target configuration window by clicking on the blue project icon, and selecting the application target under the "Targets" heading in the sidebar.
26 | 4. In the tab bar at the top of that window, open the "Build Phases" panel.
27 | 5. Expand the "Link Binary with Libraries" group, and add Swift3D.framework.
28 | 6. In your project file `import Swift3D` and you can call all of the helper functions.
29 |
30 | [](https://bitdeli.com/free "Bitdeli Badge")
31 |
--------------------------------------------------------------------------------
/swift3D.xcodeproj/xcuserdata/adrian.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | swift3D-Mac.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 | swift3D-iOS.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 1
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 3ABBC61C1BE68FF500D563DF
21 |
22 | primary
23 |
24 |
25 | 3ABBC6261BE68FF500D563DF
26 |
27 | primary
28 |
29 |
30 | 3ABBC63B1BE6908E00D563DF
31 |
32 | primary
33 |
34 |
35 | 3ABBC6441BE6908E00D563DF
36 |
37 | primary
38 |
39 |
40 | 3ABBC6571BE690C100D563DF
41 |
42 | primary
43 |
44 |
45 | 3ABBC6601BE690C100D563DF
46 |
47 | primary
48 |
49 |
50 | 3ABBC6731BE6911600D563DF
51 |
52 | primary
53 |
54 |
55 | 3ABBC67C1BE6911600D563DF
56 |
57 | primary
58 |
59 |
60 | 3ABBC68F1BE691F100D563DF
61 |
62 | primary
63 |
64 |
65 | 3ABBC6981BE691F200D563DF
66 |
67 | primary
68 |
69 |
70 | 3ABBC6AB1BE6947300D563DF
71 |
72 | primary
73 |
74 |
75 | 3ABBC6B41BE6947300D563DF
76 |
77 | primary
78 |
79 |
80 | 3ABBC6C81BE695DA00D563DF
81 |
82 | primary
83 |
84 |
85 | 3ABBC6D11BE695DA00D563DF
86 |
87 | primary
88 |
89 |
90 | 3ABBC6E41BE696DB00D563DF
91 |
92 | primary
93 |
94 |
95 | 3ABBC6ED1BE696DB00D563DF
96 |
97 | primary
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/Source/Vector.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Adrian Krupa on 30.11.2015.
3 | // Copyright (c) 2015 Adrian Krupa. All rights reserved.
4 | //
5 |
6 | import Foundation
7 | import simd
8 |
9 | public extension float3 {
10 |
11 | public init(_ v: float4) {
12 | self.init(v.x, v.y, v.z)
13 | }
14 | }
15 |
16 | public extension float4 {
17 |
18 | public init(_ v: float3, _ vw: Float) {
19 | self.init()
20 | x = v.x
21 | y = v.y
22 | z = v.z
23 | w = vw
24 | }
25 |
26 | public init(_ v: float3) {
27 | self.init()
28 | x = v.x
29 | y = v.y
30 | z = v.z
31 | w = 0
32 | }
33 |
34 | public init(_ q: quat) {
35 | self.init()
36 | x = q.x
37 | y = q.y
38 | z = q.z
39 | w = q.w
40 | }
41 | }
42 |
43 | public extension double3 {
44 |
45 | public init(_ v: double4) {
46 | self.init(v.x, v.y, v.z)
47 | }
48 | }
49 |
50 | public extension double4 {
51 |
52 | public init(_ v: double3, _ vw: Double) {
53 | self.init()
54 | x = v.x
55 | y = v.y
56 | z = v.z
57 | w = vw
58 | }
59 |
60 | public init(_ v: double3) {
61 | self.init()
62 | x = v.x
63 | y = v.y
64 | z = v.z
65 | w = 0
66 | }
67 |
68 | public init(_ q: dquat) {
69 | self.init()
70 | x = q.x
71 | y = q.y
72 | z = q.z
73 | w = q.w
74 | }
75 | }
76 |
77 | public func ==(a: float4, b: float4) -> Bool {
78 | for i in 0..<4 {
79 | if(a[i] != b[i]) {
80 | return false
81 | }
82 | }
83 | return true
84 | }
85 |
86 | public func !=(a: float4, b: float4) -> Bool {
87 | return !(a==b)
88 | }
89 |
90 | public func ==(a: float3, b: float3) -> Bool {
91 | for i in 0..<3 {
92 | if(a[i] != b[i]) {
93 | return false
94 | }
95 | }
96 | return true
97 | }
98 |
99 | public func !=(a: float3, b: float3) -> Bool {
100 | return !(a==b)
101 | }
102 |
103 | public func ==(a: float2, b: float2) -> Bool {
104 | for i in 0..<2 {
105 | if(a[i] != b[i]) {
106 | return false
107 | }
108 | }
109 | return true
110 | }
111 |
112 | public func !=(a: float2, b: float2) -> Bool {
113 | return !(a==b)
114 | }
115 |
116 | public func ==(a: double4, b: double4) -> Bool {
117 | for i in 0..<4 {
118 | if(a[i] != b[i]) {
119 | return false
120 | }
121 | }
122 | return true
123 | }
124 |
125 | public func !=(a: double4, b: double4) -> Bool {
126 | return !(a==b)
127 | }
128 |
129 | public func ==(a: double3, b: double3) -> Bool {
130 | for i in 0..<3 {
131 | if(a[i] != b[i]) {
132 | return false
133 | }
134 | }
135 | return true
136 | }
137 |
138 | public func !=(a: double3, b: double3) -> Bool {
139 | return !(a==b)
140 | }
141 |
142 | public func ==(a: double2, b: double2) -> Bool {
143 | for i in 0..<2 {
144 | if(a[i] != b[i]) {
145 | return false
146 | }
147 | }
148 | return true
149 | }
150 |
151 | public func !=(a: double2, b: double2) -> Bool {
152 | return !(a==b)
153 | }
--------------------------------------------------------------------------------
/swift3D.xcodeproj/xcshareddata/xcschemes/swift3D-iOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/xcode,swift,c++,osx,appcode
3 |
4 | ### Xcode ###
5 | # Xcode
6 | #
7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
8 |
9 | ## Build generated
10 | build/
11 | DerivedData
12 |
13 | ## Various settings
14 | *.pbxuser
15 | !default.pbxuser
16 | *.mode1v3
17 | !default.mode1v3
18 | *.mode2v3
19 | !default.mode2v3
20 | *.perspectivev3
21 | !default.perspectivev3
22 | xcuserdata
23 |
24 | ## Other
25 | *.xccheckout
26 | *.moved-aside
27 | *.xcuserstate
28 |
29 |
30 | ### Swift ###
31 | # Xcode
32 | #
33 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
34 |
35 | ## Build generated
36 | build/
37 | DerivedData
38 |
39 | ## Various settings
40 | *.pbxuser
41 | !default.pbxuser
42 | *.mode1v3
43 | !default.mode1v3
44 | *.mode2v3
45 | !default.mode2v3
46 | *.perspectivev3
47 | !default.perspectivev3
48 | xcuserdata
49 |
50 | ## Other
51 | *.xccheckout
52 | *.moved-aside
53 | *.xcuserstate
54 | *.xcscmblueprint
55 |
56 | ## Obj-C/Swift specific
57 | *.hmap
58 | *.ipa
59 |
60 | # CocoaPods
61 | #
62 | # We recommend against adding the Pods directory to your .gitignore. However
63 | # you should judge for yourself, the pros and cons are mentioned at:
64 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
65 | #
66 | # Pods/
67 |
68 | # Carthage
69 | #
70 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
71 | # Carthage/Checkouts
72 |
73 | Carthage/Build
74 |
75 | # fastlane
76 | #
77 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
78 | # screenshots whenever they are needed.
79 | # For more information about the recommended setup visit:
80 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
81 |
82 | fastlane/report.xml
83 | fastlane/screenshots
84 |
85 |
86 | ### C++ ###
87 | # Compiled Object files
88 | *.slo
89 | *.lo
90 | *.o
91 | *.obj
92 |
93 | # Precompiled Headers
94 | *.gch
95 | *.pch
96 |
97 | # Compiled Dynamic libraries
98 | *.so
99 | *.dylib
100 | *.dll
101 |
102 | # Fortran module files
103 | *.mod
104 |
105 | # Compiled Static libraries
106 | *.lai
107 | *.la
108 | *.a
109 | *.lib
110 |
111 | # Executables
112 | *.exe
113 | *.out
114 | *.app
115 |
116 |
117 | ### OSX ###
118 | .DS_Store
119 | .AppleDouble
120 | .LSOverride
121 |
122 | # Icon must end with two \r
123 | Icon
124 |
125 |
126 | # Thumbnails
127 | ._*
128 |
129 | # Files that might appear in the root of a volume
130 | .DocumentRevisions-V100
131 | .fseventsd
132 | .Spotlight-V100
133 | .TemporaryItems
134 | .Trashes
135 | .VolumeIcon.icns
136 |
137 | # Directories potentially created on remote AFP share
138 | .AppleDB
139 | .AppleDesktop
140 | Network Trash Folder
141 | Temporary Items
142 | .apdisk
143 |
144 |
145 | ### AppCode ###
146 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
147 |
148 | *.iml
149 |
150 | ## Directory-based project format:
151 | .idea/
152 | # if you remove the above rule, at least ignore the following:
153 |
154 | # User-specific stuff:
155 | # .idea/workspace.xml
156 | # .idea/tasks.xml
157 | # .idea/dictionaries
158 | # .idea/shelf
159 |
160 | # Sensitive or high-churn files:
161 | # .idea/dataSources.ids
162 | # .idea/dataSources.xml
163 | # .idea/sqlDataSources.xml
164 | # .idea/dynamic.xml
165 | # .idea/uiDesigner.xml
166 |
167 | # Gradle:
168 | # .idea/gradle.xml
169 | # .idea/libraries
170 |
171 | # Mongo Explorer plugin:
172 | # .idea/mongoSettings.xml
173 |
174 | ## File-based project format:
175 | *.ipr
176 | *.iws
177 |
178 | ## Plugin-specific files:
179 |
180 | # IntelliJ
181 | /out/
182 |
183 | # mpeltonen/sbt-idea plugin
184 | .idea_modules/
185 |
186 | # JIRA plugin
187 | atlassian-ide-plugin.xml
188 |
189 | # Crashlytics plugin (for Android Studio and IntelliJ)
190 | com_crashlytics_export_strings.xml
191 | crashlytics.properties
192 | crashlytics-build.properties
193 | fabric.properties
194 |
--------------------------------------------------------------------------------
/swift3D.xcodeproj/xcshareddata/xcschemes/swift3D-Mac.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
34 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
65 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
84 |
90 |
91 |
92 |
93 |
95 |
96 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Source/Matrix.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Matrix.swift
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 15.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import simd
11 |
12 | public extension float2x2 {
13 | /// Return the determinant of a squared matrix.
14 | public var determinant : Float {
15 | get {
16 | return self[0,0]*self[1,1]-self[0,1]*self[1,0]
17 | }
18 | }
19 | }
20 |
21 | public extension float3x3 {
22 | /// Return the determinant of a squared matrix.
23 | public var determinant : Float {
24 | get {
25 | let t1 = self[0,0] * (self[1,1] * self[2,2] - self[2,1] * self[1,2])
26 | let t2 = -self[1,0] * (self[0,1] * self[2,2] - self[2,1] * self[0,2])
27 | let t3 = self[2,0] * (self[0,1] * self[1,2] - self[1,1] * self[0,2])
28 | return t1 + t2 + t3
29 | }
30 | }
31 |
32 | public init(_ m: float4x4) {
33 | self.init([float3(m[0]), float3(m[1]), float3(m[2])])
34 | }
35 | }
36 |
37 | public extension float4x4 {
38 | /// Return the determinant of a squared matrix.
39 | public var determinant : Float {
40 | get {
41 | let SubFactor00 = self[2,2] * self[3,3] - self[3,2] * self[2,3];
42 | let SubFactor01 = self[2,1] * self[3,3] - self[3,1] * self[2,3];
43 | let SubFactor02 = self[2,1] * self[3,2] - self[3,1] * self[2,2];
44 | let SubFactor03 = self[2,0] * self[3,3] - self[3,0] * self[2,3];
45 | let SubFactor04 = self[2,0] * self[3,2] - self[3,0] * self[2,2];
46 | let SubFactor05 = self[2,0] * self[3,1] - self[3,0] * self[2,1];
47 |
48 | let DetCof = float4(
49 | +(self[1,1] * SubFactor00 - self[1,2] * SubFactor01 + self[1,3] * SubFactor02),
50 | -(self[1,0] * SubFactor00 - self[1,2] * SubFactor03 + self[1,3] * SubFactor04),
51 | +(self[1,0] * SubFactor01 - self[1,1] * SubFactor03 + self[1,3] * SubFactor05),
52 | -(self[1,0] * SubFactor02 - self[1,1] * SubFactor04 + self[1,2] * SubFactor05));
53 |
54 | return
55 | self[0,0] * DetCof[0] + self[0,1] * DetCof[1] +
56 | self[0,2] * DetCof[2] + self[0,3] * DetCof[3];
57 | }
58 | }
59 |
60 | public init(_ m: float3x3) {
61 | self.init([float4(m[0]), float4(m[1]), float4(m[2]), float4(0, 0, 0, 1)])
62 | }
63 | }
64 |
65 | public extension double2x2 {
66 | /// Return the determinant of a squared matrix.
67 | public var determinant : Double {
68 | get {
69 | return self[0,0]*self[1,1]-self[0,1]*self[1,0]
70 | }
71 | }
72 | }
73 |
74 | public extension double3x3 {
75 | /// Return the determinant of a squared matrix.
76 | public var determinant : Double {
77 | get {
78 | let t1 = self[0,0] * (self[1,1] * self[2,2] - self[2,1] * self[1,2])
79 | let t2 = -self[1,0] * (self[0,1] * self[2,2] - self[2,1] * self[0,2])
80 | let t3 = self[2,0] * (self[0,1] * self[1,2] - self[1,1] * self[0,2])
81 | return t1 + t2 + t3
82 | }
83 | }
84 |
85 | public init(_ m: double4x4) {
86 | self.init([double3(m[0]), double3(m[1]), double3(m[2])])
87 | }
88 | }
89 |
90 | public extension double4x4 {
91 | /// Return the determinant of a squared matrix.
92 | public var determinant : Double {
93 | get {
94 | let SubFactor00 = self[2,2] * self[3,3] - self[3,2] * self[2,3];
95 | let SubFactor01 = self[2,1] * self[3,3] - self[3,1] * self[2,3];
96 | let SubFactor02 = self[2,1] * self[3,2] - self[3,1] * self[2,2];
97 | let SubFactor03 = self[2,0] * self[3,3] - self[3,0] * self[2,3];
98 | let SubFactor04 = self[2,0] * self[3,2] - self[3,0] * self[2,2];
99 | let SubFactor05 = self[2,0] * self[3,1] - self[3,0] * self[2,1];
100 |
101 | let DetCof = double4(
102 | +(self[1,1] * SubFactor00 - self[1,2] * SubFactor01 + self[1,3] * SubFactor02),
103 | -(self[1,0] * SubFactor00 - self[1,2] * SubFactor03 + self[1,3] * SubFactor04),
104 | +(self[1,0] * SubFactor01 - self[1,1] * SubFactor03 + self[1,3] * SubFactor05),
105 | -(self[1,0] * SubFactor02 - self[1,1] * SubFactor04 + self[1,2] * SubFactor05));
106 |
107 | return
108 | self[0,0] * DetCof[0] + self[0,1] * DetCof[1] +
109 | self[0,2] * DetCof[2] + self[0,3] * DetCof[3];
110 | }
111 | }
112 |
113 | public init(_ m: double3x3) {
114 | self.init([double4(m[0]), double4(m[1]), double4(m[2]), double4(0, 0, 0, 1)])
115 | }
116 | }
117 |
118 | public func ==(a: float4x4, b: float4x4) -> Bool {
119 | for i in 0..<4 {
120 | if(a[i] != b[i]) {
121 | return false
122 | }
123 | }
124 | return true
125 | }
126 |
127 | public func !=(a: float4x4, b: float4x4) -> Bool {
128 | return !(a==b)
129 | }
130 |
131 | public func ==(a: float3x3, b: float3x3) -> Bool {
132 | for i in 0..<3 {
133 | if(a[i] != b[i]) {
134 | return false
135 | }
136 | }
137 | return true
138 | }
139 |
140 | public func !=(a: float3x3, b: float3x3) -> Bool {
141 | return !(a==b)
142 | }
143 |
144 | public func ==(a: float2x2, b: float2x2) -> Bool {
145 | for i in 0..<2 {
146 | if(a[i] != b[i]) {
147 | return false
148 | }
149 | }
150 | return true
151 | }
152 |
153 | public func !=(a: float2x2, b: float2x2) -> Bool {
154 | return !(a==b)
155 | }
156 |
157 | public func ==(a: double4x4, b: double4x4) -> Bool {
158 | for i in 0..<4 {
159 | if(a[i] != b[i]) {
160 | return false
161 | }
162 | }
163 | return true
164 | }
165 |
166 | public func !=(a: double4x4, b: double4x4) -> Bool {
167 | return !(a==b)
168 | }
169 |
170 | public func ==(a: double3x3, b: double3x3) -> Bool {
171 | for i in 0..<3 {
172 | if(a[i] != b[i]) {
173 | return false
174 | }
175 | }
176 | return true
177 | }
178 |
179 | public func !=(a: double3x3, b: double3x3) -> Bool {
180 | return !(a==b)
181 | }
182 |
183 | public func ==(a: double2x2, b: double2x2) -> Bool {
184 | for i in 0..<2 {
185 | if(a[i] != b[i]) {
186 | return false
187 | }
188 | }
189 | return true
190 | }
191 |
192 | public func !=(a: double2x2, b: double2x2) -> Bool {
193 | return !(a==b)
194 | }
--------------------------------------------------------------------------------
/Tests/glm-to-swift-quat.h:
--------------------------------------------------------------------------------
1 | //
2 | // glm-to-swift-quat.h
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 02.01.2016.
6 | // Copyright © 2016 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface glm_to_swift_quat : NSObject
13 |
14 | +(BOOL) quatInitWithResult:(vector_float4) result;
15 | +(BOOL) quatInitWithValuesW:(float) w ValueX:(float) x ValueY:(float) y ValueZ:(float) z AndResult:(vector_float4) result;
16 | +(BOOL) quatInitWithQuatWithInitValuesW:(float) w ValueX:(float) x ValueY:(float) y ValueZ:(float) z andResult:(vector_float4) result;
17 | +(BOOL) quatInitWithFloat:(float) s andVec3:(vector_float3) v andResult:(vector_float4) result;
18 | +(BOOL) quatInitWithAngle:(float)angle andAxis:(vector_float3)axis andResult:(vector_float4) result;
19 | +(BOOL) quatInitWithEulerAngles:(vector_float3) angles andResult:(vector_float4) result;
20 | +(BOOL) quatInitWithNormalizedAxis:(vector_float3) axis1 withAxis:(vector_float3) axis2 andResult:(vector_float4) result;
21 | +(BOOL) quatInitWithMat3x3:(matrix_float3x3) mat andResult:(vector_float4) result;
22 | +(BOOL) quatInitWithMat4x4:(matrix_float4x4) mat andResult:(vector_float4) result;
23 |
24 | +(BOOL) quatPlus:(vector_float4)v andResult:(vector_float4) result;
25 | +(BOOL) quatMinus:(vector_float4)v andResult:(vector_float4) result;
26 | +(BOOL) quatAddition:(vector_float4)v1 withQuat:(vector_float4)v2 andResult:(vector_float4) result;
27 | +(BOOL) quatMultiplication:(vector_float4)v1 withQuat:(vector_float4)v2 andResult:(vector_float4) result;
28 | +(BOOL) quatMultiplication:(vector_float4)v1 withScalar:(float)f andResult:(vector_float4) result;
29 | +(BOOL) quatMultiplication_2:(vector_float4)v1 withScalar:(float)f andResult:(vector_float4) result;
30 | +(BOOL) quatMultiplication:(vector_float4)v1 withVec3:(vector_float3)v2 andResult:(vector_float3) result;
31 | +(BOOL) quatMultiplication_2:(vector_float4)v1 withVec3:(vector_float3)v2 andResult:(vector_float3) result;
32 | +(BOOL) quatMultiplication:(vector_float4)v1 withVec4:(vector_float4)v2 andResult:(vector_float4) result;
33 | +(BOOL) quatMultiplication_2:(vector_float4)v1 withVec4:(vector_float4)v2 andResult:(vector_float4) result;
34 | +(BOOL) quatDivision:(vector_float4)v1 withScalar:(float)f andResult:(vector_float4) result;
35 |
36 | +(BOOL) quatDot:(vector_float4)v1 withQuat:(vector_float4)v2 andResult:(float) result;
37 | +(BOOL) quatLength:(vector_float4)v andResult:(float) result;
38 | +(BOOL) quatInverse:(vector_float4)v andResult:(vector_float4) result;
39 | +(BOOL) quatNormalization:(vector_float4) source andResult:(vector_float4) result;
40 | +(BOOL) quatConjugate:(vector_float4) source andResult:(vector_float4) result;
41 |
42 | +(BOOL) quatMix:(vector_float4)q1 with:(vector_float4)q2 at:(float)t andResult:(vector_float4) result;
43 | +(BOOL) quatLerp:(vector_float4)q1 with:(vector_float4)q2 at:(float)t andResult:(vector_float4) result;
44 | +(BOOL) quatSlerp:(vector_float4)q1 with:(vector_float4)q2 at:(float)t andResult:(vector_float4) result;
45 |
46 | +(BOOL) quatRotate:(vector_float4)q withAngle:(float)angle withAxis:(vector_float3)axis andResult:(vector_float4) result;
47 | +(BOOL) quatEulerAngles:(vector_float4)q withResult:(vector_float3) result;
48 |
49 | +(BOOL) quatFloat3x3Cast:(vector_float4)q withResult:(matrix_float3x3) result;
50 | +(BOOL) quatFloat4x4Cast:(vector_float4)q withResult:(matrix_float4x4) result;
51 |
52 | +(BOOL) quatAngle:(vector_float4)q withResult:(float) result;
53 | +(BOOL) quatAxis:(vector_float4)q withResult:(vector_float3) result;
54 |
55 |
56 |
57 | +(BOOL) quatInitWithResultDouble:(vector_double4) result;
58 | +(BOOL) quatInitWithValuesWDouble:(double) w ValueX:(double) x ValueY:(double) y ValueZ:(double) z AndResult:(vector_double4) result;
59 | +(BOOL) quatInitWithQuatWithInitValuesWDouble:(double) w ValueX:(double) x ValueY:(double) y ValueZ:(double) z andResult:(vector_double4) result;
60 | +(BOOL) quatInitWithDouble:(double)s andVec3:(vector_double3)v andResult:(vector_double4) result;
61 | +(BOOL) quatInitWithAngleDouble:(double)angle andAxis:(vector_double3)axis andResult:(vector_double4) result;
62 | +(BOOL) quatInitWithEulerAnglesDouble:(vector_double3) angles andResult:(vector_double4) result;
63 | +(BOOL) quatInitWithNormalizedAxisDouble:(vector_double3) axis1 withAxis:(vector_double3) axis2 andResult:(vector_double4) result;
64 | +(BOOL) quatInitWithMat3x3Double:(matrix_double3x3) mat andResult:(vector_double4) result;
65 | +(BOOL) quatInitWithMat4x4Double:(matrix_double4x4) mat andResult:(vector_double4) result;
66 |
67 | +(BOOL) quatPlusDouble:(vector_double4)v andResult:(vector_double4) result;
68 | +(BOOL) quatMinusDouble:(vector_double4)v andResult:(vector_double4) result;
69 | +(BOOL) quatAdditionDouble:(vector_double4)v1 withQuat:(vector_double4)v2 andResult:(vector_double4) result;
70 | +(BOOL) quatMultiplicationDouble:(vector_double4)v1 withQuat:(vector_double4)v2 andResult:(vector_double4) result;
71 | +(BOOL) quatMultiplicationDouble:(vector_double4)v1 withScalar:(double)f andResult:(vector_double4) result;
72 | +(BOOL) quatMultiplication_2Double:(vector_double4)v1 withScalar:(double)f andResult:(vector_double4) result;
73 | +(BOOL) quatMultiplicationDouble:(vector_double4)v1 withVec3:(vector_double3)v2 andResult:(vector_double3) result;
74 | +(BOOL) quatMultiplication_2Double:(vector_double4)v1 withVec3:(vector_double3)v2 andResult:(vector_double3) result;
75 | +(BOOL) quatMultiplicationDouble:(vector_double4)v1 withVec4:(vector_double4)v2 andResult:(vector_double4) result;
76 | +(BOOL) quatMultiplication_2Double:(vector_double4)v1 withVec4:(vector_double4)v2 andResult:(vector_double4) result;
77 | +(BOOL) quatDivisionDouble:(vector_double4)v1 withScalar:(double)f andResult:(vector_double4) result;
78 |
79 | +(BOOL) quatDotDouble:(vector_double4)v1 withQuat:(vector_double4)v2 andResult:(double) result;
80 | +(BOOL) quatLengthDouble:(vector_double4)v andResult:(double) result;
81 | +(BOOL) quatInverseDouble:(vector_double4)v andResult:(vector_double4) result;
82 | +(BOOL) quatNormalizationDouble:(vector_double4) source andResult:(vector_double4) result;
83 | +(BOOL) quatConjugateDouble:(vector_double4) source andResult:(vector_double4) result;
84 |
85 | +(BOOL) quatMixDouble:(vector_double4)q1 with:(vector_double4)q2 at:(double)t andResult:(vector_double4) result;
86 | +(BOOL) quatLerpDouble:(vector_double4)q1 with:(vector_double4)q2 at:(double)t andResult:(vector_double4) result;
87 | +(BOOL) quatSlerpDouble:(vector_double4)q1 with:(vector_double4)q2 at:(double)t andResult:(vector_double4) result;
88 |
89 | +(BOOL) quatRotateDouble:(vector_double4)q withAngle:(double)angle withAxis:(vector_double3)axis andResult:(vector_double4) result;
90 | +(BOOL) quatEulerAnglesDouble:(vector_double4)q withResult:(vector_double3) result;
91 |
92 | +(BOOL) quatdouble3x3CastDouble:(vector_double4)q withResult:(matrix_double3x3) result;
93 | +(BOOL) quatdouble4x4CastDouble:(vector_double4)q withResult:(matrix_double4x4) result;
94 |
95 | +(BOOL) quatAngleDouble:(vector_double4)q withResult:(double) result;
96 | +(BOOL) quatAxisDouble:(vector_double4)q withResult:(vector_double3) result;
97 |
98 | @end
99 |
--------------------------------------------------------------------------------
/Source/Trigonometric.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Trigonometric.swift
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 15.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import simd
11 |
12 | // MARK: radians
13 |
14 | /// Converts degrees to radians and returns the result.
15 | @warn_unused_result
16 | public func radians(degrees: Float) -> Float {
17 | return degrees * Float(0.01745329251994329576923690768489)
18 | }
19 |
20 | /// Converts degrees to radians and returns the result.
21 | @warn_unused_result
22 | public func radians(degrees: float2) -> float2 {
23 | return degrees * float2(0.01745329251994329576923690768489)
24 | }
25 |
26 | /// Converts degrees to radians and returns the result.
27 | @warn_unused_result
28 | public func radians(degrees: float3) -> float3 {
29 | return degrees * float3(0.01745329251994329576923690768489)
30 | }
31 |
32 | /// Converts degrees to radians and returns the result.
33 | @warn_unused_result
34 | public func radians(degrees: float4) -> float4 {
35 | return degrees * float4(0.01745329251994329576923690768489)
36 | }
37 |
38 | /// Converts degrees to radians and returns the result.
39 | @warn_unused_result
40 | public func radians(degrees: Double) -> Double {
41 | return degrees * Double(0.01745329251994329576923690768489)
42 | }
43 |
44 | /// Converts degrees to radians and returns the result.
45 | @warn_unused_result
46 | public func radians(degrees: double2) -> double2 {
47 | return degrees * double2(0.01745329251994329576923690768489)
48 | }
49 |
50 | /// Converts degrees to radians and returns the result.
51 | @warn_unused_result
52 | public func radians(degrees: double3) -> double3 {
53 | return degrees * double3(0.01745329251994329576923690768489)
54 | }
55 |
56 | /// Converts degrees to radians and returns the result.
57 | @warn_unused_result
58 | public func radians(degrees: double4) -> double4 {
59 | return degrees * double4(0.01745329251994329576923690768489)
60 | }
61 |
62 | // MARK: degrees
63 |
64 | /// Converts radians to degrees and returns the result.
65 | @warn_unused_result
66 | public func degrees(radians: Float) -> Float {
67 | return radians * Float(57.295779513082320876798154814105)
68 | }
69 |
70 | /// Converts radians to degrees and returns the result.
71 | @warn_unused_result
72 | public func degrees(radians: float2) -> float2 {
73 | return radians * float2(57.295779513082320876798154814105)
74 | }
75 |
76 | /// Converts radians to degrees and returns the result.
77 | @warn_unused_result
78 | public func degrees(radians: float3) -> float3 {
79 | return radians * float3(57.295779513082320876798154814105)
80 | }
81 |
82 | /// Converts radians to degrees and returns the result.
83 | @warn_unused_result
84 | public func degrees(radians: float4) -> float4 {
85 | return radians * float4(57.295779513082320876798154814105)
86 | }
87 |
88 | /// Converts radians to degrees and returns the result.
89 | @warn_unused_result
90 | public func degrees(radians: Double) -> Double {
91 | return radians * Double(57.295779513082320876798154814105)
92 | }
93 |
94 | /// Converts radians to degrees and returns the result.
95 | @warn_unused_result
96 | public func degrees(radians: double2) -> double2 {
97 | return radians * double2(57.295779513082320876798154814105)
98 | }
99 |
100 | /// Converts radians to degrees and returns the result.
101 | @warn_unused_result
102 | public func degrees(radians: double3) -> double3 {
103 | return radians * double3(57.295779513082320876798154814105)
104 | }
105 |
106 | /// Converts radians to degrees and returns the result.
107 | @warn_unused_result
108 | public func degrees(radians: double4) -> double4 {
109 | return radians * double4(57.295779513082320876798154814105)
110 | }
111 |
112 | // MARK: sin
113 |
114 | /// The standard trigonometric sine function.
115 | /// The values returned by this function will range from [-1, 1].
116 | @warn_unused_result
117 | public func sin(v: float2) -> float2 {
118 | return float2(sin(v.x), sin(v.y))
119 | }
120 |
121 | /// The standard trigonometric sine function.
122 | /// The values returned by this function will range from [-1, 1].
123 | @warn_unused_result
124 | public func sin(v: float3) -> float3 {
125 | return float3(sin(v.x), sin(v.y), sin(v.z))
126 | }
127 |
128 | /// The standard trigonometric sine function.
129 | /// The values returned by this function will range from [-1, 1].
130 | @warn_unused_result
131 | public func sin(v: float4) -> float4 {
132 | return float4(sin(v.x), sin(v.y), sin(v.z), sin(v.w))
133 | }
134 |
135 | /// The standard trigonometric sine function.
136 | /// The values returned by this function will range from [-1, 1].
137 | @warn_unused_result
138 | public func sin(v: double2) -> double2 {
139 | return double2(sin(v.x), sin(v.y))
140 | }
141 |
142 | /// The standard trigonometric sine function.
143 | /// The values returned by this function will range from [-1, 1].
144 | @warn_unused_result
145 | public func sin(v: double3) -> double3 {
146 | return double3(sin(v.x), sin(v.y), sin(v.z))
147 | }
148 |
149 | /// The standard trigonometric sine function.
150 | /// The values returned by this function will range from [-1, 1].
151 | @warn_unused_result
152 | public func sin(v: double4) -> double4 {
153 | return double4(sin(v.x), sin(v.y), sin(v.z), sin(v.w))
154 | }
155 |
156 | // MARK: cos
157 |
158 | /// The standard trigonometric cosine function.
159 | /// The values returned by this function will range from [-1, 1].
160 | @warn_unused_result
161 | public func cos(v: float2) -> float2 {
162 | return float2(cos(v.x), cos(v.y))
163 | }
164 |
165 | /// The standard trigonometric cosine function.
166 | /// The values returned by this function will range from [-1, 1].
167 | @warn_unused_result
168 | public func cos(v: float3) -> float3 {
169 | return float3(cos(v.x), cos(v.y), cos(v.z))
170 | }
171 |
172 | /// The standard trigonometric cosine function.
173 | /// The values returned by this function will range from [-1, 1].
174 | @warn_unused_result
175 | public func cos(v: float4) -> float4 {
176 | return float4(cos(v.x), cos(v.y), cos(v.z), cos(v.w))
177 | }
178 |
179 | /// The standard trigonometric cosine function.
180 | /// The values returned by this function will range from [-1, 1].
181 | @warn_unused_result
182 | public func cos(v: double2) -> double2 {
183 | return double2(cos(v.x), cos(v.y))
184 | }
185 |
186 | /// The standard trigonometric cosine function.
187 | /// The values returned by this function will range from [-1, 1].
188 | @warn_unused_result
189 | public func cos(v: double3) -> double3 {
190 | return double3(cos(v.x), cos(v.y), cos(v.z))
191 | }
192 |
193 | /// The standard trigonometric cosine function.
194 | /// The values returned by this function will range from [-1, 1].
195 | @warn_unused_result
196 | public func cos(v: double4) -> double4 {
197 | return double4(cos(v.x), cos(v.y), cos(v.z), cos(v.w))
198 | }
199 |
200 | // TODO: tan
201 | // TODO: asin
202 | // TODO: acos
203 | // TODO: atan
204 | // TODO: sinh
205 | // TODO: cosh
206 | // TODO: tanh
207 | // TODO: asinh
208 | // TODO: acosh
209 | // TODO: atanh
210 |
211 |
--------------------------------------------------------------------------------
/Source/Exponential.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 14.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import simd
11 |
12 | // MARK: pow
13 |
14 | /// Returns 'base' raised to the power 'exp'.
15 | @warn_unused_result
16 | public func pow(base: float2, _ exp: float2) -> float2 {
17 | return float2(pow(base[0], exp[0]), pow(base[1], exp[1]))
18 | }
19 |
20 | /// Returns 'base' raised to the power 'exp'.
21 | @warn_unused_result
22 | public func pow(base: float3, _ exp: float3) -> float3 {
23 | return float3(pow(base[0], exp[0]), pow(base[1], exp[1]), pow(base[2], exp[2]))
24 | }
25 |
26 | /// Returns 'base' raised to the power 'exp'.
27 | @warn_unused_result
28 | public func pow(base: float4, _ exp: float4) -> float4 {
29 | return float4(pow(base[0], exp[0]), pow(base[1], exp[1]), pow(base[2], exp[2]), pow(base[3], exp[3]))
30 | }
31 |
32 | /// Returns 'base' raised to the power 'exp'.
33 | @warn_unused_result
34 | public func pow(base: double2, _ exp: double2) -> double2 {
35 | return double2(pow(base[0], exp[0]), pow(base[1], exp[1]))
36 | }
37 |
38 | /// Returns 'base' raised to the power 'exp'.
39 | @warn_unused_result
40 | public func pow(base: double3, _ exp: double3) -> double3 {
41 | return double3(pow(base[0], exp[0]), pow(base[1], exp[1]), pow(base[2], exp[2]))
42 | }
43 |
44 | /// Returns 'base' raised to the power 'exp'.
45 | @warn_unused_result
46 | public func pow(base: double4, _ exp: double4) -> double4 {
47 | return double4(pow(base[0], exp[0]), pow(base[1], exp[1]), pow(base[2], exp[2]), pow(base[3], exp[3]))
48 | }
49 |
50 | // MARK: exp
51 |
52 | /// Returns the natural exponentiation of x, i.e., e^x.
53 | @warn_unused_result
54 | public func exp(x: float2) -> float2 {
55 | return float2(exp(x[0]), exp(x[1]))
56 | }
57 |
58 | /// Returns the natural exponentiation of x, i.e., e^x.
59 | @warn_unused_result
60 | public func exp(x: float3) -> float3 {
61 | return float3(exp(x[0]), exp(x[1]), exp(x[2]))
62 | }
63 |
64 | /// Returns the natural exponentiation of x, i.e., e^x.
65 | @warn_unused_result
66 | public func exp(x: float4) -> float4 {
67 | return float4(exp(x[0]), exp(x[1]), exp(x[2]), exp(x[3]))
68 | }
69 |
70 | /// Returns the natural exponentiation of x, i.e., e^x.
71 | @warn_unused_result
72 | public func exp(x: double2) -> double2 {
73 | return double2(exp(x[0]), exp(x[1]))
74 | }
75 |
76 | /// Returns the natural exponentiation of x, i.e., e^x.
77 | @warn_unused_result
78 | public func exp(x: double3) -> double3 {
79 | return double3(exp(x[0]), exp(x[1]), exp(x[2]))
80 | }
81 |
82 | /// Returns the natural exponentiation of x, i.e., e^x.
83 | @warn_unused_result
84 | public func exp(x: double4) -> double4 {
85 | return double4(exp(x[0]), exp(x[1]), exp(x[2]), exp(x[3]))
86 | }
87 |
88 | // MARK: log
89 |
90 | /// Returns the natural logarithm of v, i.e.,
91 | /// Returns the value y which satisfies the equation x = e^y.
92 | /// Results are undefined if v <= 0.
93 | @warn_unused_result
94 | public func log(v: float2) -> float2 {
95 | return float2(log(v[0]), log(v[1]))
96 | }
97 |
98 | /// Returns the natural logarithm of v, i.e.,
99 | /// Returns the value y which satisfies the equation x = e^y.
100 | /// Results are undefined if v <= 0.
101 | @warn_unused_result
102 | public func log(v: float3) -> float3 {
103 | return float3(log(v[0]), log(v[1]), log(v[2]))
104 | }
105 |
106 | /// Returns the natural logarithm of v, i.e.,
107 | /// Returns the value y which satisfies the equation x = e^y.
108 | /// Results are undefined if v <= 0.
109 | @warn_unused_result
110 | public func log(v: float4) -> float4 {
111 | return float4(log(v[0]), log(v[1]), log(v[2]), log(v[3]))
112 | }
113 |
114 | /// Returns the natural logarithm of v, i.e.,
115 | /// Returns the value y which satisfies the equation x = e^y.
116 | /// Results are undefined if v <= 0.
117 | @warn_unused_result
118 | public func log(v: double2) -> double2 {
119 | return double2(log(v[0]), log(v[1]))
120 | }
121 |
122 | /// Returns the natural logarithm of v, i.e.,
123 | /// Returns the value y which satisfies the equation x = e^y.
124 | /// Results are undefined if v <= 0.
125 | @warn_unused_result
126 | public func log(v: double3) -> double3 {
127 | return double3(log(v[0]), log(v[1]), log(v[2]))
128 | }
129 |
130 | /// Returns the natural logarithm of v, i.e.,
131 | /// Returns the value y which satisfies the equation x = e^y.
132 | /// Results are undefined if v <= 0.
133 | @warn_unused_result
134 | public func log(v: double4) -> double4 {
135 | return double4(log(v[0]), log(v[1]), log(v[2]), log(v[3]))
136 | }
137 |
138 | // MARK: exp2
139 |
140 | /// Returns 2 raised to the v power.
141 | @warn_unused_result
142 | public func exp2(v: float2) -> float2 {
143 | return float2(exp2(v[0]), exp2(v[1]))
144 | }
145 |
146 | /// Returns 2 raised to the v power.
147 | @warn_unused_result
148 | public func exp2(v: float3) -> float3 {
149 | return float3(exp2(v[0]), exp2(v[1]), exp2(v[2]))
150 | }
151 |
152 | /// Returns 2 raised to the v power.
153 | @warn_unused_result
154 | public func exp2(v: float4) -> float4 {
155 | return float4(exp2(v[0]), exp2(v[1]), exp2(v[2]), exp2(v[3]))
156 | }
157 |
158 | /// Returns 2 raised to the v power.
159 | @warn_unused_result
160 | public func exp2(v: double2) -> double2 {
161 | return double2(exp2(v[0]), exp2(v[1]))
162 | }
163 |
164 | /// Returns 2 raised to the v power.
165 | @warn_unused_result
166 | public func exp2(v: double3) -> double3 {
167 | return double3(exp2(v[0]), exp2(v[1]), exp2(v[2]))
168 | }
169 |
170 | /// Returns 2 raised to the v power.
171 | @warn_unused_result
172 | public func exp2(v: double4) -> double4 {
173 | return double4(exp2(v[0]), exp2(v[1]), exp2(v[2]), exp2(v[3]))
174 | }
175 |
176 | // MARK: log2
177 |
178 | /// Returns the base 2 log of x, i.e., returns the value y,
179 | /// which satisfies the equation x = 2 ^ y.
180 | @warn_unused_result
181 | public func log2(x: float2) -> float2 {
182 | return float2(log2(x[0]), log2(x[1]))
183 | }
184 |
185 | /// Returns the base 2 log of x, i.e., returns the value y,
186 | /// which satisfies the equation x = 2 ^ y.
187 | @warn_unused_result
188 | public func log2(x: float3) -> float3 {
189 | return float3(log2(x[0]), log2(x[1]), log2(x[2]))
190 | }
191 |
192 | /// Returns the base 2 log of x, i.e., returns the value y,
193 | /// which satisfies the equation x = 2 ^ y.
194 | @warn_unused_result
195 | public func log2(x: float4) -> float4 {
196 | return float4(log2(x[0]), log2(x[1]), log2(x[2]), log2(x[3]))
197 | }
198 |
199 | /// Returns the base 2 log of x, i.e., returns the value y,
200 | /// which satisfies the equation x = 2 ^ y.
201 | @warn_unused_result
202 | public func log2(x: double2) -> double2 {
203 | return double2(log2(x[0]), log2(x[1]))
204 | }
205 |
206 | /// Returns the base 2 log of x, i.e., returns the value y,
207 | /// which satisfies the equation x = 2 ^ y.
208 | @warn_unused_result
209 | public func log2(x: double3) -> double3 {
210 | return double3(log2(x[0]), log2(x[1]), log2(x[2]))
211 | }
212 |
213 | /// Returns the base 2 log of x, i.e., returns the value y,
214 | /// which satisfies the equation x = 2 ^ y.
215 | @warn_unused_result
216 | public func log2(x: double4) -> double4 {
217 | return double4(log2(x[0]), log2(x[1]), log2(x[2]), log2(x[3]))
218 | }
219 |
220 | // MARK: sqrt
221 |
222 | /// Returns the positive square root of v.
223 | @warn_unused_result
224 | public func sqrt(v: float2) -> float2 {
225 | return float2(sqrt(v[0]), sqrt(v[1]))
226 | }
227 |
228 | /// Returns the positive square root of v.
229 | @warn_unused_result
230 | public func sqrt(v: float3) -> float3 {
231 | return float3(sqrt(v[0]), sqrt(v[1]), sqrt(v[2]))
232 | }
233 |
234 | /// Returns the positive square root of v.
235 | @warn_unused_result
236 | public func sqrt(v: float4) -> float4 {
237 | return float4(sqrt(v[0]), sqrt(v[1]), sqrt(v[2]), sqrt(v[3]))
238 | }
239 |
240 | /// Returns the positive square root of v.
241 | @warn_unused_result
242 | public func sqrt(v: double2) -> double2 {
243 | return double2(sqrt(v[0]), sqrt(v[1]))
244 | }
245 |
246 | /// Returns the positive square root of v.
247 | @warn_unused_result
248 | public func sqrt(v: double3) -> double3 {
249 | return double3(sqrt(v[0]), sqrt(v[1]), sqrt(v[2]))
250 | }
251 |
252 | /// Returns the positive square root of v.
253 | @warn_unused_result
254 | public func sqrt(v: double4) -> double4 {
255 | return double4(sqrt(v[0]), sqrt(v[1]), sqrt(v[2]), sqrt(v[3]))
256 | }
257 |
258 | // MARK: inversesqrt
259 |
260 | /// Returns the reciprocal of the positive square root of v.
261 | @warn_unused_result
262 | public func inversesqrt(v: float2) -> float2 {
263 | return float2(1) / sqrt(v)
264 | }
265 |
266 | /// Returns the reciprocal of the positive square root of v.
267 | @warn_unused_result
268 | public func inversesqrt(v: float3) -> float3 {
269 | return float3(1) / sqrt(v)
270 | }
271 |
272 | /// Returns the reciprocal of the positive square root of v.
273 | @warn_unused_result
274 | public func inversesqrt(v: float4) -> float4 {
275 | return float4(1) / sqrt(v)
276 | }
277 |
278 | /// Returns the reciprocal of the positive square root of v.
279 | @warn_unused_result
280 | public func inversesqrt(v: double2) -> double2 {
281 | return double2(1) / sqrt(v)
282 | }
283 |
284 | /// Returns the reciprocal of the positive square root of v.
285 | @warn_unused_result
286 | public func inversesqrt(v: double3) -> double3 {
287 | return double3(1) / sqrt(v)
288 | }
289 |
290 | /// Returns the reciprocal of the positive square root of v.
291 | @warn_unused_result
292 | public func inversesqrt(v: double4) -> double4 {
293 | return double4(1) / sqrt(v)
294 | }
--------------------------------------------------------------------------------
/Source/Matrix_Transform.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Matrix_Transform.swift
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 26.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import simd
11 |
12 | /// Builds a translation 4 * 4 matrix created from a vector of 3 components.
13 | @warn_unused_result
14 | public func translate(m: float4x4, v: float3) -> float4x4 {
15 | var result = m
16 | let vv = float4(v.x, v.y, v.z, 1)
17 | result[3] = m * vv
18 | return result
19 | }
20 |
21 | /// Builds a translation 4 * 4 matrix created from a vector of 3 components.
22 | @warn_unused_result
23 | public func translate(m: double4x4, v: double3) -> double4x4 {
24 | var result = m
25 | let vv = double4(v.x, v.y, v.z, 1)
26 | result[3] = m * vv
27 | return result
28 | }
29 |
30 | /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
31 | @warn_unused_result
32 | public func rotate(m: float4x4, angle: Float, axis: float3) -> float4x4 {
33 |
34 | let a = angle
35 | let c = cos(a)
36 | let s = sin(a)
37 |
38 | let v = normalize(axis)
39 | let temp = (1 - c) * v
40 |
41 | var Rotate = float4x4(0)
42 | Rotate[0][0] = c + temp[0] * v[0]
43 | Rotate[0][1] = 0 + temp[0] * v[1] + s * v[2]
44 | Rotate[0][2] = 0 + temp[0] * v[2] - s * v[1]
45 |
46 | Rotate[1][0] = 0 + temp[1] * v[0] - s * v[2]
47 | Rotate[1][1] = c + temp[1] * v[1]
48 | Rotate[1][2] = 0 + temp[1] * v[2] + s * v[0]
49 |
50 | Rotate[2][0] = 0 + temp[2] * v[0] + s * v[1]
51 | Rotate[2][1] = 0 + temp[2] * v[1] - s * v[0]
52 | Rotate[2][2] = c + temp[2] * v[2]
53 |
54 | var Result = float4x4(0)
55 | Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]
56 | Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]
57 | Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]
58 | Result[3] = m[3]
59 | return Result
60 | }
61 |
62 | /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
63 | @warn_unused_result
64 | public func rotate(m: double4x4, angle: Double, axis: double3) -> double4x4 {
65 |
66 | let a = angle
67 | let c = cos(a)
68 | let s = sin(a)
69 |
70 | let v = normalize(axis)
71 | let temp = (1 - c) * v
72 |
73 | var Rotate = double4x4(0)
74 | Rotate[0][0] = c + temp[0] * v[0]
75 | Rotate[0][1] = 0 + temp[0] * v[1] + s * v[2]
76 | Rotate[0][2] = 0 + temp[0] * v[2] - s * v[1]
77 |
78 | Rotate[1][0] = 0 + temp[1] * v[0] - s * v[2]
79 | Rotate[1][1] = c + temp[1] * v[1]
80 | Rotate[1][2] = 0 + temp[1] * v[2] + s * v[0]
81 |
82 | Rotate[2][0] = 0 + temp[2] * v[0] + s * v[1]
83 | Rotate[2][1] = 0 + temp[2] * v[1] - s * v[0]
84 | Rotate[2][2] = c + temp[2] * v[2]
85 |
86 | var Result = double4x4(0)
87 | Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]
88 | Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]
89 | Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]
90 | Result[3] = m[3]
91 | return Result
92 | }
93 |
94 | /// Builds a scale 4 * 4 matrix created from 3 scalars.
95 | @warn_unused_result
96 | public func scale(m: float4x4, v: float3) -> float4x4 {
97 | var Result = float4x4(0)
98 | Result[0] = m[0] * v[0];
99 | Result[1] = m[1] * v[1];
100 | Result[2] = m[2] * v[2];
101 | Result[3] = m[3];
102 | return Result;
103 | }
104 |
105 | /// Builds a scale 4 * 4 matrix created from 3 scalars.
106 | @warn_unused_result
107 | public func scale(m: double4x4, v: double3) -> double4x4 {
108 | var Result = double4x4(0)
109 | Result[0] = m[0] * v[0];
110 | Result[1] = m[1] * v[1];
111 | Result[2] = m[2] * v[2];
112 | Result[3] = m[3];
113 | return Result;
114 | }
115 |
116 | /// Creates a matrix for an orthographic parallel viewing volume.
117 | @warn_unused_result
118 | public func ortho(left: Float, right: Float, bottom: Float, top: Float, zNear: Float, zFar: Float) -> float4x4 {
119 | var Result = float4x4(1)
120 | Result[0][0] = Float(2) / (right - left)
121 | Result[1][1] = Float(2) / (top - bottom)
122 | Result[2][2] = -Float(2) / (zFar - zNear)
123 | Result[3][0] = -(right + left) / (right - left)
124 | Result[3][1] = -(top + bottom) / (top - bottom)
125 | Result[3][2] = -(zFar + zNear) / (zFar - zNear)
126 | return Result
127 | }
128 |
129 | /// Creates a matrix for projecting two-dimensional coordinates onto the screen.
130 | @warn_unused_result
131 | public func ortho(left: Float, right: Float, bottom: Float, top: Float) -> float4x4 {
132 | var Result = float4x4(1)
133 | Result[0][0] = Float(2) / (right - left)
134 | Result[1][1] = Float(2) / (top - bottom)
135 | Result[2][2] = -Float(1)
136 | Result[3][0] = -(right + left) / (right - left)
137 | Result[3][1] = -(top + bottom) / (top - bottom)
138 | return Result
139 | }
140 |
141 | /// Creates a matrix for an orthographic parallel viewing volume.
142 | @warn_unused_result
143 | public func ortho(left: Double, right: Double, bottom: Double, top: Double, zNear: Double, zFar: Double) -> double4x4 {
144 | var Result = double4x4(1)
145 | Result[0][0] = Double(2) / (right - left)
146 | Result[1][1] = Double(2) / (top - bottom)
147 | Result[2][2] = -Double(2) / (zFar - zNear)
148 | Result[3][0] = -(right + left) / (right - left)
149 | Result[3][1] = -(top + bottom) / (top - bottom)
150 | Result[3][2] = -(zFar + zNear) / (zFar - zNear)
151 | return Result
152 | }
153 |
154 | /// Creates a matrix for projecting two-dimensional coordinates onto the screen.
155 | @warn_unused_result
156 | public func ortho(left: Double, right: Double, bottom: Double, top: Double) -> double4x4 {
157 | var Result = double4x4(1)
158 | Result[0][0] = Double(2) / (right - left)
159 | Result[1][1] = Double(2) / (top - bottom)
160 | Result[2][2] = -Double(1)
161 | Result[3][0] = -(right + left) / (right - left)
162 | Result[3][1] = -(top + bottom) / (top - bottom)
163 | return Result
164 | }
165 |
166 | /// Creates a frustum matrix.
167 | @warn_unused_result
168 | public func frustum(left: Float, right: Float, bottom: Float, top: Float, near: Float, far: Float) -> float4x4 {
169 | var Result = float4x4(0)
170 | Result[0][0] = (Float(2) * near) / (right - left)
171 | Result[1][1] = (Float(2) * near) / (top - bottom)
172 | Result[2][0] = (right + left) / (right - left)
173 | Result[2][1] = (top + bottom) / (top - bottom)
174 | Result[2][2] = -(far + near) / (far - near)
175 | Result[2][3] = Float(-1)
176 | Result[3][2] = -(Float(2) * far * near) / (far - near)
177 | return Result
178 | }
179 |
180 | /// Creates a frustum matrix.
181 | @warn_unused_result
182 | public func frustum(left: Double, right: Double, bottom: Double, top: Double, near: Double, far: Double) -> double4x4 {
183 | var Result = double4x4(0)
184 | Result[0][0] = (Double(2) * near) / (right - left)
185 | Result[1][1] = (Double(2) * near) / (top - bottom)
186 | Result[2][0] = (right + left) / (right - left)
187 | Result[2][1] = (top + bottom) / (top - bottom)
188 | Result[2][2] = -(far + near) / (far - near)
189 | Result[2][3] = Double(-1)
190 | Result[3][2] = -(Double(2) * far * near) / (far - near)
191 | return Result
192 | }
193 |
194 | /// Creates a matrix for a symetric perspective-view.
195 | @warn_unused_result
196 | public func perspective(fovy: Float, aspect: Float, zNear: Float, zFar: Float) -> float4x4 {
197 |
198 | assert(abs(aspect) > Float(0), "")
199 |
200 | let tanHalfFovy = tan(fovy / Float(2))
201 |
202 | var Result = float4x4(0)
203 | Result[0][0] = Float(1) / (aspect * tanHalfFovy)
204 | Result[1][1] = Float(1) / (tanHalfFovy)
205 | Result[2][2] = -(zFar + zNear) / (zFar - zNear)
206 | Result[2][3] = -Float(1)
207 | Result[3][2] = -(Float(2) * zFar * zNear) / (zFar - zNear)
208 | return Result
209 | }
210 |
211 | /// Creates a matrix for a symetric perspective-view.
212 | @warn_unused_result
213 | public func perspective(fovy: Double, aspect: Double, zNear: Double, zFar: Double) -> double4x4 {
214 |
215 | assert(abs(aspect) > Double(0), "")
216 |
217 | let tanHalfFovy = tan(fovy / Double(2))
218 |
219 | var Result = double4x4(0)
220 | Result[0][0] = Double(1) / (aspect * tanHalfFovy)
221 | Result[1][1] = Double(1) / (tanHalfFovy)
222 | Result[2][2] = -(zFar + zNear) / (zFar - zNear)
223 | Result[2][3] = -Double(1)
224 | Result[3][2] = -(Double(2) * zFar * zNear) / (zFar - zNear)
225 | return Result
226 | }
227 |
228 | /// Builds a perspective projection matrix based on a field of view.
229 | @warn_unused_result
230 | public func perspectiveFov(fov: Float, width: Float, height: Float, zNear: Float, zFar: Float) -> float4x4 {
231 | assert(width > Float(0))
232 | assert(height > Float(0))
233 | assert(fov > Float(0))
234 |
235 | let rad = fov
236 | let h = cos(Float(0.5) * rad) / sin(Float(0.5) * rad)
237 | let w = h * height / width
238 |
239 | var Result = float4x4(0)
240 | Result[0][0] = w
241 | Result[1][1] = h
242 | Result[2][2] = -(zFar + zNear) / (zFar - zNear)
243 | Result[2][3] = -Float(1)
244 | Result[3][2] = -(Float(2) * zFar * zNear) / (zFar - zNear)
245 | return Result;
246 | }
247 |
248 | /// Builds a perspective projection matrix based on a field of view.
249 | @warn_unused_result
250 | public func perspectiveFov(fov: Double, width: Double, height: Double, zNear: Double, zFar: Double) -> double4x4 {
251 | assert(width > Double(0))
252 | assert(height > Double(0))
253 | assert(fov > Double(0))
254 |
255 | let rad = fov
256 | let h = cos(Double(0.5) * rad) / sin(Double(0.5) * rad)
257 | let w = h * height / width
258 |
259 | var Result = double4x4(0)
260 | Result[0][0] = w
261 | Result[1][1] = h
262 | Result[2][2] = -(zFar + zNear) / (zFar - zNear)
263 | Result[2][3] = -Double(1)
264 | Result[3][2] = -(Double(2) * zFar * zNear) / (zFar - zNear)
265 | return Result;
266 | }
267 |
268 | /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite.
269 | @warn_unused_result
270 | public func infinitePerspective(fovy : Float, aspect: Float, zNear : Float) -> float4x4 {
271 | let range = tan(fovy / Float(2)) * zNear;
272 | let left = -range * aspect;
273 | let right = range * aspect;
274 | let bottom = -range;
275 | let top = range;
276 |
277 | var Result = float4x4(0)
278 | Result[0][0] = (Float(2) * zNear) / (right - left);
279 | Result[1][1] = (Float(2) * zNear) / (top - bottom);
280 | Result[2][2] = -Float(1);
281 | Result[2][3] = -Float(1);
282 | Result[3][2] = -Float(2) * zNear;
283 | return Result;
284 | }
285 |
286 | /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite.
287 | @warn_unused_result
288 | public func infinitePerspective(fovy : Double, aspect: Double, zNear : Double) -> double4x4 {
289 | let range = tan(fovy / Double(2)) * zNear;
290 | let left = -range * aspect;
291 | let right = range * aspect;
292 | let bottom = -range;
293 | let top = range;
294 |
295 | var Result = double4x4(0)
296 | Result[0][0] = (Double(2) * zNear) / (right - left);
297 | Result[1][1] = (Double(2) * zNear) / (top - bottom);
298 | Result[2][2] = -Double(1);
299 | Result[2][3] = -Double(1);
300 | Result[3][2] = -Double(2) * zNear;
301 | return Result;
302 | }
303 |
304 | /// Build a look at view matrix.
305 | @warn_unused_result
306 | public func lookAt(eye: float3, center: float3, up: float3) -> float4x4 {
307 |
308 | let f = normalize(center - eye);
309 | let s = normalize(cross(f, up));
310 | let u = cross(s, f);
311 |
312 | var Result = float4x4(1);
313 | Result[0][0] = s.x;
314 | Result[1][0] = s.y;
315 | Result[2][0] = s.z;
316 | Result[0][1] = u.x;
317 | Result[1][1] = u.y;
318 | Result[2][1] = u.z;
319 | Result[0][2] = -f.x;
320 | Result[1][2] = -f.y;
321 | Result[2][2] = -f.z;
322 | Result[3][0] = -dot(s, eye);
323 | Result[3][1] = -dot(u, eye);
324 | Result[3][2] = dot(f, eye);
325 | return Result
326 | }
327 |
328 | /// Build a look at view matrix.
329 | @warn_unused_result
330 | public func lookAt(eye: double3, center: double3, up: double3) -> double4x4 {
331 |
332 | let f = normalize(center - eye);
333 | let s = normalize(cross(f, up));
334 | let u = cross(s, f);
335 |
336 | var Result = double4x4(1);
337 | Result[0][0] = s.x;
338 | Result[1][0] = s.y;
339 | Result[2][0] = s.z;
340 | Result[0][1] = u.x;
341 | Result[1][1] = u.y;
342 | Result[2][1] = u.z;
343 | Result[0][2] = -f.x;
344 | Result[1][2] = -f.y;
345 | Result[2][2] = -f.z;
346 | Result[3][0] = -dot(s, eye);
347 | Result[3][1] = -dot(u, eye);
348 | Result[3][2] = dot(f, eye);
349 | return Result
350 | }
351 |
352 |
353 |
--------------------------------------------------------------------------------
/Tests/glm-to-swift.h:
--------------------------------------------------------------------------------
1 | //
2 | // glm-to-swift.h
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 01.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface glm_to_swift : NSObject
13 |
14 | + (BOOL) fractFloat: (float) f withFractedFloat: (float) fractedF;
15 | + (BOOL) fractDouble: (double) f withFractedDouble: (double) fractedF;
16 |
17 | + (BOOL) roundFloat2: (vector_float2) v withRoundedFloat2: (vector_float2) roundedV;
18 | + (BOOL) roundFloat3: (vector_float3) v withRoundedFloat3: (vector_float3) roundedV;
19 | + (BOOL) roundFloat4: (vector_float4) v withRoundedFloat4: (vector_float4) roundedV;
20 | + (BOOL) roundDouble2: (vector_double2) v withRoundedDouble2: (vector_double2) roundedV;
21 | + (BOOL) roundDouble3: (vector_double3) v withRoundedDouble3: (vector_double3) roundedV;
22 | + (BOOL) roundDouble4: (vector_double4) v withRoundedDouble4: (vector_double4) roundedV;
23 |
24 | + (BOOL) roundEvenFloat: (float) f withRoundedFloat: (float) roundedF;
25 | + (BOOL) roundEvenFloat2: (vector_float2) f withRoundedFloat2: (vector_float2) roundedF;
26 | + (BOOL) roundEvenFloat3: (vector_float3) f withRoundedFloat3: (vector_float3) roundedF;
27 | + (BOOL) roundEvenFloat4: (vector_float4) f withRoundedFloat4: (vector_float4) roundedF;
28 | + (BOOL) roundEvenDouble: (double) f withRoundedDouble: (double) roundedF;
29 | + (BOOL) roundEvenDouble2: (vector_double2) f withRoundedDouble2: (vector_double2) roundedF;
30 | + (BOOL) roundEvenDouble3: (vector_double3) f withRoundedDouble3: (vector_double3) roundedF;
31 | + (BOOL) roundEvenDouble4: (vector_double4) f withRoundedDouble4: (vector_double4) roundedF;
32 |
33 | + (BOOL) modFloatX: (float) x andFloatY: (float) y withModdedFloat:(float) moddedF;
34 | + (BOOL) modFloat2X: (vector_float2) x andFloatY: (float) y withModdedFloat:(vector_float2) moddedF;
35 | + (BOOL) modFloat3X: (vector_float3) x andFloatY: (float) y withModdedFloat:(vector_float3) moddedF;
36 | + (BOOL) modFloat4X: (vector_float4) x andFloatY: (float) y withModdedFloat:(vector_float4) moddedF;
37 | + (BOOL) modFloat2X: (vector_float2) x andFloat2Y: (vector_float2) y withModdedFloat2:(vector_float2) moddedF;
38 | + (BOOL) modFloat3X: (vector_float3) x andFloat3Y: (vector_float3) y withModdedFloat3:(vector_float3) moddedF;
39 | + (BOOL) modFloat4X: (vector_float4) x andFloat4Y: (vector_float4) y withModdedFloat4:(vector_float4) moddedF;
40 |
41 | + (BOOL) modDoubleX: (double) x andDoubleY: (double) y withModdedDouble:(double) moddedF;
42 | + (BOOL) modDouble2X: (vector_double2) x andDoubleY: (double) y withModdedDouble:(vector_double2) moddedF;
43 | + (BOOL) modDouble3X: (vector_double3) x andDoubleY: (double) y withModdedDouble:(vector_double3) moddedF;
44 | + (BOOL) modDouble4X: (vector_double4) x andDoubleY: (double) y withModdedDouble:(vector_double4) moddedF;
45 | + (BOOL) modDouble2X: (vector_double2) x andDouble2Y: (vector_double2) y withModdedDouble2:(vector_double2) moddedF;
46 | + (BOOL) modDouble3X: (vector_double3) x andDouble3Y: (vector_double3) y withModdedDouble3:(vector_double3) moddedF;
47 | + (BOOL) modDouble4X: (vector_double4) x andDouble4Y: (vector_double4) y withModdedDouble4:(vector_double4) moddedF;
48 |
49 |
50 | + (BOOL) modfFloat: (float) f withIntegerPart: (float) integerPart andFractionalType: (float) fractionalType;
51 | + (BOOL) modfFloat2: (vector_float2) f withInteger2Part: (vector_float2) integerPart andFractional2Type: (vector_float2) fractionalType;
52 | + (BOOL) modfFloat3: (vector_float3) f withInteger3Part: (vector_float3) integerPart andFractional3Type: (vector_float3) fractionalType;
53 | + (BOOL) modfFloat4: (vector_float4) f withInteger4Part: (vector_float4) integerPart andFractional4Type: (vector_float4) fractionalType;
54 |
55 | + (BOOL) modfDouble: (double) f withIntegerPart: (double) integerPart andFractionalType: (double) fractionalType;
56 | + (BOOL) modfDouble2: (vector_double2) f withInteger2Part: (vector_double2) integerPart andFractional2Type: (vector_double2) fractionalType;
57 | + (BOOL) modfDouble3: (vector_double3) f withInteger3Part: (vector_double3) integerPart andFractional3Type: (vector_double3) fractionalType;
58 | + (BOOL) modfDouble4: (vector_double4) f withInteger4Part: (vector_double4) integerPart andFractional4Type: (vector_double4) fractionalType;
59 |
60 | + (BOOL) smooothstepFloat: (float) f withEdge0: (float) edge0 andWithEdge1: (float) edge1 withSmoothsteppedFloat: (float) smoothsteppedFloat;
61 | + (BOOL) smooothstepDouble: (double) f withEdge0: (double) edge0 andWithEdge1: (double) edge1 withSmoothsteppedDouble: (double) smoothsteppedDouble;
62 |
63 | + (BOOL) fmaFloat2a: (vector_float2) a andFloat2b: (vector_float2) b andFloat2c: (vector_float2) c withResultFloat2: (vector_float2) result;
64 | + (BOOL) fmaFloat3a: (vector_float3) a andFloat3b: (vector_float3) b andFloat3c: (vector_float3) c withResultFloat3: (vector_float3) result;
65 | + (BOOL) fmaFloat4a: (vector_float4) a andFloat4b: (vector_float4) b andFloat4c: (vector_float4) c withResultFloat4: (vector_float4) result;
66 | + (BOOL) fmaDouble2a: (vector_double2) a andDouble2b: (vector_double2) b andDouble2c: (vector_double2) c withResultDouble2: (vector_double2) result;
67 | + (BOOL) fmaDouble3a: (vector_double3) a andDouble3b: (vector_double3) b andDouble3c: (vector_double3) c withResultDouble3: (vector_double3) result;
68 | + (BOOL) fmaDouble4a: (vector_double4) a andDouble4b: (vector_double4) b andDouble4c: (vector_double4) c withResultDouble4: (vector_double4) result;
69 |
70 | + (BOOL) frexp: (vector_float2) value withValFloat2:(vector_float2) val andExponent2: (vector_int2) exp;
71 | + (BOOL) frexp: (vector_float3) value withValFloat3:(vector_float3) val andExponent3: (vector_int3) exp;
72 | + (BOOL) frexp: (vector_float4) value withValFloat4:(vector_float4) val andExponent4: (vector_int4) exp;
73 | + (BOOL) frexp: (vector_double2) value withValDouble2:(vector_double2) val andExponent2: (vector_int2) exp;
74 | + (BOOL) frexp: (vector_double3) value withValDouble3:(vector_double3) val andExponent3: (vector_int3) exp;
75 | + (BOOL) frexp: (vector_double4) value withValDouble4:(vector_double4) val andExponent4: (vector_int4) exp;
76 |
77 | +(BOOL) pow:(vector_float2) base withPowerFloat2:(vector_float2) exp andResult:(vector_float2) result;
78 | +(BOOL) pow:(vector_float3) base withPowerFloat3:(vector_float3) exp andResult:(vector_float3) result;
79 | +(BOOL) pow:(vector_float4) base withPowerFloat4:(vector_float4) exp andResult:(vector_float4) result;
80 | +(BOOL) pow:(vector_double2) base withPowerDouble2:(vector_double2) exp andResult:(vector_double2) result;
81 | +(BOOL) pow:(vector_double3) base withPowerDouble3:(vector_double3) exp andResult:(vector_double3) result;
82 | +(BOOL) pow:(vector_double4) base withPowerDouble4:(vector_double4) exp andResult:(vector_double4) result;
83 |
84 | +(BOOL) expFloat2:(vector_float2) x andResult:(vector_float2) result;
85 | +(BOOL) expFloat3:(vector_float3) x andResult:(vector_float3) result;
86 | +(BOOL) expFloat4:(vector_float4) x andResult:(vector_float4) result;
87 | +(BOOL) expDouble2:(vector_double2) x andResult:(vector_double2) result;
88 | +(BOOL) expDouble3:(vector_double3) x andResult:(vector_double3) result;
89 | +(BOOL) expDouble4:(vector_double4) x andResult:(vector_double4) result;
90 |
91 | +(BOOL) logFloat2:(vector_float2) x andResult:(vector_float2) result;
92 | +(BOOL) logFloat3:(vector_float3) x andResult:(vector_float3) result;
93 | +(BOOL) logFloat4:(vector_float4) x andResult:(vector_float4) result;
94 | +(BOOL) logDouble2:(vector_double2) x andResult:(vector_double2) result;
95 | +(BOOL) logDouble3:(vector_double3) x andResult:(vector_double3) result;
96 | +(BOOL) logDouble4:(vector_double4) x andResult:(vector_double4) result;
97 |
98 | +(BOOL) exp2Float2:(vector_float2) x andResult:(vector_float2) result;
99 | +(BOOL) exp2Float3:(vector_float3) x andResult:(vector_float3) result;
100 | +(BOOL) exp2Float4:(vector_float4) x andResult:(vector_float4) result;
101 | +(BOOL) exp2Double2:(vector_double2) x andResult:(vector_double2) result;
102 | +(BOOL) exp2Double3:(vector_double3) x andResult:(vector_double3) result;
103 | +(BOOL) exp2Double4:(vector_double4) x andResult:(vector_double4) result;
104 |
105 | +(BOOL) log2Float2:(vector_float2) x andResult:(vector_float2) result;
106 | +(BOOL) log2Float3:(vector_float3) x andResult:(vector_float3) result;
107 | +(BOOL) log2Float4:(vector_float4) x andResult:(vector_float4) result;
108 | +(BOOL) log2Double2:(vector_double2) x andResult:(vector_double2) result;
109 | +(BOOL) log2Double3:(vector_double3) x andResult:(vector_double3) result;
110 | +(BOOL) log2Double4:(vector_double4) x andResult:(vector_double4) result;
111 |
112 | +(BOOL) sqrtFloat2:(vector_float2) x andResult:(vector_float2) result;
113 | +(BOOL) sqrtFloat3:(vector_float3) x andResult:(vector_float3) result;
114 | +(BOOL) sqrtFloat4:(vector_float4) x andResult:(vector_float4) result;
115 | +(BOOL) sqrtDouble2:(vector_double2) x andResult:(vector_double2) result;
116 | +(BOOL) sqrtDouble3:(vector_double3) x andResult:(vector_double3) result;
117 | +(BOOL) sqrtDouble4:(vector_double4) x andResult:(vector_double4) result;
118 |
119 | +(BOOL) inversesqrtFloat2:(vector_float2) x andResult:(vector_float2) result;
120 | +(BOOL) inversesqrtFloat3:(vector_float3) x andResult:(vector_float3) result;
121 | +(BOOL) inversesqrtFloat4:(vector_float4) x andResult:(vector_float4) result;
122 | +(BOOL) inversesqrtDouble2:(vector_double2) x andResult:(vector_double2) result;
123 | +(BOOL) inversesqrtDouble3:(vector_double3) x andResult:(vector_double3) result;
124 | +(BOOL) inversesqrtDouble4:(vector_double4) x andResult:(vector_double4) result;
125 |
126 | +(BOOL) faceforward:(vector_float2) N withI:(vector_float2) i withNref:(vector_float2) nRef andResultFloat2:(vector_float2) result;
127 | +(BOOL) faceforward:(vector_float3) N withI:(vector_float3) i withNref:(vector_float3) nRef andResultFloat3:(vector_float3) result;
128 | +(BOOL) faceforward:(vector_float4) N withI:(vector_float4) i withNref:(vector_float4) nRef andResultFloat4:(vector_float4) result;
129 | +(BOOL) faceforward:(vector_double2) N withI:(vector_double2) i withNref:(vector_double2) nRef andResultDouble2:(vector_double2) result;
130 | +(BOOL) faceforward:(vector_double3) N withI:(vector_double3) i withNref:(vector_double3) nRef andResultDouble3:(vector_double3) result;
131 | +(BOOL) faceforward:(vector_double4) N withI:(vector_double4) i withNref:(vector_double4) nRef andResultDouble4:(vector_double4) result;
132 |
133 | +(BOOL) determinant:(matrix_float2x2) M andResultFloat2x2:(float) result;
134 | +(BOOL) determinant:(matrix_float3x3) M andResultFloat3x3:(float) result;
135 | +(BOOL) determinant:(matrix_float4x4) M andResultFloat4x4:(float) result;
136 | +(BOOL) determinant:(matrix_double2x2) M andResultDouble2x2:(double) result;
137 | +(BOOL) determinant:(matrix_double3x3) M andResultDouble3x3:(double) result;
138 | +(BOOL) determinant:(matrix_double4x4) M andResultDouble4x4:(double) result;
139 |
140 | +(BOOL) radiansFromDegrees:(float) degrees floatWithResult:(float) result;
141 | +(BOOL) radiansFromDegrees:(vector_float2) degrees float2WithResult:(vector_float2) result;
142 | +(BOOL) radiansFromDegrees:(vector_float3) degrees float3WithResult:(vector_float3) result;
143 | +(BOOL) radiansFromDegrees:(vector_float4) degrees float4WithResult:(vector_float4) result;
144 | +(BOOL) radiansFromDegrees:(double) degrees doubleWithResult:(double) result;
145 | +(BOOL) radiansFromDegrees:(vector_double2) degrees double2WithResult:(vector_double2) result;
146 | +(BOOL) radiansFromDegrees:(vector_double3) degrees double3WithResult:(vector_double3) result;
147 | +(BOOL) radiansFromDegrees:(vector_double4) degrees double4WithResult:(vector_double4) result;
148 |
149 | +(BOOL) degreesFromRadians:(float) degrees floatWithResult:(float) result;
150 | +(BOOL) degreesFromRadians:(vector_float2) degrees float2WithResult:(vector_float2) result;
151 | +(BOOL) degreesFromRadians:(vector_float3) degrees float3WithResult:(vector_float3) result;
152 | +(BOOL) degreesFromRadians:(vector_float4) degrees float4WithResult:(vector_float4) result;
153 | +(BOOL) degreesFromRadians:(double) degrees doubleWithResult:(double) result;
154 | +(BOOL) degreesFromRadians:(vector_double2) degrees double2WithResult:(vector_double2) result;
155 | +(BOOL) degreesFromRadians:(vector_double3) degrees double3WithResult:(vector_double3) result;
156 | +(BOOL) degreesFromRadians:(vector_double4) degrees double4WithResult:(vector_double4) result;
157 |
158 | +(BOOL) translateFloat:(matrix_float4x4) m withVector:(vector_float3) v withResult:(matrix_float4x4) result;
159 | +(BOOL) translateDouble:(matrix_double4x4) m withVector:(vector_double3) v withResult:(matrix_double4x4) result;
160 |
161 | +(BOOL) rotateFloat:(matrix_float4x4)m withAngle:(float) angle withAxis:(vector_float3) axis andResult:(matrix_float4x4) result;
162 | +(BOOL) rotateDouble:(matrix_double4x4)m withAngle:(double) angle withAxis:(vector_double3) axis andResult:(matrix_double4x4) result;
163 |
164 | +(BOOL) scaleFloat:(matrix_float4x4)m withVector:(vector_float3) v andResult:(matrix_float4x4) result;
165 | +(BOOL) scaleDouble:(matrix_double4x4)m withVector:(vector_double3) v andResult:(matrix_double4x4) result;
166 |
167 | +(BOOL) orthoFloat:(float)left withRight:(float)right withBottom:(float)bottom withTop:(float)top withZNear:(float)zNear withZFar:(float)zFar andResult:(matrix_float4x4) result;
168 | +(BOOL) orthoFloat:(float)left withRight:(float)right withBottom:(float)bottom withTop:(float)top andResult:(matrix_float4x4) result;
169 | +(BOOL) orthoDouble:(double)left withRight:(double)right withBottom:(double)bottom withTop:(double)top withZNear:(double)zNear withZFar:(double)zFar andResult:(matrix_double4x4) result;
170 | +(BOOL) orthoDouble:(double)left withRight:(double)right withBottom:(double)bottom withTop:(double)top andResult:(matrix_double4x4) result;
171 |
172 | +(BOOL) frustumFloat:(float)left withRight:(float)right withBottom:(float)bottom withTop:(float)top withNear:(float)near withFar:(float)far andResult:(matrix_float4x4) result;
173 | +(BOOL) frustumDouble:(double)left withRight:(double)right withBottom:(double)bottom withTop:(double)top withNear:(double)near withFar:(double)far andResult:(matrix_double4x4) result;
174 |
175 | +(BOOL) perspectiveFloat:(float)fovy withAspect:(float)aspect withZNear:(float)zNear withZFar:(float) zFar andResult:(matrix_float4x4) result;
176 | +(BOOL) perspectiveDouble:(double)fovy withAspect:(double)aspect withZNear:(double)zNear withZFar:(double) zFar andResult:(matrix_double4x4) result;
177 |
178 | +(BOOL) perspectiveFovFloat:(float)fovy withWidth:(float)width withHeight:(float)height withZNear:(float)zNear withZFar:(float) zFar andResult:(matrix_float4x4) result;
179 | +(BOOL) perspectiveFovDouble:(double)fovy withWidth:(double)width withHeight:(double)height withZNear:(double)zNear withZFar:(double) zFar andResult:(matrix_double4x4) result;
180 |
181 | +(BOOL) infinitePerspectiveFloat:(float)fovy withAspect:(float)aspect withZNear:(float)zNear andResult:(matrix_float4x4) result;
182 | +(BOOL) infinitePerspectiveDouble:(double)fovy withAspect:(double)aspect withZNear:(double)zNear andResult:(matrix_double4x4) result;
183 |
184 | +(BOOL) lookAtFloat:(vector_float3) eye withCenter:(vector_float3) center withUp:(vector_float3) up andResult:(matrix_float4x4) result;
185 | +(BOOL) lookAtDouble:(vector_double3) eye withCenter:(vector_double3) center withUp:(vector_double3) up andResult:(matrix_double4x4) result;
186 |
187 | @end
188 |
--------------------------------------------------------------------------------
/Source/Common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // common.swift
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 01.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import simd
11 |
12 | // MARK: clamp
13 |
14 | /// Clamp `x` to the range [`min`, max]. If lane of `x` is
15 | /// NaN, the result is `min`.
16 | @warn_unused_result
17 | public func clamp(value: Float, lower: Float, upper: Float) -> Float {
18 | return min(max(value, lower), upper)
19 | }
20 |
21 | /// Clamp `x` to the range [`min`, max]. If lane of `x` is
22 | /// NaN, the result is `min`.
23 | @warn_unused_result
24 | public func clamp(value: Double, lower: Double, upper: Double) -> Double {
25 | return min(max(value, lower), upper)
26 | }
27 |
28 | // MARK: - fract
29 |
30 | /// `x - floor(x)`, clamped to lie in the range [0,1). Without this clamp step,
31 | /// the result would be 1.0 when `x` is a very small negative number, which may
32 | /// result in out-of-bounds table accesses in common usage.
33 | @warn_unused_result
34 | public func fract(x: Float) -> Float {
35 | return clamp(x - floor(x), lower: 0.0, upper: 1.0)
36 | }
37 |
38 | /// `x - floor(x)`, clamped to lie in the range [0,1). Without this clamp step,
39 | /// the result would be 1.0 when `x` is a very small negative number, which may
40 | /// result in out-of-bounds table accesses in common usage.
41 | @warn_unused_result
42 | public func fract(x: Double) -> Double {
43 | return clamp(x - floor(x), lower: 0.0, upper: 1.0)
44 | }
45 |
46 | // MARK: - round
47 |
48 | /// Returns a value equal to the nearest integer to x.
49 | @warn_unused_result
50 | public func round(x: float2) -> float2 {
51 | return float2(round(x[0]), round(x[1]))
52 | }
53 |
54 | /// Returns a value equal to the nearest integer to x.
55 | @warn_unused_result
56 | public func round(x: float3) -> float3 {
57 | return float3(round(x[0]), round(x[1]), round(x[2]))
58 | }
59 |
60 | /// Returns a value equal to the nearest integer to x.
61 | @warn_unused_result
62 | public func round(x: float4) -> float4 {
63 | return float4(round(x[0]), round(x[1]), round(x[2]), round(x[3]))
64 | }
65 |
66 | /// Returns a value equal to the nearest integer to x.
67 | @warn_unused_result
68 | public func round(x: double2) -> double2 {
69 | return double2(round(x[0]), round(x[1]))
70 | }
71 |
72 | /// Returns a value equal to the nearest integer to x.
73 | @warn_unused_result
74 | public func round(x: double3) -> double3 {
75 | return double3(round(x[0]), round(x[1]), round(x[2]))
76 | }
77 |
78 | /// Returns a value equal to the nearest integer to x.
79 | @warn_unused_result
80 | public func round(x: double4) -> double4 {
81 | return double4(round(x[0]), round(x[1]), round(x[2]), round(x[3]))
82 | }
83 |
84 | // MARK: - roundEven
85 |
86 | /// Returns a value equal to the nearest integer to x.
87 | /// A fractional part of 0.5 will round toward the nearest even
88 | /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
89 | @warn_unused_result
90 | public func roundEven(x: Float) -> Float {
91 | let fractionalPart = fract(x)
92 | let integer = Int(x)
93 | let integerPart = Float(integer)
94 |
95 | if(fractionalPart > 0.5 || fractionalPart < 0.5) {
96 | return round(x)
97 | } else if ((integer % 2) == 0) {
98 | return integerPart
99 | } else if (x <= 0) {
100 | return integerPart - 1
101 | } else {
102 | return integerPart + 1
103 | }
104 | }
105 |
106 | /// Returns a value equal to the nearest integer to x.
107 | /// A fractional part of 0.5 will round toward the nearest even
108 | /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
109 | @warn_unused_result
110 | public func roundEven(x: float2) -> float2 {
111 | return float2(roundEven(x[0]), roundEven(x[1]))
112 | }
113 |
114 | /// Returns a value equal to the nearest integer to x.
115 | /// A fractional part of 0.5 will round toward the nearest even
116 | /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
117 | @warn_unused_result
118 | public func roundEven(x: float3) -> float3 {
119 | return float3(roundEven(x[0]), roundEven(x[1]), roundEven(x[2]))
120 | }
121 |
122 | /// Returns a value equal to the nearest integer to x.
123 | /// A fractional part of 0.5 will round toward the nearest even
124 | /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
125 | @warn_unused_result
126 | public func roundEven(x: float4) -> float4 {
127 | return float4(roundEven(x[0]), roundEven(x[1]), roundEven(x[2]), roundEven(x[3]))
128 | }
129 |
130 | /// Returns a value equal to the nearest integer to x.
131 | /// A fractional part of 0.5 will round toward the nearest even
132 | /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
133 | @warn_unused_result
134 | public func roundEven(x: Double) -> Double {
135 | let fractionalPart = fract(x)
136 | let integer = Int(x)
137 | let integerPart = Double(integer)
138 |
139 | if(fractionalPart > 0.5 || fractionalPart < 0.5) {
140 | return round(x)
141 | } else if ((integer % 2) == 0) {
142 | return integerPart
143 | } else if (x <= 0) {
144 | return integerPart - 1
145 | } else {
146 | return integerPart + 1
147 | }
148 | }
149 |
150 | /// Returns a value equal to the nearest integer to x.
151 | /// A fractional part of 0.5 will round toward the nearest even
152 | /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
153 | @warn_unused_result
154 | public func roundEven(x: double2) -> double2 {
155 | return double2(roundEven(x[0]), roundEven(x[1]))
156 | }
157 |
158 | /// Returns a value equal to the nearest integer to x.
159 | /// A fractional part of 0.5 will round toward the nearest even
160 | /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
161 | @warn_unused_result
162 | public func roundEven(x: double3) -> double3 {
163 | return double3(roundEven(x[0]), roundEven(x[1]), roundEven(x[2]))
164 | }
165 |
166 | /// Returns a value equal to the nearest integer to x.
167 | /// A fractional part of 0.5 will round toward the nearest even
168 | /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
169 | @warn_unused_result
170 | public func roundEven(x: double4) -> double4 {
171 | return double4(roundEven(x[0]), roundEven(x[1]), roundEven(x[2]), roundEven(x[3]))
172 | }
173 |
174 | // MARK: - mod
175 |
176 | /// Modulus. Returns x - y * floor(x / y)
177 | /// for each component in x using the floating point value y.
178 | @warn_unused_result
179 | public func mod(x: Float, _ y: Float) -> Float {
180 | return x-y * floor(x/y)
181 | }
182 |
183 | /// Modulus. Returns x - y * floor(x / y)
184 | /// for each component in x using the floating point value y.
185 | @warn_unused_result
186 | public func mod(x: float2, _ y: Float) -> float2 {
187 | return float2(mod(x[0], y), mod(x[1], y))
188 | }
189 |
190 | /// Modulus. Returns x - y * floor(x / y)
191 | /// for each component in x using the floating point value y.
192 | @warn_unused_result
193 | public func mod(x: float3, _ y: Float) -> float3 {
194 | return float3(mod(x[0], y), mod(x[1], y), mod(x[2], y))
195 | }
196 |
197 | /// Modulus. Returns x - y * floor(x / y)
198 | /// for each component in x using the floating point value y.
199 | @warn_unused_result
200 | public func mod(x: float4, _ y: Float) -> float4 {
201 | return float4(mod(x[0], y), mod(x[1], y), mod(x[2], y), mod(x[3], y))
202 | }
203 |
204 | /// Modulus. Returns x - y * floor(x / y)
205 | /// for each component in x using the floating point value y.
206 | @warn_unused_result
207 | public func mod(x: float2, _ y: float2) -> float2 {
208 | return float2(mod(x[0], y[0]), mod(x[1], y[1]))
209 | }
210 |
211 | /// Modulus. Returns x - y * floor(x / y)
212 | /// for each component in x using the floating point value y.
213 | @warn_unused_result
214 | public func mod(x: float3, _ y: float3) -> float3 {
215 | return float3(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2]))
216 | }
217 |
218 | /// Modulus. Returns x - y * floor(x / y)
219 | /// for each component in x using the floating point value y.
220 | @warn_unused_result
221 | public func mod(x: float4, _ y: float4) -> float4 {
222 | return float4(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2]), mod(x[3], y[3]))
223 | }
224 |
225 | /// Modulus. Returns x - y * floor(x / y)
226 | /// for each component in x using the floating point value y.
227 | @warn_unused_result
228 | public func mod(x: Double, _ y: Double) -> Double {
229 | return x-y * floor(x/y)
230 | }
231 |
232 | /// Modulus. Returns x - y * floor(x / y)
233 | /// for each component in x using the floating point value y.
234 | @warn_unused_result
235 | public func mod(x: double2, _ y: Double) -> double2 {
236 | return double2(mod(x[0], y), mod(x[1], y))
237 | }
238 |
239 | /// Modulus. Returns x - y * floor(x / y)
240 | /// for each component in x using the floating point value y.
241 | @warn_unused_result
242 | public func mod(x: double3, _ y: Double) -> double3 {
243 | return double3(mod(x[0], y), mod(x[1], y), mod(x[2], y))
244 | }
245 |
246 | /// Modulus. Returns x - y * floor(x / y)
247 | /// for each component in x using the floating point value y.
248 | @warn_unused_result
249 | public func mod(x: double4, _ y: Double) -> double4 {
250 | return double4(mod(x[0], y), mod(x[1], y), mod(x[2], y), mod(x[3], y))
251 | }
252 |
253 | /// Modulus. Returns x - y * floor(x / y)
254 | /// for each component in x using the floating point value y.
255 | @warn_unused_result
256 | public func mod(x: double2, _ y: double2) -> double2 {
257 | return double2(mod(x[0], y[0]), mod(x[1], y[1]))
258 | }
259 |
260 | /// Modulus. Returns x - y * floor(x / y)
261 | /// for each component in x using the floating point value y.
262 | public func mod(x: double3, _ y: double3) -> double3 {
263 | return double3(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2]))
264 | }
265 |
266 | /// Modulus. Returns x - y * floor(x / y)
267 | /// for each component in x using the floating point value y.
268 | @warn_unused_result
269 | public func mod(x: double4, _ y: double4) -> double4 {
270 | return double4(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2]), mod(x[3], y[3]))
271 | }
272 |
273 | // MARK: - modf
274 |
275 | /// Returns the integer (as a whole number floating point value) and fractional
276 | /// part of x. Both the return values will have the same sign as x.
277 | @warn_unused_result
278 | public func modf(x: float2) -> (float2, float2) {
279 | let y = trunc(x)
280 | return (y, x - y)
281 | }
282 |
283 | /// Returns the integer (as a whole number floating point value) and fractional
284 | /// part of x. Both the return values will have the same sign as x.
285 | @warn_unused_result
286 | public func modf(x: float3) -> (float3, float3) {
287 | let y = trunc(x)
288 | return (y, x - y)
289 | }
290 |
291 | /// Returns the integer (as a whole number floating point value) and fractional
292 | /// part of x. Both the return values will have the same sign as x.
293 | @warn_unused_result
294 | public func modf(x: float4) -> (float4, float4) {
295 | let y = trunc(x)
296 | return (y, x - y)
297 | }
298 |
299 | /// Returns the integer (as a whole number floating point value) and fractional
300 | /// part of x. Both the return values will have the same sign as x.
301 | @warn_unused_result
302 | public func modf(x: double2) -> (double2, double2) {
303 | let y = trunc(x)
304 | return (y, x - y)
305 | }
306 |
307 | /// Returns the integer (as a whole number floating point value) and fractional
308 | /// part of x. Both the return values will have the same sign as x.
309 | @warn_unused_result
310 | public func modf(x: double3) -> (double3, double3) {
311 | let y = trunc(x)
312 | return (y, x - y)
313 | }
314 |
315 | /// Returns the integer (as a whole number floating point value) and fractional
316 | /// part of x. Both the return values will have the same sign as x.
317 | @warn_unused_result
318 | public func modf(x: double4) -> (double4, double4) {
319 | let y = trunc(x)
320 | return (y, x - y)
321 | }
322 |
323 | // MARK: - mix
324 |
325 | /// Returns x * (1.0 - t) + y * t, i.e., the linear blend of
326 | /// x and y using the floating-point value a.
327 | /// The value for t is not restricted to the range [0, 1].
328 | @warn_unused_result
329 | public func mix(x: Float, _ y: Float, _ t: Float) -> Float {
330 | return x + t * (y - x)
331 | }
332 |
333 | /// Returns x * (1.0 - t) + y * t, i.e., the linear blend of
334 | /// x and y using the floating-point value a.
335 | /// The value for t is not restricted to the range [0, 1].
336 | @warn_unused_result
337 | public func mix(x: Double, _ y: Double, _ t: Double) -> Double {
338 | return x + t * (y - x)
339 | }
340 |
341 | // MARK: - smoothstep
342 |
343 | /// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
344 | /// performs smooth Hermite interpolation between 0 and 1
345 | /// when edge0 < x < edge1. This is useful in cases where
346 | /// you would want a threshold function with a smooth
347 | @warn_unused_result
348 | public func smoothstep(x: Float, edge0: Float, edge1: Float) -> Float {
349 | let t = clamp ((x - edge0) / (edge1 - edge0), lower: 0, upper: 1)
350 | return t * t * (3 - 2 * t);
351 | }
352 |
353 | /// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
354 | /// performs smooth Hermite interpolation between 0 and 1
355 | /// when edge0 < x < edge1. This is useful in cases where
356 | /// you would want a threshold function with a smooth
357 | @warn_unused_result
358 | public func smoothstep(x: Double, edge0: Double, edge1: Double) -> Double {
359 | let t = clamp ((x - edge0) / (edge1 - edge0), lower: 0, upper: 1)
360 | return t * t * (3 - 2 * t);
361 | }
362 |
363 | // MARK: - fma
364 |
365 | /// Computes and returns a * b + c.
366 | @warn_unused_result
367 | public func fma(a: float2, b: float2, c: float2) -> float2 {
368 | return float2(fma(a[0], b[0], c[0]), fma(a[1], b[1], c[1]))
369 | }
370 |
371 | /// Computes and returns a * b + c.
372 | @warn_unused_result
373 | public func fma(a: float3, b: float3, c: float3) -> float3 {
374 | return float3(fma(a[0], b[0], c[0]), fma(a[1], b[1], c[1]), fma(a[2], b[2], c[2]))
375 | }
376 |
377 | /// Computes and returns a * b + c.
378 | @warn_unused_result
379 | public func fma(a: float4, b: float4, c: float4) -> float4 {
380 | return float4(fma(a[0], b[0], c[0]), fma(a[1], b[1], c[1]), fma(a[2], b[2], c[2]), fma(a[3], b[3], c[3]))
381 | }
382 |
383 | /// Computes and returns a * b + c.
384 | @warn_unused_result
385 | public func fma(a: double2, b: double2, c: double2) -> double2 {
386 | return double2(fma(a[0], b[0], c[0]), fma(a[1], b[1], c[1]))
387 | }
388 |
389 | /// Computes and returns a * b + c.
390 | @warn_unused_result
391 | public func fma(a: double3, b: double3, c: double3) -> double3 {
392 | return double3(fma(a[0], b[0], c[0]), fma(a[1], b[1], c[1]), fma(a[2], b[2], c[2]))
393 | }
394 |
395 | /// Computes and returns a * b + c.
396 | @warn_unused_result
397 | public func fma(a: double4, b: double4, c: double4) -> double4 {
398 | return double4(fma(a[0], b[0], c[0]), fma(a[1], b[1], c[1]), fma(a[2], b[2], c[2]), fma(a[3], b[3], c[3]))
399 | }
400 |
401 | // MARK: - frexp
402 |
403 | /// Splits x into a floating-point significand in the range
404 | /// [0.5, 1.0) and an integral exponent of two, such that:
405 | /// x = significand * exp(2, exponent)
406 | @warn_unused_result
407 | public func frexp(x: float2) -> (float2, int2) {
408 | let f1 = frexp(x[0])
409 | let f2 = frexp(x[1])
410 | return (float2(f1.0, f2.0), int2(Int32(f1.1), Int32(f2.1)))
411 | }
412 |
413 | /// Splits x into a floating-point significand in the range
414 | /// [0.5, 1.0) and an integral exponent of two, such that:
415 | /// x = significand * exp(2, exponent)
416 | @warn_unused_result
417 | public func frexp(x: float3) -> (float3, int3) {
418 | let f1 = frexp(x[0])
419 | let f2 = frexp(x[1])
420 | let f3 = frexp(x[2])
421 | return (float3(f1.0, f2.0, f3.0), int3(Int32(f1.1), Int32(f2.1), Int32(f3.1)))
422 | }
423 |
424 | /// Splits x into a floating-point significand in the range
425 | /// [0.5, 1.0) and an integral exponent of two, such that:
426 | /// x = significand * exp(2, exponent)
427 | @warn_unused_result
428 | public func frexp(x: float4) -> (float4, int4) {
429 | let f1 = frexp(x[0])
430 | let f2 = frexp(x[1])
431 | let f3 = frexp(x[2])
432 | let f4 = frexp(x[3])
433 | return (float4(f1.0, f2.0, f3.0, f4.0), int4(Int32(f1.1), Int32(f2.1), Int32(f3.1), Int32(f4.1)))
434 | }
435 |
436 | /// Splits x into a floating-point significand in the range
437 | /// [0.5, 1.0) and an integral exponent of two, such that:
438 | /// x = significand * exp(2, exponent)
439 | @warn_unused_result
440 | public func frexp(x: double2) -> (double2, int2) {
441 | let f1 = frexp(x[0])
442 | let f2 = frexp(x[1])
443 | return (double2(f1.0, f2.0), int2(Int32(f1.1), Int32(f2.1)))
444 | }
445 |
446 | /// Splits x into a floating-point significand in the range
447 | /// [0.5, 1.0) and an integral exponent of two, such that:
448 | /// x = significand * exp(2, exponent)
449 | @warn_unused_result
450 | public func frexp(x: double3) -> (double3, int3) {
451 | let f1 = frexp(x[0])
452 | let f2 = frexp(x[1])
453 | let f3 = frexp(x[2])
454 | return (double3(f1.0, f2.0, f3.0), int3(Int32(f1.1), Int32(f2.1), Int32(f3.1)))
455 | }
456 |
457 | /// Splits x into a floating-point significand in the range
458 | /// [0.5, 1.0) and an integral exponent of two, such that:
459 | /// x = significand * exp(2, exponent)
460 | @warn_unused_result
461 | public func frexp(x: double4) -> (double4, int4) {
462 | let f1 = frexp(x[0])
463 | let f2 = frexp(x[1])
464 | let f3 = frexp(x[2])
465 | let f4 = frexp(x[3])
466 | return (double4(f1.0, f2.0, f3.0, f4.0), int4(Int32(f1.1), Int32(f2.1), Int32(f3.1), Int32(f4.1)))
467 | }
468 |
469 | // MARK: - ldexp
470 |
471 | /// Builds a floating-point number from x and the
472 | /// corresponding integral exponent of two in exp, returning:
473 | /// significand * exp(2, exponent)
474 | @warn_unused_result
475 | public func ldexp(x: float2, exp: int2) -> float2 {
476 | return float2(ldexp(x[0], Int(exp[0])), ldexp(x[1], Int(exp[1])))
477 | }
478 |
479 | /// Builds a floating-point number from x and the
480 | /// corresponding integral exponent of two in exp, returning:
481 | /// significand * exp(2, exponent)
482 | @warn_unused_result
483 | public func ldexp(x: float3, exp: int3) -> float3 {
484 | return float3(ldexp(x[0], Int(exp[0])), ldexp(x[1], Int(exp[1])), ldexp(x[2], Int(exp[2])))
485 | }
486 |
487 | /// Builds a floating-point number from x and the
488 | /// corresponding integral exponent of two in exp, returning:
489 | /// significand * exp(2, exponent)
490 | @warn_unused_result
491 | public func ldexp(x: float4, exp: int4) -> float4 {
492 | return float4(ldexp(x[0], Int(exp[0])), ldexp(x[1], Int(exp[1])), ldexp(x[2], Int(exp[2])), ldexp(x[3], Int(exp[3])))
493 | }
494 |
495 | /// Builds a floating-point number from x and the
496 | /// corresponding integral exponent of two in exp, returning:
497 | /// significand * exp(2, exponent)
498 | @warn_unused_result
499 | public func ldexp(x: double2, exp: int2) -> double2 {
500 | return double2(ldexp(x[0], Int(exp[0])), ldexp(x[1], Int(exp[1])))
501 | }
502 |
503 | /// Builds a floating-point number from x and the
504 | /// corresponding integral exponent of two in exp, returning:
505 | /// significand * exp(2, exponent)
506 | @warn_unused_result
507 | public func ldexp(x: double3, exp: int3) -> double3 {
508 | return double3(ldexp(x[0], Int(exp[0])), ldexp(x[1], Int(exp[1])), ldexp(x[2], Int(exp[2])))
509 | }
510 |
511 | /// Builds a floating-point number from x and the
512 | /// corresponding integral exponent of two in exp, returning:
513 | /// significand * exp(2, exponent)
514 | @warn_unused_result
515 | public func ldexp(x: double4, exp: int4) -> double4 {
516 | return double4(ldexp(x[0], Int(exp[0])), ldexp(x[1], Int(exp[1])), ldexp(x[2], Int(exp[2])), ldexp(x[3], Int(exp[3])))
517 | }
518 |
--------------------------------------------------------------------------------
/Tests/glm-to-swift-quat.mm:
--------------------------------------------------------------------------------
1 | //
2 | // glm-to-swift-quat.m
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 02.01.2016.
6 | // Copyright © 2016 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | #include
10 |
11 | #import "glm-to-swift-quat.h"
12 | #import "glm/glm/glm.hpp"
13 | #import "glm/glm/gtc/epsilon.hpp"
14 |
15 | BOOL compare(vector_float4 v, glm::quat q) {
16 | return glm::epsilonEqual(v.x, q.x, 0.00000001f) &&
17 | glm::epsilonEqual(v.y, q.y, 0.00000001f) &&
18 | glm::epsilonEqual(v.z, q.z, 0.00000001f) &&
19 | glm::epsilonEqual(v.w, q.w, 0.00000001f);
20 | }
21 |
22 | BOOL compare(vector_double4 v, glm::dquat q) {
23 | return glm::epsilonEqual(v.x, q.x, 0.00000001) &&
24 | glm::epsilonEqual(v.y, q.y, 0.00000001) &&
25 | glm::epsilonEqual(v.z, q.z, 0.00000001) &&
26 | glm::epsilonEqual(v.w, q.w, 0.00000001);
27 | }
28 |
29 | template
30 | t castVector(u vec, int indexI) {
31 | t retVec;
32 | for (int i=0; i
64 | BOOL isEqual(const T& v1, const T& v2, float eps) {
65 | auto r = glm::epsilonEqual(v1, v2, eps);
66 | for (int i=0; i
75 | BOOL isEqual(const T& v1, const T& v2, double eps) {
76 | auto r = glm::epsilonEqual(v1, v2, eps);
77 | for (int i=0; i
86 | t castMatrix(u vec, int indexI, int indexJ) {
87 | t retMat;
88 | for (int i=0; i
97 | t castMatrix(u vec, int indexI) {
98 | return castMatrix(vec, indexI, indexI);
99 | }
100 |
101 | template
102 | BOOL isEqualMatrix(const T& v1, const T& v2, float eps) {
103 | auto v = glm::detail::component_count(v1);
104 | for (int j=0; j
116 | BOOL isEqualMatrix(const T& v1, const T& v2, double eps) {
117 | auto v = glm::detail::component_count(v1);
118 | for (int j=0; j(v, 3);
154 | glm::quat q(s, glmV);
155 | return compare(result, q);
156 | }
157 |
158 | +(BOOL) quatInitWithAngle:(float)angle andAxis:(vector_float3)axis andResult:(vector_float4) result {
159 | glm::vec3 glmAxis = castVector(axis, 3);
160 | glm::quat glmResult = castQuat(castVector(result, 4));
161 |
162 | return isEqual(glmResult, glm::angleAxis(angle, glmAxis), 0.00000001f);
163 | }
164 |
165 | +(BOOL) quatInitWithEulerAngles:(vector_float3) angles andResult:(vector_float4) result {
166 | glm::vec3 glmAngles = castVector(angles, 3);
167 | glm::quat q(glmAngles);
168 |
169 | return compare(result, q);
170 | }
171 |
172 | +(BOOL) quatInitWithNormalizedAxis:(vector_float3) axis1 withAxis:(vector_float3) axis2 andResult:(vector_float4) result {
173 | glm::vec3 glmAxis1 = castVector(axis1, 3);
174 | glm::vec3 glmAxis2 = castVector(axis2, 3);
175 | glm::quat q(glmAxis1, glmAxis2);
176 |
177 | return compare(result, q);
178 | }
179 |
180 | +(BOOL) quatInitWithMat3x3:(matrix_float3x3) mat andResult:(vector_float4) result {
181 | glm::mat3 glmMat = castMatrix(mat, 3);
182 | glm::quat q(glmMat);
183 |
184 | return compare(result, q);
185 | }
186 |
187 | +(BOOL) quatInitWithMat4x4:(matrix_float4x4) mat andResult:(vector_float4) result {
188 | glm::mat4 glmMat = castMatrix(mat, 4);
189 | glm::quat q(glmMat);
190 |
191 | return compare(result, q);
192 | }
193 |
194 | +(BOOL) quatPlus:(vector_float4)v andResult:(vector_float4) result {
195 | glm::quat q = castQuat(castVector(v, 4));
196 | return compare(result, +q);
197 | }
198 |
199 | +(BOOL) quatMinus:(vector_float4)v andResult:(vector_float4) result {
200 | glm::quat q = castQuat(castVector(v, 4));
201 | return compare(result, -q);
202 | }
203 |
204 | +(BOOL) quatAddition:(vector_float4)v1 withQuat:(vector_float4)v2 andResult:(vector_float4) result {
205 |
206 | glm::quat q1 = castQuat(castVector(v1, 4));
207 | glm::quat q2 = castQuat(castVector(v2, 4));
208 | return compare(result, q1+q2);
209 | }
210 |
211 | +(BOOL) quatMultiplication:(vector_float4)v1 withQuat:(vector_float4)v2 andResult:(vector_float4) result {
212 |
213 | glm::quat q1 = castQuat(castVector(v1, 4));
214 | glm::quat q2 = castQuat(castVector(v2, 4));
215 | return compare(result, q1*q2);
216 | }
217 |
218 | +(BOOL) quatMultiplication:(vector_float4)v1 withScalar:(float)f andResult:(vector_float4) result {
219 | glm::quat q1 = castQuat(castVector(v1, 4));
220 | return compare(result, q1*f);
221 | }
222 |
223 | +(BOOL) quatMultiplication_2:(vector_float4)v1 withScalar:(float)f andResult:(vector_float4) result {
224 | glm::quat q1 = castQuat(castVector(v1, 4));
225 | return compare(result, f*q1);
226 | }
227 |
228 | +(BOOL) quatMultiplication:(vector_float4)v1 withVec3:(vector_float3)v2 andResult:(vector_float3) result {
229 | glm::quat q = castQuat(castVector(v1, 4));
230 | glm::vec3 v = castVector(v2, 3);
231 | glm::vec3 glmResult = castVector(result, 3);
232 | return isEqual(q*v, glmResult, 0.00000001f);
233 | }
234 |
235 | +(BOOL) quatMultiplication_2:(vector_float4)v1 withVec3:(vector_float3)v2 andResult:(vector_float3) result {
236 | glm::quat q = castQuat(castVector(v1, 4));
237 | glm::vec3 v = castVector(v2, 3);
238 | glm::vec3 glmResult = castVector(result, 3);
239 | return isEqual(v*q, glmResult, 0.00000001f);
240 | }
241 |
242 | +(BOOL) quatMultiplication:(vector_float4)v1 withVec4:(vector_float4)v2 andResult:(vector_float4) result {
243 | glm::quat q = castQuat(castVector(v1, 4));
244 | glm::vec4 v = castVector(v2, 4);
245 | glm::vec4 glmResult = castVector(result, 4);
246 | return isEqual(q*v, glmResult, 0.00000001f);
247 | }
248 |
249 | +(BOOL) quatMultiplication_2:(vector_float4)v1 withVec4:(vector_float4)v2 andResult:(vector_float4) result {
250 | glm::quat q = castQuat(castVector(v1, 4));
251 | glm::vec4 v = castVector(v2, 4);
252 | glm::vec4 glmResult = castVector(result, 4);
253 | return isEqual(v*q, glmResult, 0.00000001f);
254 | }
255 |
256 | +(BOOL) quatDivision:(vector_float4)v1 withScalar:(float)f andResult:(vector_float4) result {
257 |
258 | glm::quat q = castQuat(castVector(v1, 4));
259 | return compare(result, q / f);
260 | }
261 |
262 | +(BOOL) quatDot:(vector_float4)v1 withQuat:(vector_float4)v2 andResult:(float) result {
263 | glm::quat q1 = castQuat(castVector(v1, 4));
264 | glm::quat q2 = castQuat(castVector(v2, 4));
265 | return glm::epsilonEqual(result, dot(q1,q2), 0.00000001f);
266 | }
267 |
268 | +(BOOL) quatLength:(vector_float4)v andResult:(float) result {
269 | glm::quat q = castQuat(castVector(v, 4));
270 | return glm::epsilonEqual(result, glm::length(q), 0.00000001f);
271 | }
272 |
273 | +(BOOL) quatInverse:(vector_float4)v andResult:(vector_float4) result {
274 | glm::quat q = castQuat(castVector(v, 4));
275 | return compare(result, glm::inverse(q));
276 | }
277 |
278 | +(BOOL) quatNormalization:(vector_float4) source andResult:(vector_float4) result {
279 | glm::quat q = castQuat(castVector(source, 4));
280 |
281 | return compare(result, glm::normalize(q));
282 | }
283 |
284 | +(BOOL) quatConjugate:(vector_float4) source andResult:(vector_float4) result {
285 | glm::quat q = castQuat(castVector(source, 4));
286 |
287 | return compare(result, glm::conjugate(q));
288 | }
289 |
290 | +(BOOL) quatMix:(vector_float4)q1 with:(vector_float4)q2 at:(float)t andResult:(vector_float4) result {
291 | glm::quat glmQ1 = castQuat(castVector(q1, 4));
292 | glm::quat glmQ2 = castQuat(castVector(q2, 4));
293 | glm::quat glmResult = castQuat(castVector(result, 4));
294 |
295 | return isEqual(glmResult, glm::mix(glmQ1, glmQ2, t), 0.00000001f);
296 | }
297 |
298 | +(BOOL) quatLerp:(vector_float4)q1 with:(vector_float4)q2 at:(float)t andResult:(vector_float4) result {
299 | glm::quat glmQ1 = castQuat(castVector(q1, 4));
300 | glm::quat glmQ2 = castQuat(castVector(q2, 4));
301 | glm::quat glmResult = castQuat(castVector(result, 4));
302 |
303 | return isEqual(glmResult, glm::lerp(glmQ1, glmQ2, t), 0.00000001f);
304 | }
305 |
306 | +(BOOL) quatSlerp:(vector_float4)q1 with:(vector_float4)q2 at:(float)t andResult:(vector_float4) result {
307 | glm::quat glmQ1 = castQuat(castVector(q1, 4));
308 | glm::quat glmQ2 = castQuat(castVector(q2, 4));
309 | glm::quat glmResult = castQuat(castVector(result, 4));
310 |
311 | return isEqual(glmResult, glm::slerp(glmQ1, glmQ2, t), 0.00000001f);
312 | }
313 |
314 | +(BOOL) quatRotate:(vector_float4)q withAngle:(float)angle withAxis:(vector_float3)axis andResult:(vector_float4) result {
315 | glm::quat glmQ = castQuat(castVector(q, 4));
316 | glm::vec3 glmAxis = castVector(axis, 3);
317 | glm::quat glmResult = castQuat(castVector(result, 4));
318 |
319 | return isEqual(glmResult, glm::rotate(glmQ, angle, glmAxis), 0.00000001f);
320 | }
321 |
322 | +(BOOL) quatEulerAngles:(vector_float4)q withResult:(vector_float3) result {
323 | glm::quat glmQ = castQuat(castVector(q, 4));
324 | glm::vec3 glmResult = castVector(result, 3);
325 |
326 | return isEqual(glmResult, glm::eulerAngles(glmQ), 0.00000001f);
327 | }
328 |
329 | +(BOOL) quatFloat3x3Cast:(vector_float4)q withResult:(matrix_float3x3) result {
330 | glm::mat3 glmResult = castMatrix(result, 3);
331 | glm::quat glmQ = castQuat(castVector(q, 4));
332 |
333 | return isEqualMatrix(glmResult, glm::mat3_cast(glmQ), 0.00000001f);
334 | }
335 |
336 | +(BOOL) quatFloat4x4Cast:(vector_float4)q withResult:(matrix_float4x4) result {
337 | glm::mat4 glmResult = castMatrix(result, 4);
338 | glm::quat glmQ = castQuat(castVector(q, 4));
339 |
340 | return isEqualMatrix(glmResult, glm::mat4_cast(glmQ), 0.00000001f);
341 | }
342 |
343 | +(BOOL) quatAngle:(vector_float4)q withResult:(float) result {
344 | glm::quat glmQ = castQuat(castVector(q, 4));
345 | return glm::epsilonEqual(result, glm::angle(glmQ), 0.00000001f);
346 | }
347 |
348 | +(BOOL) quatAxis:(vector_float4)q withResult:(vector_float3) result {
349 | glm::quat glmQ = castQuat(castVector(q, 4));
350 | glm::vec3 glmResult = castVector(result, 3);
351 | return isEqual(glmResult, glm::axis(glmQ), 0.00000001f);
352 | }
353 |
354 |
355 |
356 | + (BOOL) quatInitWithResultDouble:(vector_double4) result {
357 |
358 | glm::dquat q;
359 |
360 | return compare(result, q);
361 | }
362 |
363 | +(BOOL) quatInitWithValuesWDouble:(double) w ValueX:(double) x ValueY:(double) y ValueZ:(double) z AndResult:(vector_double4) result {
364 |
365 | glm::dquat q(w, x, y, z);
366 | return compare(result, q);
367 | }
368 |
369 | +(BOOL) quatInitWithQuatWithInitValuesWDouble:(double) w ValueX:(double) x ValueY:(double) y ValueZ:(double) z andResult:(vector_double4) result {
370 |
371 | glm::dquat q(w, x, y, z);
372 | glm::dquat q2(q);
373 |
374 | return compare(result, q2);
375 | }
376 |
377 | +(BOOL) quatInitWithDouble:(double) s andVec3:(vector_double3) v andResult:(vector_double4) result {
378 | glm::dvec3 glmV = castVector(v, 3);
379 | glm::dquat q(s, glmV);
380 | return compare(result, q);
381 | }
382 |
383 | +(BOOL) quatInitWithAngleDouble:(double)angle andAxis:(vector_double3)axis andResult:(vector_double4) result {
384 | glm::dvec3 glmAxis = castVector(axis, 3);
385 | glm::dquat glmResult = castQuat(castVector(result, 4));
386 |
387 | return isEqual(glmResult, glm::angleAxis(angle, glmAxis), 0.00000001);
388 | }
389 |
390 | +(BOOL) quatInitWithEulerAnglesDouble:(vector_double3) angles andResult:(vector_double4) result {
391 | glm::dvec3 glmAngles = castVector(angles, 3);
392 | glm::dquat q(glmAngles);
393 |
394 | return compare(result, q);
395 | }
396 |
397 | +(BOOL) quatInitWithNormalizedAxisDouble:(vector_double3) axis1 withAxis:(vector_double3) axis2 andResult:(vector_double4) result {
398 | glm::dvec3 glmAxis1 = castVector(axis1, 3);
399 | glm::dvec3 glmAxis2 = castVector(axis2, 3);
400 | glm::dquat q(glmAxis1, glmAxis2);
401 |
402 | return compare(result, q);
403 | }
404 |
405 | +(BOOL) quatInitWithMat3x3Double:(matrix_double3x3) mat andResult:(vector_double4) result {
406 | glm::dmat3 glmMat = castMatrix(mat, 3);
407 | glm::dquat q(glmMat);
408 |
409 | return compare(result, q);
410 | }
411 |
412 | +(BOOL) quatInitWithMat4x4Double:(matrix_double4x4) mat andResult:(vector_double4) result {
413 | glm::dmat4 glmMat = castMatrix(mat, 4);
414 | glm::dquat q(glmMat);
415 |
416 | return compare(result, q);
417 | }
418 |
419 | +(BOOL) quatPlusDouble:(vector_double4)v andResult:(vector_double4) result {
420 | glm::dquat q = castQuat(castVector(v, 4));
421 | return compare(result, +q);
422 | }
423 |
424 | +(BOOL) quatMinusDouble:(vector_double4)v andResult:(vector_double4) result {
425 | glm::dquat q = castQuat(castVector(v, 4));
426 | return compare(result, -q);
427 | }
428 |
429 | +(BOOL) quatAdditionDouble:(vector_double4)v1 withQuat:(vector_double4)v2 andResult:(vector_double4) result {
430 |
431 | glm::dquat q1 = castQuat(castVector(v1, 4));
432 | glm::dquat q2 = castQuat(castVector(v2, 4));
433 | return compare(result, q1+q2);
434 | }
435 |
436 | +(BOOL) quatMultiplicationDouble:(vector_double4)v1 withQuat:(vector_double4)v2 andResult:(vector_double4) result {
437 |
438 | glm::dquat q1 = castQuat(castVector(v1, 4));
439 | glm::dquat q2 = castQuat(castVector(v2, 4));
440 | return compare(result, q1*q2);
441 | }
442 |
443 | +(BOOL) quatMultiplicationDouble:(vector_double4)v1 withScalar:(double)f andResult:(vector_double4) result {
444 | glm::dquat q1 = castQuat(castVector(v1, 4));
445 | return compare(result, q1*f);
446 | }
447 |
448 | +(BOOL) quatMultiplication_2Double:(vector_double4)v1 withScalar:(double)f andResult:(vector_double4) result {
449 | glm::dquat q1 = castQuat(castVector(v1, 4));
450 | return compare(result, f*q1);
451 | }
452 |
453 | +(BOOL) quatMultiplicationDouble:(vector_double4)v1 withVec3:(vector_double3)v2 andResult:(vector_double3) result {
454 | glm::dquat q = castQuat(castVector(v1, 4));
455 | glm::dvec3 v = castVector(v2, 3);
456 | glm::dvec3 glmResult = castVector(result, 3);
457 | return isEqual(q*v, glmResult, 0.00000001);
458 | }
459 |
460 | +(BOOL) quatMultiplication_2Double:(vector_double4)v1 withVec3:(vector_double3)v2 andResult:(vector_double3) result {
461 | glm::dquat q = castQuat(castVector(v1, 4));
462 | glm::dvec3 v = castVector(v2, 3);
463 | glm::dvec3 glmResult = castVector(result, 3);
464 | return isEqual(v*q, glmResult, 0.00000001);
465 | }
466 |
467 | +(BOOL) quatMultiplicationDouble:(vector_double4)v1 withVec4:(vector_double4)v2 andResult:(vector_double4) result {
468 | glm::dquat q = castQuat(castVector(v1, 4));
469 | glm::dvec4 v = castVector(v2, 4);
470 | glm::dvec4 glmResult = castVector(result, 4);
471 | return isEqual(q*v, glmResult, 0.00000001);
472 | }
473 |
474 | +(BOOL) quatMultiplication_2Double:(vector_double4)v1 withVec4:(vector_double4)v2 andResult:(vector_double4) result {
475 | glm::dquat q = castQuat(castVector(v1, 4));
476 | glm::dvec4 v = castVector(v2, 4);
477 | glm::dvec4 glmResult = castVector(result, 4);
478 | return isEqual(v*q, glmResult, 0.00000001);
479 | }
480 |
481 | +(BOOL) quatDivisionDouble:(vector_double4)v1 withScalar:(double)f andResult:(vector_double4) result {
482 |
483 | glm::dquat q = castQuat(castVector(v1, 4));
484 | return compare(result, q / f);
485 | }
486 |
487 | +(BOOL) quatDotDouble:(vector_double4)v1 withQuat:(vector_double4)v2 andResult:(double) result {
488 | glm::dquat q1 = castQuat(castVector(v1, 4));
489 | glm::dquat q2 = castQuat(castVector(v2, 4));
490 | return glm::epsilonEqual(result, dot(q1,q2), 0.00000001);
491 | }
492 |
493 | +(BOOL) quatLengthDouble:(vector_double4)v andResult:(double) result {
494 | glm::dquat q = castQuat(castVector(v, 4));
495 | return glm::epsilonEqual(result, glm::length(q), 0.00000001);
496 | }
497 |
498 | +(BOOL) quatInverseDouble:(vector_double4)v andResult:(vector_double4) result {
499 | glm::dquat q = castQuat(castVector(v, 4));
500 | return compare(result, glm::inverse(q));
501 | }
502 |
503 | +(BOOL) quatNormalizationDouble:(vector_double4) source andResult:(vector_double4) result {
504 | glm::dquat q = castQuat(castVector(source, 4));
505 |
506 | return compare(result, glm::normalize(q));
507 | }
508 |
509 | +(BOOL) quatConjugateDouble:(vector_double4) source andResult:(vector_double4) result {
510 | glm::dquat q = castQuat(castVector(source, 4));
511 |
512 | return compare(result, glm::conjugate(q));
513 | }
514 |
515 | +(BOOL) quatMixDouble:(vector_double4)q1 with:(vector_double4)q2 at:(double)t andResult:(vector_double4) result {
516 | glm::dquat glmQ1 = castQuat(castVector(q1, 4));
517 | glm::dquat glmQ2 = castQuat(castVector(q2, 4));
518 | glm::dquat glmResult = castQuat(castVector(result, 4));
519 |
520 | return isEqual(glmResult, glm::mix(glmQ1, glmQ2, t), 0.00000001);
521 | }
522 |
523 | +(BOOL) quatLerpDouble:(vector_double4)q1 with:(vector_double4)q2 at:(double)t andResult:(vector_double4) result {
524 | glm::dquat glmQ1 = castQuat(castVector(q1, 4));
525 | glm::dquat glmQ2 = castQuat(castVector(q2, 4));
526 | glm::dquat glmResult = castQuat(castVector(result, 4));
527 |
528 | return isEqual(glmResult, glm::lerp(glmQ1, glmQ2, t), 0.00000001);
529 | }
530 |
531 | +(BOOL) quatSlerpDouble:(vector_double4)q1 with:(vector_double4)q2 at:(double)t andResult:(vector_double4) result {
532 | glm::dquat glmQ1 = castQuat(castVector(q1, 4));
533 | glm::dquat glmQ2 = castQuat(castVector(q2, 4));
534 | glm::dquat glmResult = castQuat(castVector(result, 4));
535 |
536 | return isEqual(glmResult, glm::slerp(glmQ1, glmQ2, t), 0.00000001);
537 | }
538 |
539 | +(BOOL) quatRotateDouble:(vector_double4)q withAngle:(double)angle withAxis:(vector_double3)axis andResult:(vector_double4) result {
540 | glm::dquat glmQ = castQuat(castVector(q, 4));
541 | glm::dvec3 glmAxis = castVector(axis, 3);
542 | glm::dquat glmResult = castQuat(castVector(result, 4));
543 |
544 | return isEqual(glmResult, glm::rotate(glmQ, angle, glmAxis), 0.00000001);
545 | }
546 |
547 | +(BOOL) quatEulerAnglesDouble:(vector_double4)q withResult:(vector_double3) result {
548 | glm::dquat glmQ = castQuat(castVector(q, 4));
549 | glm::dvec3 glmResult = castVector(result, 3);
550 |
551 | return isEqual(glmResult, glm::eulerAngles(glmQ), 0.00000001);
552 | }
553 |
554 | +(BOOL) quatdouble3x3CastDouble:(vector_double4)q withResult:(matrix_double3x3) result {
555 | glm::dmat3 glmResult = castMatrix(result, 3);
556 | glm::dquat glmQ = castQuat(castVector(q, 4));
557 |
558 | return isEqualMatrix(glmResult, glm::mat3_cast(glmQ), 0.00000001);
559 | }
560 |
561 | +(BOOL) quatdouble4x4CastDouble:(vector_double4)q withResult:(matrix_double4x4) result {
562 | glm::dmat4 glmResult = castMatrix(result, 4);
563 | glm::dquat glmQ = castQuat(castVector(q, 4));
564 |
565 | return isEqualMatrix(glmResult, glm::mat4_cast(glmQ), 0.00000001);
566 | }
567 |
568 | +(BOOL) quatAngleDouble:(vector_double4)q withResult:(double) result {
569 | glm::dquat glmQ = castQuat(castVector(q, 4));
570 | return glm::epsilonEqual(result, glm::angle(glmQ), 0.00000001);
571 | }
572 |
573 | +(BOOL) quatAxisDouble:(vector_double4)q withResult:(vector_double3) result {
574 | glm::dquat glmQ = castQuat(castVector(q, 4));
575 | glm::dvec3 glmResult = castVector(result, 3);
576 | return isEqual(glmResult, glm::axis(glmQ), 0.00000001);
577 | }
578 |
579 | @end
--------------------------------------------------------------------------------
/Source/Quaternion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Quaternion.swift
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 30.11.2015.
6 | // Copyright © 2015 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import simd
11 |
12 | public struct quat: ArrayLiteralConvertible, CustomDebugStringConvertible {
13 | public var x: Float
14 | public var y: Float
15 | public var z: Float
16 | public var w: Float
17 |
18 | public init() {
19 | x = 0
20 | y = 0
21 | z = 0
22 | w = 1
23 | }
24 |
25 | public init(w: Float, v: float3) {
26 | x = v.x
27 | y = v.y
28 | z = v.z
29 | self.w = w
30 | }
31 |
32 | public init(angle: Float, axis: float3) {
33 | self = angleAxis(angle, axis: axis)
34 | }
35 |
36 | public init(_ w: Float, _ x: Float, _ y: Float, _ z: Float) {
37 | self.x = x
38 | self.y = y
39 | self.z = z
40 | self.w = w
41 | }
42 |
43 | public init(_ q: quat) {
44 | x = q.x
45 | y = q.y
46 | z = q.z
47 | w = q.w
48 | }
49 |
50 | /// Initialize to a vector with elements taken from `array`.
51 | ///
52 | /// - Precondition: `array` must have exactly four elements.
53 | public init(_ array: [Float]) {
54 | x = array[0]
55 | y = array[1]
56 | z = array[2]
57 | w = array[3]
58 | }
59 |
60 | /// Initialize using `arrayLiteral`.
61 | ///
62 | /// - Precondition: the array literal must exactly four elements.
63 | public init(arrayLiteral elements: Float...) {
64 | x = elements[0]
65 | y = elements[1]
66 | z = elements[2]
67 | w = elements[3]
68 | }
69 |
70 | /// Create a quaternion from two normalized axis
71 | /// @see http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors
72 | public init(_ u: float3, _ v: float3) {
73 | let LocalW = cross(u, v)
74 | let Dot = dot(u, v)
75 | let q = quat(1 + Dot, LocalW.x, LocalW.y, LocalW.z)
76 | self.init(normalize(q))
77 | }
78 |
79 | public init(_ eulerAngle: float3) {
80 | let c = cos(eulerAngle * Float(0.5))
81 | let s = sin(eulerAngle * Float(0.5))
82 |
83 | w = c.x * c.y * c.z + s.x * s.y * s.z
84 | x = s.x * c.y * c.z - c.x * s.y * s.z
85 | y = c.x * s.y * c.z + s.x * c.y * s.z
86 | z = c.x * c.y * s.z - s.x * s.y * c.z
87 | }
88 |
89 | public init(_ m: float3x3) {
90 | self.init(quat_cast(m))
91 | }
92 |
93 | public init(_ m: float4x4) {
94 | self.init(quat_cast(m))
95 | }
96 |
97 | public var debugDescription: String {
98 | get {
99 | return ""
100 | }
101 | }
102 | }
103 |
104 | prefix public func +(q: quat) -> quat {
105 | return q
106 | }
107 |
108 | prefix public func -(q: quat) -> quat {
109 | return quat(-q.w, -q.x, -q.y, -q.z)
110 | }
111 |
112 | public func +(q: quat, p: quat) -> quat {
113 | return quat(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z)
114 | }
115 |
116 | public func *(p: quat, q: quat) -> quat {
117 |
118 | let w = p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z
119 | let x = p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y
120 | let y = p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z
121 | let z = p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x
122 | return quat(w, x, y, z)
123 | }
124 |
125 | public func *(q: quat, v: float3) -> float3 {
126 | let QuatVector = float3(q.x, q.y, q.z)
127 | let uv = cross(QuatVector, v)
128 | let uuv = cross(QuatVector, uv)
129 |
130 | return v + ((uv * q.w) + uuv) * Float(2)
131 | }
132 |
133 | public func *(v: float3, q: quat) -> float3 {
134 | return inverse(q) * v
135 | }
136 |
137 | public func *(q: quat, v: float4) -> float4 {
138 | return float4(q * float3(v), v.w)
139 | }
140 |
141 | public func *(v: float4, q: quat) -> float4 {
142 | return inverse(q) * v
143 | }
144 |
145 | public func *(q: quat, p: Float) -> quat {
146 | return quat( q.w * p, q.x * p, q.y * p, q.z * p)
147 | }
148 |
149 | public func *(p: Float, q: quat) -> quat {
150 | return q * p
151 | }
152 |
153 | public func /(q: quat, p: Float) -> quat {
154 | return quat( q.w / p, q.x / p, q.y / p, q.z / p)
155 | }
156 |
157 | /// Returns the normalized quaternion.
158 | public func normalize(q: quat) -> quat {
159 | let len = length(q)
160 | if (len <= Float(0)) {
161 | // Problem
162 | return quat(1, 0, 0, 0)
163 | }
164 | let oneOverLen = Float(1) / len
165 | return quat(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen)
166 | }
167 |
168 | /// Returns the length of the quaternion.
169 | public func length(q: quat) -> Float {
170 | return sqrt(dot(q, q))
171 | }
172 |
173 | /// Returns the q conjugate.
174 | public func conjugate(q: quat) -> quat {
175 | return quat(q.w, -q.x, -q.y, -q.z)
176 | }
177 |
178 | /// Returns the q inverse.
179 | public func inverse(q: quat) -> quat {
180 | return conjugate(q) / dot(q, q)
181 | }
182 |
183 | public func dot(q1: quat, _ q2: quat) -> Float {
184 | let tmp = float4(q1.x * q2.x, q1.y * q2.y, q1.z * q2.z, q1.w * q2.w)
185 | return (tmp.x + tmp.y) + (tmp.z + tmp.w)
186 | }
187 |
188 | /// Spherical linear interpolation of two quaternions.
189 | /// The interpolation is oriented and the rotation is performed at constant speed.
190 | /// For short path spherical linear interpolation, use the slerp function.
191 | public func mix(x: quat, _ y: quat, _ a: Float) -> quat {
192 | let cosTheta = dot(x, y);
193 |
194 | // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
195 | if (cosTheta > Float(1) - Float(0.0000001)) {
196 |
197 | // Linear interpolation
198 | return quat(
199 | mix(x.w, y.w, a),
200 | mix(x.x, y.x, a),
201 | mix(x.y, y.y, a),
202 | mix(x.z, y.z, a))
203 | } else {
204 | // Essential Mathematics, page 467
205 | let angle = acos(cosTheta)
206 | return (sin((Float(1) - a) * angle) * x + sin(a * angle) * y) / sin(angle)
207 | }
208 | }
209 |
210 | /// Linear interpolation of two quaternions.
211 | /// The interpolation is oriented.
212 | public func lerp(x: quat, _ y: quat, _ a: Float) -> quat {
213 | return x * (Float(1) - a) + (y * a)
214 | }
215 |
216 | /// Spherical linear interpolation of two quaternions.
217 | /// The interpolation always take the short path and the rotation is performed at constant speed.
218 | public func slerp(x: quat, _ y: quat, _ a: Float) -> quat {
219 | var z = y
220 |
221 | var cosTheta = dot(x, y)
222 |
223 | // If cosTheta < 0, the interpolation will take the long way around the sphere.
224 | // To fix this, one quat must be negated.
225 | if (cosTheta < Float(0)) {
226 | z = -y
227 | cosTheta = -cosTheta
228 | }
229 |
230 | // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
231 | if (cosTheta > Float(1) - Float(0.0000001)) {
232 | // Linear interpolation
233 | return quat(
234 | mix(x.w, z.w, a),
235 | mix(x.x, z.x, a),
236 | mix(x.y, z.y, a),
237 | mix(x.z, z.z, a))
238 | } else {
239 | // Essential Mathematics, page 467
240 | let angle = acos(cosTheta)
241 | return (sin((Float(1) - a) * angle) * x + sin(a * angle) * z) / sin(angle)
242 | }
243 | }
244 |
245 | /// Rotates a quaternion from a vector of 3 components axis and an angle.
246 | public func rotate(q: quat, angle: Float, axis: float3) -> quat {
247 | var tmp = axis
248 |
249 | // Axis of rotation must be normalised
250 | let len = length(tmp)
251 | if (abs(len - Float(1)) > Float(0.001)) {
252 | let oneOverLen = Float(1) / len
253 | tmp *= oneOverLen
254 | }
255 |
256 | let AngleRad = angle
257 | let Sin = sin(AngleRad * Float(0.5))
258 |
259 | return q * quat(cos(AngleRad * Float(0.5)), tmp.x * Sin, tmp.y * Sin, tmp.z * Sin)
260 | }
261 |
262 | /// Returns euler angles, yitch as x, yaw as y, roll as z.
263 | /// The result is expressed in radians if GLM_FORCE_RADIANS is defined or degrees otherwise.
264 | public func eulerAngles(x: quat) -> float3 {
265 | return float3(pitch(x), yaw(x), roll(x))
266 | }
267 |
268 | /// Returns roll value of euler angles expressed in radians.
269 | public func roll(q: quat) -> Float {
270 | return Float(atan2(Float(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z))
271 | }
272 |
273 | /// Returns pitch value of euler angles expressed in radians.
274 | public func pitch(q: quat) -> Float {
275 | return Float(atan2(Float(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z))
276 | }
277 |
278 | /// Returns yaw value of euler angles expressed in radians.
279 | public func yaw(q: quat) -> Float {
280 | return asin(Float(-2) * (q.x * q.z - q.w * q.y))
281 | }
282 |
283 | /// Converts a quaternion to a 3 * 3 matrix.
284 | public func float3x3_cast(q: quat) -> float3x3 {
285 | var Result = float3x3(1)
286 | let qxx = q.x * q.x
287 | let qyy = q.y * q.y
288 | let qzz = q.z * q.z
289 | let qxz = q.x * q.z
290 | let qxy = q.x * q.y
291 | let qyz = q.y * q.z
292 | let qwx = q.w * q.x
293 | let qwy = q.w * q.y
294 | let qwz = q.w * q.z
295 |
296 | Result[0][0] = 1 - 2 * (qyy + qzz)
297 | Result[0][1] = 2 * (qxy + qwz)
298 | Result[0][2] = 2 * (qxz - qwy)
299 |
300 | Result[1][0] = 2 * (qxy - qwz)
301 | Result[1][1] = 1 - 2 * (qxx + qzz)
302 | Result[1][2] = 2 * (qyz + qwx)
303 |
304 | Result[2][0] = 2 * (qxz + qwy)
305 | Result[2][1] = 2 * (qyz - qwx)
306 | Result[2][2] = 1 - 2 * (qxx + qyy)
307 | return Result
308 | }
309 |
310 | /// Converts a quaternion to a 4 * 4 matrix.
311 | public func float4x4_cast(q: quat) -> float4x4 {
312 | return float4x4(float3x3_cast(q))
313 | }
314 |
315 | /// Converts a 3 * 3 matrix to a quaternion.
316 | public func quat_cast(m: float3x3) -> quat {
317 | let fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2]
318 | let fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2]
319 | let fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1]
320 | let fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2]
321 |
322 | var biggestIndex = 0
323 | var fourBiggestSquaredMinus1 = fourWSquaredMinus1
324 |
325 | if fourXSquaredMinus1 > fourBiggestSquaredMinus1 {
326 | fourBiggestSquaredMinus1 = fourXSquaredMinus1
327 | biggestIndex = 1
328 | }
329 | if fourYSquaredMinus1 > fourBiggestSquaredMinus1 {
330 | fourBiggestSquaredMinus1 = fourYSquaredMinus1
331 | biggestIndex = 2
332 | }
333 | if fourZSquaredMinus1 > fourBiggestSquaredMinus1 {
334 | fourBiggestSquaredMinus1 = fourZSquaredMinus1
335 | biggestIndex = 3
336 | }
337 |
338 | let biggestVal = sqrt(fourBiggestSquaredMinus1 + Float(1)) * Float(0.5)
339 | let mult = Float(0.25) / biggestVal
340 |
341 | var Result = quat()
342 | switch (biggestIndex) {
343 | case 0:
344 | Result.w = biggestVal
345 | Result.x = (m[1][2] - m[2][1]) * mult
346 | Result.y = (m[2][0] - m[0][2]) * mult
347 | Result.z = (m[0][1] - m[1][0]) * mult
348 | break
349 | case 1:
350 | Result.w = (m[1][2] - m[2][1]) * mult
351 | Result.x = biggestVal
352 | Result.y = (m[0][1] + m[1][0]) * mult
353 | Result.z = (m[2][0] + m[0][2]) * mult
354 | break
355 | case 2:
356 | Result.w = (m[2][0] - m[0][2]) * mult
357 | Result.x = (m[0][1] + m[1][0]) * mult
358 | Result.y = biggestVal
359 | Result.z = (m[1][2] + m[2][1]) * mult
360 | break
361 | case 3:
362 | Result.w = (m[0][1] - m[1][0]) * mult
363 | Result.x = (m[2][0] + m[0][2]) * mult
364 | Result.y = (m[1][2] + m[2][1]) * mult
365 | Result.z = biggestVal
366 | break
367 |
368 | default:
369 | assert(false)
370 | break
371 | }
372 | return Result
373 | }
374 |
375 | /// Converts a 4 * 4 matrix to a quaternion.
376 | public func quat_cast(m: float4x4) -> quat {
377 | return quat_cast(float3x3(m))
378 | }
379 |
380 | /// Returns the quaternion rotation angle.
381 | public func angle(q: quat) -> Float {
382 | return acos(q.w) * Float(2)
383 | }
384 |
385 | /// Returns the q rotation axis.
386 | public func axis(q: quat) -> float3 {
387 | let tmp1 = Float(1) - q.w * q.w
388 | if (tmp1 <= Float(0)) {
389 | return float3(0, 0, 1)
390 | }
391 | let tmp2 = Float(1) / sqrt(tmp1)
392 | return float3(q.x * tmp2, q.y * tmp2, q.z * tmp2)
393 | }
394 |
395 | /// Build a quaternion from an angle and a normalized axis.
396 | public func angleAxis(angle: Float, axis: float3) -> quat {
397 | var Result = quat()
398 |
399 | let a = angle
400 | let s = sin(a * Float(0.5))
401 |
402 | Result.w = cos(a * Float(0.5))
403 | Result.x = axis.x * s
404 | Result.y = axis.y * s
405 | Result.z = axis.z * s
406 | return Result
407 | }
408 |
409 | public struct dquat: ArrayLiteralConvertible, CustomDebugStringConvertible {
410 | public var x: Double
411 | public var y: Double
412 | public var z: Double
413 | public var w: Double
414 |
415 | public init() {
416 | x = 0
417 | y = 0
418 | z = 0
419 | w = 1
420 | }
421 |
422 | public init(w: Double, v: double3) {
423 | x = v.x
424 | y = v.y
425 | z = v.z
426 | self.w = w
427 | }
428 |
429 | public init(angle: Double, axis: double3) {
430 | self = angleAxis(angle, axis: axis)
431 | }
432 |
433 | public init(_ w: Double, _ x: Double, _ y: Double, _ z: Double) {
434 | self.x = x
435 | self.y = y
436 | self.z = z
437 | self.w = w
438 | }
439 |
440 | public init(_ q: dquat) {
441 | x = q.x
442 | y = q.y
443 | z = q.z
444 | w = q.w
445 | }
446 |
447 | /// Initialize to a vector with elements taken from `array`.
448 | ///
449 | /// - Precondition: `array` must have exactly four elements.
450 | public init(_ array: [Double]) {
451 | w = array[0]
452 | x = array[1]
453 | y = array[2]
454 | z = array[3]
455 | }
456 |
457 | /// Initialize using `arrayLiteral`.
458 | ///
459 | /// - Precondition: the array literal must exactly four elements.
460 | public init(arrayLiteral elements: Double...) {
461 | w = elements[0]
462 | x = elements[1]
463 | y = elements[2]
464 | z = elements[3]
465 | }
466 |
467 |
468 | /// Create a quaternion from two normalized axis
469 | /// @see http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors
470 | public init(_ u: double3, _ v: double3) {
471 | let LocalW = cross(u, v)
472 | let Dot = dot(u, v)
473 | let q = dquat(1 + Dot, LocalW.x, LocalW.y, LocalW.z)
474 | self.init(normalize(q))
475 | }
476 |
477 | public init(_ eulerAngle: double3) {
478 | let c = cos(eulerAngle * Double(0.5))
479 | let s = sin(eulerAngle * Double(0.5))
480 |
481 | w = c.x * c.y * c.z + s.x * s.y * s.z
482 | x = s.x * c.y * c.z - c.x * s.y * s.z
483 | y = c.x * s.y * c.z + s.x * c.y * s.z
484 | z = c.x * c.y * s.z - s.x * s.y * c.z
485 | }
486 |
487 | public init(_ m: double3x3) {
488 | self.init(dquat_cast(m))
489 | }
490 |
491 | public init(_ m: double4x4) {
492 | self.init(dquat_cast(m))
493 | }
494 |
495 | public var debugDescription: String {
496 | get {
497 | return ""
498 | }
499 | }
500 | }
501 |
502 | prefix public func +(q: dquat) -> dquat {
503 | return q
504 | }
505 |
506 | prefix public func -(q: dquat) -> dquat {
507 | return dquat( -q.w, -q.x, -q.y, -q.z)
508 | }
509 |
510 | public func +(q: dquat, p: dquat) -> dquat {
511 | return dquat(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z)
512 | }
513 |
514 | public func *(p: dquat, q: dquat) -> dquat {
515 |
516 | let w = p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z
517 | let x = p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y
518 | let y = p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z
519 | let z = p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x
520 | return dquat(w, x, y, z)
521 | }
522 |
523 | public func *(q: dquat, v: double3) -> double3 {
524 | let QuatVector = double3(q.x, q.y, q.z)
525 | let uv = cross(QuatVector, v)
526 | let uuv = cross(QuatVector, uv)
527 |
528 | return v + ((uv * q.w) + uuv) * Double(2)
529 | }
530 |
531 | public func *(v: double3, q: dquat) -> double3 {
532 | return inverse(q) * v
533 | }
534 |
535 | public func *(q: dquat, v: double4) -> double4 {
536 | return double4(q * double3(v), v.w)
537 | }
538 |
539 | public func *(v: double4, q: dquat) -> double4 {
540 | return inverse(q) * v
541 | }
542 |
543 | public func *(q: dquat, p: Double) -> dquat {
544 | return dquat(q.w * p, q.x * p, q.y * p, q.z * p)
545 | }
546 |
547 | public func *(p: Double, q: dquat) -> dquat {
548 | return q * p
549 | }
550 |
551 | public func /(q: dquat, p: Double) -> dquat {
552 | return dquat(q.w / p, q.x / p, q.y / p, q.z / p)
553 | }
554 |
555 | /// Returns the normalized quaternion.
556 | public func normalize(q: dquat) -> dquat {
557 | let len = length(q)
558 | if (len <= Double(0)) {
559 | // Problem
560 | return dquat(1, 0, 0, 0)
561 | }
562 | let oneOverLen = Double(1) / len
563 | return dquat(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen)
564 | }
565 |
566 | /// Returns the length of the quaternion.
567 | public func length(q: dquat) -> Double {
568 | return sqrt(dot(q, q))
569 | }
570 |
571 | /// Returns the q conjugate.
572 | public func conjugate(q: dquat) -> dquat {
573 | return dquat(q.w, -q.x, -q.y, -q.z)
574 | }
575 |
576 | /// Returns the q inverse.
577 | public func inverse(q: dquat) -> dquat {
578 | return conjugate(q) / dot(q, q)
579 | }
580 |
581 | /// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ...
582 | public func dot(q1: dquat, _ q2: dquat) -> Double {
583 | let tmp = double4(q1.x * q2.x, q1.y * q2.y, q1.z * q2.z, q1.w * q2.w)
584 | return (tmp.x + tmp.y) + (tmp.z + tmp.w)
585 | }
586 |
587 | /// Spherical linear interpolation of two quaternions.
588 | /// The interpolation is oriented and the rotation is performed at constant speed.
589 | /// For short path spherical linear interpolation, use the slerp function.
590 | public func mix(x: dquat, _ y: dquat, _ a: Double) -> dquat {
591 | let cosTheta = dot(x, y);
592 |
593 | // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
594 | if (cosTheta > Double(1) - Double(0.0000001)) {
595 |
596 | // Linear interpolation
597 | return dquat(
598 | mix(x.w, y.w, a),
599 | mix(x.x, y.x, a),
600 | mix(x.y, y.y, a),
601 | mix(x.z, y.z, a))
602 | } else {
603 | // Essential Mathematics, page 467
604 | let angle = acos(cosTheta)
605 | return (sin((Double(1) - a) * angle) * x + sin(a * angle) * y) / sin(angle)
606 | }
607 | }
608 |
609 | /// Linear interpolation of two quaternions.
610 | /// The interpolation is oriented.
611 | public func lerp(x: dquat, _ y: dquat, _ a: Double) -> dquat {
612 | return x * (Double(1) - a) + (y * a)
613 | }
614 |
615 | /// Spherical linear interpolation of two quaternions.
616 | /// The interpolation always take the short path and the rotation is performed at constant speed.
617 | public func slerp(x: dquat, _ y: dquat, _ a: Double) -> dquat {
618 | var z = y
619 |
620 | var cosTheta = dot(x, y)
621 |
622 | // If cosTheta < 0, the interpolation will take the long way around the sphere.
623 | // To fix this, one quat must be negated.
624 | if (cosTheta < Double(0)) {
625 | z = -y
626 | cosTheta = -cosTheta
627 | }
628 |
629 | // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
630 | if (cosTheta > Double(1) - Double(0.0000001)) {
631 | // Linear interpolation
632 | return dquat(
633 | mix(x.w, z.w, a),
634 | mix(x.x, z.x, a),
635 | mix(x.y, z.y, a),
636 | mix(x.z, z.z, a))
637 | } else {
638 | // Essential Mathematics, page 467
639 | let angle = acos(cosTheta)
640 | return (sin((Double(1) - a) * angle) * x + sin(a * angle) * z) / sin(angle)
641 | }
642 | }
643 |
644 | /// Rotates a quaternion from a vector of 3 components axis and an angle.
645 | public func rotate(q: dquat, angle: Double, axis: double3) -> dquat {
646 | var tmp = axis
647 |
648 | // Axis of rotation must be normalised
649 | let len = length(tmp)
650 | if (abs(len - Double(1)) > Double(0.001)) {
651 | let oneOverLen = Double(1) / len
652 | tmp *= oneOverLen
653 | }
654 |
655 | let AngleRad = angle
656 | let Sin = sin(AngleRad * Double(0.5))
657 |
658 | return q * dquat(cos(AngleRad * Double(0.5)), tmp.x * Sin, tmp.y * Sin, tmp.z * Sin)
659 | }
660 |
661 | /// Returns euler angles, yitch as x, yaw as y, roll as z.
662 | /// The result is expressed in radians if GLM_FORCE_RADIANS is defined or degrees otherwise.
663 | public func eulerAngles(x: dquat) -> double3 {
664 | return double3(pitch(x), yaw(x), roll(x))
665 | }
666 |
667 | /// Returns roll value of euler angles expressed in radians.
668 | public func roll(q: dquat) -> Double {
669 | return Double(atan2(Double(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z))
670 | }
671 |
672 | /// Returns pitch value of euler angles expressed in radians.
673 | public func pitch(q: dquat) -> Double {
674 | return Double(atan2(Double(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z))
675 | }
676 |
677 | /// Returns yaw value of euler angles expressed in radians.
678 | public func yaw(q: dquat) -> Double {
679 | return asin(Double(-2) * (q.x * q.z - q.w * q.y))
680 | }
681 |
682 | /// Converts a quaternion to a 3 * 3 matrix.
683 | public func double3x3_cast(q: dquat) -> double3x3 {
684 | var Result = double3x3(1)
685 | let qxx = q.x * q.x
686 | let qyy = q.y * q.y
687 | let qzz = q.z * q.z
688 | let qxz = q.x * q.z
689 | let qxy = q.x * q.y
690 | let qyz = q.y * q.z
691 | let qwx = q.w * q.x
692 | let qwy = q.w * q.y
693 | let qwz = q.w * q.z
694 |
695 | Result[0][0] = 1 - 2 * (qyy + qzz)
696 | Result[0][1] = 2 * (qxy + qwz)
697 | Result[0][2] = 2 * (qxz - qwy)
698 |
699 | Result[1][0] = 2 * (qxy - qwz)
700 | Result[1][1] = 1 - 2 * (qxx + qzz)
701 | Result[1][2] = 2 * (qyz + qwx)
702 |
703 | Result[2][0] = 2 * (qxz + qwy)
704 | Result[2][1] = 2 * (qyz - qwx)
705 | Result[2][2] = 1 - 2 * (qxx + qyy)
706 | return Result
707 | }
708 |
709 | /// Converts a quaternion to a 4 * 4 matrix.
710 | public func double4x4_cast(q: dquat) -> double4x4 {
711 | return double4x4(double3x3_cast(q))
712 | }
713 |
714 | /// Converts a 3 * 3 matrix to a quaternion.
715 | public func dquat_cast(m: double3x3) -> dquat {
716 | let fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2]
717 | let fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2]
718 | let fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1]
719 | let fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2]
720 |
721 | var biggestIndex = 0
722 | var fourBiggestSquaredMinus1 = fourWSquaredMinus1
723 |
724 | if fourXSquaredMinus1 > fourBiggestSquaredMinus1 {
725 | fourBiggestSquaredMinus1 = fourXSquaredMinus1
726 | biggestIndex = 1
727 | }
728 | if fourYSquaredMinus1 > fourBiggestSquaredMinus1 {
729 | fourBiggestSquaredMinus1 = fourYSquaredMinus1
730 | biggestIndex = 2
731 | }
732 | if fourZSquaredMinus1 > fourBiggestSquaredMinus1 {
733 | fourBiggestSquaredMinus1 = fourZSquaredMinus1
734 | biggestIndex = 3
735 | }
736 |
737 | let biggestVal = sqrt(fourBiggestSquaredMinus1 + Double(1)) * Double(0.5)
738 | let mult = Double(0.25) / biggestVal
739 |
740 | var Result = dquat()
741 | switch (biggestIndex) {
742 | case 0:
743 | Result.w = biggestVal
744 | Result.x = (m[1][2] - m[2][1]) * mult
745 | Result.y = (m[2][0] - m[0][2]) * mult
746 | Result.z = (m[0][1] - m[1][0]) * mult
747 | break
748 | case 1:
749 | Result.w = (m[1][2] - m[2][1]) * mult
750 | Result.x = biggestVal
751 | Result.y = (m[0][1] + m[1][0]) * mult
752 | Result.z = (m[2][0] + m[0][2]) * mult
753 | break
754 | case 2:
755 | Result.w = (m[2][0] - m[0][2]) * mult
756 | Result.x = (m[0][1] + m[1][0]) * mult
757 | Result.y = biggestVal
758 | Result.z = (m[1][2] + m[2][1]) * mult
759 | break
760 | case 3:
761 | Result.w = (m[0][1] - m[1][0]) * mult
762 | Result.x = (m[2][0] + m[0][2]) * mult
763 | Result.y = (m[1][2] + m[2][1]) * mult
764 | Result.z = biggestVal
765 | break
766 |
767 | default:
768 | assert(false)
769 | break
770 | }
771 | return Result
772 | }
773 |
774 | /// Converts a 4 * 4 matrix to a quaternion.
775 | public func dquat_cast(m: double4x4) -> dquat {
776 | return dquat_cast(double3x3(m))
777 | }
778 |
779 | /// Returns the quaternion rotation angle.
780 | public func angle(q: dquat) -> Double {
781 | return acos(q.w) * Double(2)
782 | }
783 |
784 | /// Returns the q rotation axis.
785 | public func axis(q: dquat) -> double3 {
786 | let tmp1 = Double(1) - q.w * q.w
787 | if (tmp1 <= Double(0)) {
788 | return double3(0, 0, 1)
789 | }
790 | let tmp2 = Double(1) / sqrt(tmp1)
791 | return double3(q.x * tmp2, q.y * tmp2, q.z * tmp2)
792 | }
793 |
794 | /// Build a quaternion from an angle and a normalized axis.
795 | public func angleAxis(angle: Double, axis: double3) -> dquat {
796 | var Result = dquat()
797 |
798 | let a = angle
799 | let s = sin(a * Double(0.5))
800 |
801 | Result.w = cos(a * Double(0.5))
802 | Result.x = axis.x * s
803 | Result.y = axis.y * s
804 | Result.z = axis.z * s
805 | return Result
806 | }
--------------------------------------------------------------------------------
/Tests/swift3DQuaterionTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // swift3DQuaterionTests.swift
3 | // swift3D
4 | //
5 | // Created by Adrian Krupa on 02.01.2016.
6 | // Copyright © 2016 Adrian Krupa. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import swift3D
11 |
12 | class swift_3D_testQuaterionFloat: XCTestCase {
13 |
14 | func testQuaternionEmptyConstructor() {
15 | let q = quat()
16 | XCTAssert(glm_to_swift_quat.quatInitWithResult(float4(q)))
17 | }
18 |
19 | func testQuaternionValuesConstructor() {
20 | let w: Float = 0.3
21 | let x: Float = 2.2
22 | let y: Float = 1.7
23 | let z: Float = 2.5
24 | let q = quat(w, x, y, z)
25 | XCTAssert(glm_to_swift_quat.quatInitWithValuesW(w, valueX: x, valueY: y, valueZ: z, andResult: float4(q)))
26 | }
27 |
28 | func testQuaternionSandV3() {
29 | let s: Float = 0.5
30 | let v = float3(0.2, 0.5, 2.2)
31 | let q = quat(w: s, v: v)
32 | XCTAssert(glm_to_swift_quat.quatInitWithFloat(s, andVec3: v, andResult: float4(q)))
33 | }
34 |
35 | func testQuaternionInitAngleAxis() {
36 | let angle: Float = Float(M_PI_4)
37 | let v = normalize(float3(0.2, 0.5, 2.2))
38 | let q = quat(angle: angle, axis: v)
39 | XCTAssert(glm_to_swift_quat.quatInitWithAngle(angle, andAxis: v, andResult: float4(q)))
40 | }
41 |
42 | func testQuaternionQuaternionConstructor() {
43 | let w: Float = 0.3
44 | let x: Float = 2.2
45 | let y: Float = 1.7
46 | let z: Float = 2.5
47 | let q = quat(w, x, y, z)
48 | let q2 = quat(q)
49 | XCTAssert(glm_to_swift_quat.quatInitWithQuatWithInitValuesW(w, valueX: x, valueY: y, valueZ: z, andResult: float4(q2)))
50 | }
51 |
52 | func testQuaternionInitEulerAngles() {
53 | let angle = float3(-2.5, 33.213, 12.2)
54 | let q = quat(angle)
55 |
56 | XCTAssert(glm_to_swift_quat.quatInitWithEulerAngles(angle, andResult: float4(q)))
57 | }
58 |
59 | func testQuaternionNormalizedAxis() {
60 | let axis1 = normalize(float3(2.2, 12.6, -3.4))
61 | let axis2 = normalize(float3(13.4, -2.6, 0.003))
62 |
63 | let q = quat(axis1, axis2)
64 | XCTAssert(glm_to_swift_quat.quatInitWithNormalizedAxis(axis1, withAxis: axis2, andResult: float4(q)))
65 | }
66 |
67 | func testQuaternionMatrix3x3() {
68 | let m = float3x3([float3(3.3, -3, 2.8), float3(1.6, -12.7, 3.8), float3(6.123, 9.99, 0.0003)])
69 | let q = quat(m)
70 | let m2 = matrix_float3x3(columns: (m[0], m[1], m[2]))
71 | XCTAssert(glm_to_swift_quat.quatInitWithMat3x3(m2, andResult: float4(q)))
72 | }
73 |
74 | func testQuaternionMatrix4x4() {
75 | let m = float4x4([float4(3.3, -3, 2.8, 5.64532), float4(1.6, -12.7, 3.8, -3.45), float4(6.123, 9.99, 0.0003, 222.4322), float4(-11, -22, 345.23, 12.1)])
76 | let q = quat(m)
77 | let m2 = matrix_float4x4(columns: (m[0], m[1], m[2], m[3]))
78 | XCTAssert(glm_to_swift_quat.quatInitWithMat4x4(m2, andResult: float4(q)))
79 | }
80 |
81 | func testQuaternionPlus() {
82 | let q = quat(0.00001, -0.0001, 2.3, -5.6)
83 | XCTAssert(glm_to_swift_quat.quatPlus(float4(q), andResult: float4(+q)))
84 | }
85 |
86 | func testQuaternionMinus() {
87 | let q = quat(0.00001, -0.0001, 2.3, -5.6)
88 | XCTAssert(glm_to_swift_quat.quatMinus(float4(q), andResult: float4(-q)))
89 | }
90 |
91 | func testQuaternionAddition() {
92 | let q1 = quat(1,2,3,4)
93 | let q2 = quat(5,6,7,8)
94 | XCTAssert(glm_to_swift_quat.quatAddition(float4(q1), withQuat: float4(q2), andResult: float4(q1+q2)))
95 |
96 | let q3 = quat(0.5, 2.3, 5.6, -2.01)
97 | let q4 = quat(0.00001, -0.0001, 2.3, -5.6)
98 | XCTAssert(glm_to_swift_quat.quatAddition(float4(q3), withQuat: float4(q4), andResult: float4(q3+q4)))
99 | }
100 |
101 | func testQuaternionMultiplication() {
102 | let q1 = quat(1,2,3,4)
103 | let q2 = quat(5,6,7,8)
104 | XCTAssert(glm_to_swift_quat.quatMultiplication(float4(q1), withQuat: float4(q2), andResult: float4(q1*q2)))
105 |
106 | let q3 = quat(0.5, 2.3, 5.6, -2.01)
107 | let q4 = quat(0.00001, -0.0001, 2.3, -5.6)
108 | XCTAssert(glm_to_swift_quat.quatMultiplication(float4(q3), withQuat: float4(q4), andResult: float4(q3*q4)))
109 | }
110 |
111 | func testQuaternionMultiplicationScalar() {
112 | let q = quat(0.5, 2.3, 5.6, -2.01)
113 | let v = Float(3.4)
114 | XCTAssert(glm_to_swift_quat.quatMultiplication(float4(q), withScalar: v, andResult: float4(q*v)))
115 | }
116 |
117 | func testQuaternionMultiplicationScalar_2() {
118 | let q = quat(0.5, 2.3, 5.6, -2.01)
119 | let v = Float(3.4)
120 | XCTAssert(glm_to_swift_quat.quatMultiplication_2(float4(q), withScalar: v, andResult: float4(v*q)))
121 | }
122 |
123 | func testQuaternionMultiplicationFloat3() {
124 | let q = quat(0.5, 2.3, 5.6, -2.01)
125 | let v = float3(3.4, -3.9, 233)
126 | XCTAssert(glm_to_swift_quat.quatMultiplication(float4(q), withVec3: v, andResult: q*v))
127 | }
128 |
129 | func testQuaternionMultiplicationFloat3_2() {
130 | let q = quat(0.5, 2.3, 5.6, -2.01)
131 | let v = float3(3.4, -3.9, 233)
132 | XCTAssert(glm_to_swift_quat.quatMultiplication_2(float4(q), withVec3: v, andResult: v*q))
133 | }
134 |
135 | func testQuaternionMultiplicationFloat4() {
136 | let q = quat(0.5, 2.3, 5.6, -2.01)
137 | let v = float4(3.4, -3.9, 233, -0.123)
138 | XCTAssert(glm_to_swift_quat.quatMultiplication(float4(q), withVec4: v, andResult: q*v))
139 | }
140 |
141 | func testQuaternionMultiplicationFloat4_2() {
142 | let q = quat(0.5, 2.3, 5.6, -2.01)
143 | let v = float4(3.4, -3.9, 233, -0.123)
144 | XCTAssert(glm_to_swift_quat.quatMultiplication_2(float4(q), withVec4: v, andResult: v*q))
145 | }
146 |
147 | func testQuaternionDivision() {
148 | let q1 = quat(1,2,3,4)
149 | let v1 = Float(3)
150 | XCTAssert(glm_to_swift_quat.quatDivision(float4(q1), withScalar: v1, andResult: float4(q1/v1)))
151 |
152 | let q2 = quat(0.5, 2.3, 5.6, -2.01)
153 | let v2 = Float(-0.3332)
154 | XCTAssert(glm_to_swift_quat.quatDivision(float4(q2), withScalar: v2, andResult: float4(q2/v2)))
155 | }
156 |
157 | func testQuaternionDot() {
158 | let q1 = quat(0.5, 2.3, 5.6, -2.01)
159 | let q2 = quat(0.00001, -0.0001, 2.3, -5.6)
160 | XCTAssert(glm_to_swift_quat.quatDot(float4(q1), withQuat: float4(q2), andResult: dot(q1,q2)))
161 | }
162 |
163 | func testQuaternionLength() {
164 | let q = quat(0.5, 2.3, 5.6, -2.01)
165 | XCTAssert(glm_to_swift_quat.quatLength(float4(q), andResult: length(q)))
166 | }
167 |
168 | func testQuaternionInverse() {
169 | let q = quat(0.5, 2.3, 5.6, -2.01)
170 | XCTAssert(glm_to_swift_quat.quatInverse(float4(q), andResult: float4(inverse(q))))
171 | }
172 |
173 | func testQuaterionNormalization() {
174 | let q = quat(3.3, 12.4, -3.111, 6.00003)
175 |
176 | XCTAssert(glm_to_swift_quat.quatNormalization(float4(q), andResult: float4(normalize(q))))
177 | }
178 |
179 | func testQuaternionConjugate() {
180 | let q = quat(3.3, 12.4, -3.111, 6.00003)
181 |
182 | XCTAssert(glm_to_swift_quat.quatConjugate(float4(q), andResult: float4(conjugate(q))))
183 | }
184 |
185 | func testQuaternionMix() {
186 | let q1 = normalize(quat(3.3, 12.4, -3.111, 6.00003))
187 | let q2 = normalize(quat(0.00001, -0.0001, 2.3, -5.6))
188 |
189 | XCTAssert(glm_to_swift_quat.quatMix(float4(q1), with: float4(q2), at: 0, andResult: float4(mix(q1, q2, Float(0)))))
190 | XCTAssert(glm_to_swift_quat.quatMix(float4(q1), with: float4(q2), at: 0.33, andResult: float4(mix(q1, q2, Float(0.33)))))
191 | XCTAssert(glm_to_swift_quat.quatMix(float4(q1), with: float4(q2), at: 0.67, andResult: float4(mix(q1, q2, Float(0.67)))))
192 | XCTAssert(glm_to_swift_quat.quatMix(float4(q1), with: float4(q2), at: 1, andResult: float4(mix(q1, q2, Float(1)))))
193 |
194 | let q3 = normalize(quat(3.3, 12.4, -3.1, 6))
195 | let q4 = normalize(quat(3.3, 12.4, -3.1, 6))
196 |
197 | XCTAssert(glm_to_swift_quat.quatMix(float4(q3), with: float4(q4), at: 0, andResult: float4(mix(q3, q4, Float(0)))))
198 | XCTAssert(glm_to_swift_quat.quatMix(float4(q3), with: float4(q4), at: 0.33, andResult: float4(mix(q3, q3, Float(0.33)))))
199 | XCTAssert(glm_to_swift_quat.quatMix(float4(q3), with: float4(q4), at: 0.67, andResult: float4(mix(q3, q3, Float(0.67)))))
200 | XCTAssert(glm_to_swift_quat.quatMix(float4(q3), with: float4(q4), at: 1, andResult: float4(mix(q3, q4, Float(1)))))
201 | }
202 |
203 | func testQuaternionLerp() {
204 | let q1 = normalize(quat(3.3, 12.4, -3.111, 6.00003))
205 | let q2 = normalize(quat(0.00001, -0.0001, 2.3, -5.6))
206 |
207 | XCTAssert(glm_to_swift_quat.quatLerp(float4(q1), with: float4(q2), at: 0, andResult: float4(lerp(q1, q2, Float(0)))))
208 | XCTAssert(glm_to_swift_quat.quatLerp(float4(q1), with: float4(q2), at: 0.33, andResult: float4(lerp(q1, q2, Float(0.33)))))
209 | XCTAssert(glm_to_swift_quat.quatLerp(float4(q1), with: float4(q2), at: 0.67, andResult: float4(lerp(q1, q2, Float(0.67)))))
210 | XCTAssert(glm_to_swift_quat.quatLerp(float4(q1), with: float4(q2), at: 1, andResult: float4(lerp(q1, q2, Float(1)))))
211 |
212 | let q3 = normalize(quat(3.3, 12.4, -3.1, 6))
213 | let q4 = normalize(quat(3.3, 12.4, -3.1, 6))
214 |
215 | XCTAssert(glm_to_swift_quat.quatLerp(float4(q3), with: float4(q4), at: 0, andResult: float4(lerp(q3, q4, Float(0)))))
216 | XCTAssert(glm_to_swift_quat.quatLerp(float4(q3), with: float4(q4), at: 0.33, andResult: float4(lerp(q3, q3, Float(0.33)))))
217 | XCTAssert(glm_to_swift_quat.quatLerp(float4(q3), with: float4(q4), at: 0.67, andResult: float4(lerp(q3, q3, Float(0.67)))))
218 | XCTAssert(glm_to_swift_quat.quatLerp(float4(q3), with: float4(q4), at: 1, andResult: float4(lerp(q3, q4, Float(1)))))
219 | }
220 |
221 | func testQuaternionSlerp() {
222 | let q1 = normalize(quat(3.3, 12.4, -3.111, 6.00003))
223 | let q2 = normalize(quat(0.00001, -0.0001, 2.3, -5.6))
224 |
225 | XCTAssert(glm_to_swift_quat.quatSlerp(float4(q1), with: float4(q2), at: 0, andResult: float4(slerp(q1, q2, Float(0)))))
226 | XCTAssert(glm_to_swift_quat.quatSlerp(float4(q1), with: float4(q2), at: 0.33, andResult: float4(slerp(q1, q2, Float(0.33)))))
227 | XCTAssert(glm_to_swift_quat.quatSlerp(float4(q1), with: float4(q2), at: 0.67, andResult: float4(slerp(q1, q2, Float(0.67)))))
228 | XCTAssert(glm_to_swift_quat.quatSlerp(float4(q1), with: float4(q2), at: 1, andResult: float4(slerp(q1, q2, Float(1)))))
229 |
230 | let q3 = normalize(quat(3.3, 12.4, -3.1, 6))
231 | let q4 = normalize(quat(3.3, 12.4, -3.1, 6))
232 |
233 | XCTAssert(glm_to_swift_quat.quatSlerp(float4(q3), with: float4(q4), at: 0, andResult: float4(slerp(q3, q4, Float(0)))))
234 | XCTAssert(glm_to_swift_quat.quatSlerp(float4(q3), with: float4(q4), at: 0.33, andResult: float4(slerp(q3, q3, Float(0.33)))))
235 | XCTAssert(glm_to_swift_quat.quatSlerp(float4(q3), with: float4(q4), at: 0.67, andResult: float4(slerp(q3, q3, Float(0.67)))))
236 | XCTAssert(glm_to_swift_quat.quatSlerp(float4(q3), with: float4(q4), at: 1, andResult: float4(slerp(q3, q4, Float(1)))))
237 | }
238 |
239 | func testQuaternionRotate() {
240 | let q1 = quat()
241 | let axis1 = float3(0, 0, 1)
242 | let angle1 = Float(M_PI_2)
243 | XCTAssert(glm_to_swift_quat.quatRotate(float4(q1), withAngle: angle1, withAxis: axis1, andResult: float4(rotate(q1, angle: angle1, axis: axis1))))
244 |
245 | let q2 = normalize(quat(0.5, -0.5, -3, 6))
246 | let axis2 = float3(-0.33, 5.5, -1)
247 | let angle2 = Float(M_PI)
248 | XCTAssert(glm_to_swift_quat.quatRotate(float4(q2), withAngle: angle2, withAxis: axis2, andResult: float4(rotate(q2, angle: angle2, axis: axis2))))
249 |
250 | let q3 = normalize(quat(0.5, 0.5, 3, 6))
251 | let axis3 = normalize(float3(-0.33, 0.5, 1))
252 | let angle3 = Float(M_PI_4)
253 | XCTAssert(glm_to_swift_quat.quatRotate(float4(q3), withAngle: angle3, withAxis: axis3, andResult: float4(rotate(q3, angle: angle3, axis: axis3))))
254 | }
255 |
256 | func testQuaternionEulerAngles() {
257 | let q = normalize(quat(3.3, 12.4, -3.111, 6.00003))
258 | XCTAssert(glm_to_swift_quat.quatEulerAngles(float4(q), withResult: eulerAngles(q)))
259 | }
260 |
261 | func testQuaternionFloat3x3Cast() {
262 | let q = normalize(quat(3.3, 12.4, -3.111, 6.00003))
263 | let m = float3x3_cast(q)
264 | let m2 = matrix_float3x3(columns: (m[0], m[1], m[2]))
265 | XCTAssert(glm_to_swift_quat.quatFloat3x3Cast(float4(q), withResult: m2))
266 | }
267 |
268 | func testQuaternionFloat4x4Cast() {
269 | let q = normalize(quat(3.3, 12.4, -3.111, 6.00003))
270 | let m = float4x4_cast(q)
271 | let m2 = matrix_float4x4(columns: (m[0], m[1], m[2], m[3]))
272 | XCTAssert(glm_to_swift_quat.quatFloat4x4Cast(float4(q), withResult: m2))
273 | }
274 |
275 | func testQuaternionAxis() {
276 | let q = normalize(quat(3.3, 12.4, -3.111, 6.00003))
277 | XCTAssert(glm_to_swift_quat.quatAxis(float4(q), withResult: axis(q)))
278 | }
279 |
280 | func testQuaternionAngle() {
281 | let q = normalize(quat(3.3, 12.4, -3.111, 6.00003))
282 | XCTAssert(glm_to_swift_quat.quatAngle(float4(q), withResult: angle(q)))
283 | }
284 | }
285 |
286 | class swift_3D_testQuaterionDouble: XCTestCase {
287 |
288 | func testQuaternionEmptyConstructor() {
289 | let q = dquat()
290 | XCTAssert(glm_to_swift_quat.quatInitWithResultDouble(double4(q)))
291 | }
292 |
293 | func testQuaternionValuesConstructor() {
294 | let w: Double = 0.3
295 | let x: Double = 2.2
296 | let y: Double = 1.7
297 | let z: Double = 2.5
298 | let q = dquat(w, x, y, z)
299 | XCTAssert(glm_to_swift_quat.quatInitWithValuesWDouble(w, valueX: x, valueY: y, valueZ: z, andResult: double4(q)))
300 | }
301 |
302 | func testQuaternionSandV3() {
303 | let s: Double = 0.5
304 | let v = double3(0.2, 0.5, 2.2)
305 | let q = dquat(w: s, v: v)
306 | XCTAssert(glm_to_swift_quat.quatInitWithDouble(s, andVec3: v, andResult: double4(q)))
307 | }
308 |
309 | func testQuaternionInitAngleAxis() {
310 | let angle: Double = Double(M_PI_4)
311 | let v = normalize(double3(0.2, 0.5, 2.2))
312 | let q = dquat(angle: angle, axis: v)
313 | XCTAssert(glm_to_swift_quat.quatInitWithAngleDouble(angle, andAxis: v, andResult: double4(q)))
314 | }
315 |
316 | func testQuaternionQuaternionConstructor() {
317 | let w: Double = 0.3
318 | let x: Double = 2.2
319 | let y: Double = 1.7
320 | let z: Double = 2.5
321 | let q = dquat(w, x, y, z)
322 | let q2 = dquat(q)
323 | XCTAssert(glm_to_swift_quat.quatInitWithQuatWithInitValuesWDouble(w, valueX: x, valueY: y, valueZ: z, andResult: double4(q2)))
324 | }
325 |
326 | func testQuaternionInitEulerAngles() {
327 | let angle = double3(-2.5, 33.213, 12.2)
328 | let q = dquat(angle)
329 |
330 | XCTAssert(glm_to_swift_quat.quatInitWithEulerAnglesDouble(angle, andResult: double4(q)))
331 | }
332 |
333 | func testQuaternionNormalizedAxis() {
334 | let axis1 = normalize(double3(2.2, 12.6, -3.4))
335 | let axis2 = normalize(double3(13.4, -2.6, 0.003))
336 |
337 | let q = dquat(axis1, axis2)
338 | XCTAssert(glm_to_swift_quat.quatInitWithNormalizedAxisDouble(axis1, withAxis: axis2, andResult: double4(q)))
339 | }
340 |
341 | func testQuaternionMatrix3x3() {
342 | let m = double3x3([double3(3.3, -3, 2.8), double3(1.6, -12.7, 3.8), double3(6.123, 9.99, 0.0003)])
343 | let q = dquat(m)
344 | let m2 = matrix_double3x3(columns: (m[0], m[1], m[2]))
345 | XCTAssert(glm_to_swift_quat.quatInitWithMat3x3Double(m2, andResult: double4(q)))
346 | }
347 |
348 | func testQuaternionMatrix4x4() {
349 | let m = double4x4([double4(3.3, -3, 2.8, 5.64532), double4(1.6, -12.7, 3.8, -3.45), double4(6.123, 9.99, 0.0003, 222.4322), double4(-11, -22, 345.23, 12.1)])
350 | let q = dquat(m)
351 | let m2 = matrix_double4x4(columns: (m[0], m[1], m[2], m[3]))
352 | XCTAssert(glm_to_swift_quat.quatInitWithMat4x4Double(m2, andResult: double4(q)))
353 | }
354 |
355 | func testQuaternionPlus() {
356 | let q = dquat(0.00001, -0.0001, 2.3, -5.6)
357 | XCTAssert(glm_to_swift_quat.quatPlusDouble(double4(q), andResult: double4(+q)))
358 | }
359 |
360 | func testQuaternionMinus() {
361 | let q = dquat(0.00001, -0.0001, 2.3, -5.6)
362 | XCTAssert(glm_to_swift_quat.quatMinusDouble(double4(q), andResult: double4(-q)))
363 | }
364 |
365 | func testQuaternionAddition() {
366 | let q1 = dquat(1,2,3,4)
367 | let q2 = dquat(5,6,7,8)
368 | XCTAssert(glm_to_swift_quat.quatAdditionDouble(double4(q1), withQuat: double4(q2), andResult: double4(q1+q2)))
369 |
370 | let q3 = dquat(0.5, 2.3, 5.6, -2.01)
371 | let q4 = dquat(0.00001, -0.0001, 2.3, -5.6)
372 | XCTAssert(glm_to_swift_quat.quatAdditionDouble(double4(q3), withQuat: double4(q4), andResult: double4(q3+q4)))
373 | }
374 |
375 | func testQuaternionMultiplication() {
376 | let q1 = dquat(1,2,3,4)
377 | let q2 = dquat(5,6,7,8)
378 | XCTAssert(glm_to_swift_quat.quatMultiplicationDouble(double4(q1), withQuat: double4(q2), andResult: double4(q1*q2)))
379 |
380 | let q3 = dquat(0.5, 2.3, 5.6, -2.01)
381 | let q4 = dquat(0.00001, -0.0001, 2.3, -5.6)
382 | XCTAssert(glm_to_swift_quat.quatMultiplicationDouble(double4(q3), withQuat: double4(q4), andResult: double4(q3*q4)))
383 | }
384 |
385 | func testQuaternionMultiplicationScalar() {
386 | let q = dquat(0.5, 2.3, 5.6, -2.01)
387 | let v = Double(3.4)
388 | XCTAssert(glm_to_swift_quat.quatMultiplicationDouble(double4(q), withScalar: v, andResult: double4(q*v)))
389 | }
390 |
391 | func testQuaternionMultiplicationScalar_2() {
392 | let q = dquat(0.5, 2.3, 5.6, -2.01)
393 | let v = Double(3.4)
394 | XCTAssert(glm_to_swift_quat.quatMultiplication_2Double(double4(q), withScalar: v, andResult: double4(v*q)))
395 | }
396 |
397 | func testQuaternionMultiplicationdouble3() {
398 | let q = dquat(0.5, 2.3, 5.6, -2.01)
399 | let v = double3(3.4, -3.9, 233)
400 | XCTAssert(glm_to_swift_quat.quatMultiplicationDouble(double4(q), withVec3: v, andResult: q*v))
401 | }
402 |
403 | func testQuaternionMultiplicationdouble3_2() {
404 | let q = dquat(0.5, 2.3, 5.6, -2.01)
405 | let v = double3(3.4, -3.9, 233)
406 | XCTAssert(glm_to_swift_quat.quatMultiplication_2Double(double4(q), withVec3: v, andResult: v*q))
407 | }
408 |
409 | func testQuaternionMultiplicationdouble4() {
410 | let q = dquat(0.5, 2.3, 5.6, -2.01)
411 | let v = double4(3.4, -3.9, 233, -0.123)
412 | XCTAssert(glm_to_swift_quat.quatMultiplicationDouble(double4(q), withVec4: v, andResult: q*v))
413 | }
414 |
415 | func testQuaternionMultiplicationdouble4_2() {
416 | let q = dquat(0.5, 2.3, 5.6, -2.01)
417 | let v = double4(3.4, -3.9, 233, -0.123)
418 | XCTAssert(glm_to_swift_quat.quatMultiplication_2Double(double4(q), withVec4: v, andResult: v*q))
419 | }
420 |
421 | func testQuaternionDivision() {
422 | let q1 = dquat(1,2,3,4)
423 | let v1 = Double(3)
424 | XCTAssert(glm_to_swift_quat.quatDivisionDouble(double4(q1), withScalar: v1, andResult: double4(q1/v1)))
425 |
426 | let q2 = dquat(0.5, 2.3, 5.6, -2.01)
427 | let v2 = Double(-0.3332)
428 | XCTAssert(glm_to_swift_quat.quatDivisionDouble(double4(q2), withScalar: v2, andResult: double4(q2/v2)))
429 | }
430 |
431 | func testQuaternionDot() {
432 | let q1 = dquat(0.5, 2.3, 5.6, -2.01)
433 | let q2 = dquat(0.00001, -0.0001, 2.3, -5.6)
434 | XCTAssert(glm_to_swift_quat.quatDotDouble(double4(q1), withQuat: double4(q2), andResult: dot(q1,q2)))
435 | }
436 |
437 | func testQuaternionLength() {
438 | let q = dquat(0.5, 2.3, 5.6, -2.01)
439 | XCTAssert(glm_to_swift_quat.quatLengthDouble(double4(q), andResult: length(q)))
440 | }
441 |
442 | func testQuaternionInverse() {
443 | let q = dquat(0.5, 2.3, 5.6, -2.01)
444 | XCTAssert(glm_to_swift_quat.quatInverseDouble(double4(q), andResult: double4(inverse(q))))
445 | }
446 |
447 | func testQuaterionNormalization() {
448 | let q = dquat(3.3, 12.4, -3.111, 6.00003)
449 |
450 | XCTAssert(glm_to_swift_quat.quatNormalizationDouble(double4(q), andResult: double4(normalize(q))))
451 | }
452 |
453 | func testQuaternionConjugate() {
454 | let q = dquat(3.3, 12.4, -3.111, 6.00003)
455 |
456 | XCTAssert(glm_to_swift_quat.quatConjugateDouble(double4(q), andResult: double4(conjugate(q))))
457 | }
458 |
459 | func testQuaternionMix() {
460 | let q1 = normalize(dquat(3.3, 12.4, -3.111, 6.00003))
461 | let q2 = normalize(dquat(0.00001, -0.0001, 2.3, -5.6))
462 |
463 | XCTAssert(glm_to_swift_quat.quatMixDouble(double4(q1), with: double4(q2), at: 0, andResult: double4(mix(q1, q2, Double(0)))))
464 | XCTAssert(glm_to_swift_quat.quatMixDouble(double4(q1), with: double4(q2), at: 0.33, andResult: double4(mix(q1, q2, Double(0.33)))))
465 | XCTAssert(glm_to_swift_quat.quatMixDouble(double4(q1), with: double4(q2), at: 0.67, andResult: double4(mix(q1, q2, Double(0.67)))))
466 | XCTAssert(glm_to_swift_quat.quatMixDouble(double4(q1), with: double4(q2), at: 1, andResult: double4(mix(q1, q2, Double(1)))))
467 |
468 | let q3 = normalize(dquat(3.3, 12.4, -3.1, 6))
469 | let q4 = normalize(dquat(3.3, 12.4, -3.1, 6))
470 |
471 | XCTAssert(glm_to_swift_quat.quatMixDouble(double4(q3), with: double4(q4), at: 0, andResult: double4(mix(q3, q4, Double(0)))))
472 | XCTAssert(glm_to_swift_quat.quatMixDouble(double4(q3), with: double4(q4), at: 0.33, andResult: double4(mix(q3, q3, Double(0.33)))))
473 | XCTAssert(glm_to_swift_quat.quatMixDouble(double4(q3), with: double4(q4), at: 0.67, andResult: double4(mix(q3, q3, Double(0.67)))))
474 | XCTAssert(glm_to_swift_quat.quatMixDouble(double4(q3), with: double4(q4), at: 1, andResult: double4(mix(q3, q4, Double(1)))))
475 | }
476 |
477 | func testQuaternionLerp() {
478 | let q1 = normalize(dquat(3.3, 12.4, -3.111, 6.00003))
479 | let q2 = normalize(dquat(0.00001, -0.0001, 2.3, -5.6))
480 |
481 | XCTAssert(glm_to_swift_quat.quatLerpDouble(double4(q1), with: double4(q2), at: 0, andResult: double4(lerp(q1, q2, Double(0)))))
482 | XCTAssert(glm_to_swift_quat.quatLerpDouble(double4(q1), with: double4(q2), at: 0.33, andResult: double4(lerp(q1, q2, Double(0.33)))))
483 | XCTAssert(glm_to_swift_quat.quatLerpDouble(double4(q1), with: double4(q2), at: 0.67, andResult: double4(lerp(q1, q2, Double(0.67)))))
484 | XCTAssert(glm_to_swift_quat.quatLerpDouble(double4(q1), with: double4(q2), at: 1, andResult: double4(lerp(q1, q2, Double(1)))))
485 |
486 | let q3 = normalize(dquat(3.3, 12.4, -3.1, 6))
487 | let q4 = normalize(dquat(3.3, 12.4, -3.1, 6))
488 |
489 | XCTAssert(glm_to_swift_quat.quatLerpDouble(double4(q3), with: double4(q4), at: 0, andResult: double4(lerp(q3, q4, Double(0)))))
490 | XCTAssert(glm_to_swift_quat.quatLerpDouble(double4(q3), with: double4(q4), at: 0.33, andResult: double4(lerp(q3, q3, Double(0.33)))))
491 | XCTAssert(glm_to_swift_quat.quatLerpDouble(double4(q3), with: double4(q4), at: 0.67, andResult: double4(lerp(q3, q3, Double(0.67)))))
492 | XCTAssert(glm_to_swift_quat.quatLerpDouble(double4(q3), with: double4(q4), at: 1, andResult: double4(lerp(q3, q4, Double(1)))))
493 | }
494 |
495 | func testQuaternionSlerp() {
496 | let q1 = normalize(dquat(3.3, 12.4, -3.111, 6.00003))
497 | let q2 = normalize(dquat(0.00001, -0.0001, 2.3, -5.6))
498 |
499 | XCTAssert(glm_to_swift_quat.quatSlerpDouble(double4(q1), with: double4(q2), at: 0, andResult: double4(slerp(q1, q2, Double(0)))))
500 | XCTAssert(glm_to_swift_quat.quatSlerpDouble(double4(q1), with: double4(q2), at: 0.33, andResult: double4(slerp(q1, q2, Double(0.33)))))
501 | XCTAssert(glm_to_swift_quat.quatSlerpDouble(double4(q1), with: double4(q2), at: 0.67, andResult: double4(slerp(q1, q2, Double(0.67)))))
502 | XCTAssert(glm_to_swift_quat.quatSlerpDouble(double4(q1), with: double4(q2), at: 1, andResult: double4(slerp(q1, q2, Double(1)))))
503 |
504 | let q3 = normalize(dquat(3.3, 12.4, -3.1, 6))
505 | let q4 = normalize(dquat(3.3, 12.4, -3.1, 6))
506 |
507 | XCTAssert(glm_to_swift_quat.quatSlerpDouble(double4(q3), with: double4(q4), at: 0, andResult: double4(slerp(q3, q4, Double(0)))))
508 | XCTAssert(glm_to_swift_quat.quatSlerpDouble(double4(q3), with: double4(q4), at: 0.33, andResult: double4(slerp(q3, q3, Double(0.33)))))
509 | XCTAssert(glm_to_swift_quat.quatSlerpDouble(double4(q3), with: double4(q4), at: 0.67, andResult: double4(slerp(q3, q3, Double(0.67)))))
510 | XCTAssert(glm_to_swift_quat.quatSlerpDouble(double4(q3), with: double4(q4), at: 1, andResult: double4(slerp(q3, q4, Double(1)))))
511 | }
512 |
513 | func testQuaternionRotate() {
514 | let q1 = dquat()
515 | let axis1 = double3(0, 0, 1)
516 | let angle1 = Double(M_PI_2)
517 | XCTAssert(glm_to_swift_quat.quatRotateDouble(double4(q1), withAngle: angle1, withAxis: axis1, andResult: double4(rotate(q1, angle: angle1, axis: axis1))))
518 |
519 | let q2 = normalize(dquat(0.5, -0.5, -3, 6))
520 | let axis2 = double3(-0.33, 5.5, -1)
521 | let angle2 = Double(M_PI)
522 | XCTAssert(glm_to_swift_quat.quatRotateDouble(double4(q2), withAngle: angle2, withAxis: axis2, andResult: double4(rotate(q2, angle: angle2, axis: axis2))))
523 |
524 | let q3 = normalize(dquat(0.5, 0.5, 3, 6))
525 | let axis3 = normalize(double3(-0.33, 0.5, 1))
526 | let angle3 = Double(M_PI_4)
527 | XCTAssert(glm_to_swift_quat.quatRotateDouble(double4(q3), withAngle: angle3, withAxis: axis3, andResult: double4(rotate(q3, angle: angle3, axis: axis3))))
528 | }
529 |
530 | func testQuaternionEulerAngles() {
531 | let q = normalize(dquat(3.3, 12.4, -3.111, 6.00003))
532 | XCTAssert(glm_to_swift_quat.quatEulerAnglesDouble(double4(q), withResult: eulerAngles(q)))
533 | }
534 |
535 | func testQuaterniondouble3x3Cast() {
536 | let q = normalize(dquat(3.3, 12.4, -3.111, 6.00003))
537 | let m = double3x3_cast(q)
538 | let m2 = matrix_double3x3(columns: (m[0], m[1], m[2]))
539 | XCTAssert(glm_to_swift_quat.quatdouble3x3CastDouble(double4(q), withResult: m2))
540 | }
541 |
542 | func testQuaterniondouble4x4Cast() {
543 | let q = normalize(dquat(3.3, 12.4, -3.111, 6.00003))
544 | let m = double4x4_cast(q)
545 | let m2 = matrix_double4x4(columns: (m[0], m[1], m[2], m[3]))
546 | XCTAssert(glm_to_swift_quat.quatdouble4x4CastDouble(double4(q), withResult: m2))
547 | }
548 |
549 | func testQuaternionAxis() {
550 | let q = normalize(dquat(3.3, 12.4, -3.111, 6.00003))
551 | XCTAssert(glm_to_swift_quat.quatAxisDouble(double4(q), withResult: axis(q)))
552 | }
553 |
554 | func testQuaternionAngle() {
555 | let q = normalize(dquat(3.3, 12.4, -3.111, 6.00003))
556 | XCTAssert(glm_to_swift_quat.quatAngleDouble(double4(q), withResult: angle(q)))
557 | }
558 | }
--------------------------------------------------------------------------------
/swift3D.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3A0FA1AC1C1379E200BB7043 /* Vector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A0FA1AB1C1379E200BB7043 /* Vector.swift */; };
11 | 3A0FA1AD1C1379E200BB7043 /* Vector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A0FA1AB1C1379E200BB7043 /* Vector.swift */; };
12 | 3ABBC6D31BE695DA00D563DF /* swift3D.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3ABBC6C91BE695DA00D563DF /* swift3D.framework */; };
13 | 3AC30B1B1C0BDAA4006DD8AE /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B141C0BDAA4006DD8AE /* Common.swift */; };
14 | 3AC30B1C1C0BDAA4006DD8AE /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B141C0BDAA4006DD8AE /* Common.swift */; };
15 | 3AC30B1D1C0BDAA4006DD8AE /* Exponential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B151C0BDAA4006DD8AE /* Exponential.swift */; };
16 | 3AC30B1E1C0BDAA4006DD8AE /* Exponential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B151C0BDAA4006DD8AE /* Exponential.swift */; };
17 | 3AC30B1F1C0BDAA4006DD8AE /* Geometric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B161C0BDAA4006DD8AE /* Geometric.swift */; };
18 | 3AC30B201C0BDAA4006DD8AE /* Geometric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B161C0BDAA4006DD8AE /* Geometric.swift */; };
19 | 3AC30B211C0BDAA4006DD8AE /* Matrix_Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B171C0BDAA4006DD8AE /* Matrix_Transform.swift */; };
20 | 3AC30B221C0BDAA4006DD8AE /* Matrix_Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B171C0BDAA4006DD8AE /* Matrix_Transform.swift */; };
21 | 3AC30B231C0BDAA4006DD8AE /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B181C0BDAA4006DD8AE /* Matrix.swift */; };
22 | 3AC30B241C0BDAA4006DD8AE /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B181C0BDAA4006DD8AE /* Matrix.swift */; };
23 | 3AC30B271C0BDAA4006DD8AE /* Trigonometric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B1A1C0BDAA4006DD8AE /* Trigonometric.swift */; };
24 | 3AC30B281C0BDAA4006DD8AE /* Trigonometric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B1A1C0BDAA4006DD8AE /* Trigonometric.swift */; };
25 | 3AC30B301C0BDCF5006DD8AE /* swift3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AC30B2F1C0BDCF5006DD8AE /* swift3D.h */; settings = {ATTRIBUTES = (Public, ); }; };
26 | 3AC30B311C0BDCF5006DD8AE /* swift3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AC30B2F1C0BDCF5006DD8AE /* swift3D.h */; };
27 | 3AC30B341C0BE048006DD8AE /* swift3DTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B331C0BE048006DD8AE /* swift3DTests.swift */; };
28 | 3AC30B351C0BE048006DD8AE /* swift3DTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B331C0BE048006DD8AE /* swift3DTests.swift */; };
29 | 3AC30B381C0BE05E006DD8AE /* glm-to-swift.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B361C0BE05E006DD8AE /* glm-to-swift.mm */; };
30 | 3AC30B391C0BE05E006DD8AE /* glm-to-swift.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B361C0BE05E006DD8AE /* glm-to-swift.mm */; };
31 | 3AC30B3C1C0CF3B9006DD8AE /* glm in Resources */ = {isa = PBXBuildFile; fileRef = 3AC30B3B1C0CF3B9006DD8AE /* glm */; };
32 | 3AC30B3D1C0CF3B9006DD8AE /* glm in Resources */ = {isa = PBXBuildFile; fileRef = 3AC30B3B1C0CF3B9006DD8AE /* glm */; };
33 | 3AC30B3F1C0CF618006DD8AE /* Quaternion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B3E1C0CF618006DD8AE /* Quaternion.swift */; };
34 | 3AC30B401C0CF618006DD8AE /* Quaternion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC30B3E1C0CF618006DD8AE /* Quaternion.swift */; };
35 | 3AF992631C381C560061E157 /* swift3DQuaterionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AF992621C381C560061E157 /* swift3DQuaterionTests.swift */; };
36 | 3AF992641C381C560061E157 /* swift3DQuaterionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AF992621C381C560061E157 /* swift3DQuaterionTests.swift */; };
37 | 3AF9926A1C384A030061E157 /* glm-to-swift-quat.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3AF992691C384A030061E157 /* glm-to-swift-quat.mm */; };
38 | 3AF9926B1C384A030061E157 /* glm-to-swift-quat.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3AF992691C384A030061E157 /* glm-to-swift-quat.mm */; };
39 | /* End PBXBuildFile section */
40 |
41 | /* Begin PBXContainerItemProxy section */
42 | 3ABBC6D41BE695DA00D563DF /* PBXContainerItemProxy */ = {
43 | isa = PBXContainerItemProxy;
44 | containerPortal = 3ABBC6141BE68FF500D563DF /* Project object */;
45 | proxyType = 1;
46 | remoteGlobalIDString = 3ABBC6C81BE695DA00D563DF;
47 | remoteInfo = swift3D;
48 | };
49 | 3ABBC6F01BE696DB00D563DF /* PBXContainerItemProxy */ = {
50 | isa = PBXContainerItemProxy;
51 | containerPortal = 3ABBC6141BE68FF500D563DF /* Project object */;
52 | proxyType = 1;
53 | remoteGlobalIDString = 3ABBC6E41BE696DB00D563DF;
54 | remoteInfo = swift3D;
55 | };
56 | /* End PBXContainerItemProxy section */
57 |
58 | /* Begin PBXFileReference section */
59 | 3A0FA1AB1C1379E200BB7043 /* Vector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Vector.swift; path = Source/Vector.swift; sourceTree = SOURCE_ROOT; };
60 | 3ABBC6C91BE695DA00D563DF /* swift3D.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = swift3D.framework; sourceTree = BUILT_PRODUCTS_DIR; };
61 | 3ABBC6D21BE695DA00D563DF /* swift3DTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = swift3DTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
62 | 3AC30B141C0BDAA4006DD8AE /* Common.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Common.swift; path = Source/Common.swift; sourceTree = SOURCE_ROOT; };
63 | 3AC30B151C0BDAA4006DD8AE /* Exponential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Exponential.swift; path = Source/Exponential.swift; sourceTree = SOURCE_ROOT; };
64 | 3AC30B161C0BDAA4006DD8AE /* Geometric.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Geometric.swift; path = Source/Geometric.swift; sourceTree = SOURCE_ROOT; };
65 | 3AC30B171C0BDAA4006DD8AE /* Matrix_Transform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Matrix_Transform.swift; path = Source/Matrix_Transform.swift; sourceTree = SOURCE_ROOT; };
66 | 3AC30B181C0BDAA4006DD8AE /* Matrix.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Matrix.swift; path = Source/Matrix.swift; sourceTree = SOURCE_ROOT; };
67 | 3AC30B1A1C0BDAA4006DD8AE /* Trigonometric.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Trigonometric.swift; path = Source/Trigonometric.swift; sourceTree = SOURCE_ROOT; };
68 | 3AC30B291C0BDAB5006DD8AE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Source/Info.plist; sourceTree = SOURCE_ROOT; };
69 | 3AC30B2F1C0BDCF5006DD8AE /* swift3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = swift3D.h; path = Source/swift3D.h; sourceTree = SOURCE_ROOT; };
70 | 3AC30B321C0BE016006DD8AE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Tests/Info.plist; sourceTree = SOURCE_ROOT; };
71 | 3AC30B331C0BE048006DD8AE /* swift3DTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = swift3DTests.swift; path = Tests/swift3DTests.swift; sourceTree = SOURCE_ROOT; };
72 | 3AC30B361C0BE05E006DD8AE /* glm-to-swift.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "glm-to-swift.mm"; path = "Tests/glm-to-swift.mm"; sourceTree = SOURCE_ROOT; };
73 | 3AC30B371C0BE05E006DD8AE /* swift3DTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "swift3DTests-Bridging-Header.h"; path = "Tests/swift3DTests-Bridging-Header.h"; sourceTree = SOURCE_ROOT; };
74 | 3AC30B3A1C0BE065006DD8AE /* glm-to-swift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "glm-to-swift.h"; path = "Tests/glm-to-swift.h"; sourceTree = SOURCE_ROOT; };
75 | 3AC30B3B1C0CF3B9006DD8AE /* glm */ = {isa = PBXFileReference; lastKnownFileType = folder; name = glm; path = Tests/glm; sourceTree = SOURCE_ROOT; };
76 | 3AC30B3E1C0CF618006DD8AE /* Quaternion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Quaternion.swift; path = Source/Quaternion.swift; sourceTree = SOURCE_ROOT; };
77 | 3AF992621C381C560061E157 /* swift3DQuaterionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = swift3DQuaterionTests.swift; path = Tests/swift3DQuaterionTests.swift; sourceTree = SOURCE_ROOT; };
78 | 3AF992681C3849970061E157 /* glm-to-swift-quat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "glm-to-swift-quat.h"; path = "Tests/glm-to-swift-quat.h"; sourceTree = SOURCE_ROOT; };
79 | 3AF992691C384A030061E157 /* glm-to-swift-quat.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "glm-to-swift-quat.mm"; path = "Tests/glm-to-swift-quat.mm"; sourceTree = SOURCE_ROOT; };
80 | /* End PBXFileReference section */
81 |
82 | /* Begin PBXFrameworksBuildPhase section */
83 | 3ABBC6C51BE695DA00D563DF /* Frameworks */ = {
84 | isa = PBXFrameworksBuildPhase;
85 | buildActionMask = 2147483647;
86 | files = (
87 | );
88 | runOnlyForDeploymentPostprocessing = 0;
89 | };
90 | 3ABBC6CF1BE695DA00D563DF /* Frameworks */ = {
91 | isa = PBXFrameworksBuildPhase;
92 | buildActionMask = 2147483647;
93 | files = (
94 | 3ABBC6D31BE695DA00D563DF /* swift3D.framework in Frameworks */,
95 | );
96 | runOnlyForDeploymentPostprocessing = 0;
97 | };
98 | 3ABBC6E11BE696DB00D563DF /* Frameworks */ = {
99 | isa = PBXFrameworksBuildPhase;
100 | buildActionMask = 2147483647;
101 | files = (
102 | );
103 | runOnlyForDeploymentPostprocessing = 0;
104 | };
105 | 3ABBC6EB1BE696DB00D563DF /* Frameworks */ = {
106 | isa = PBXFrameworksBuildPhase;
107 | buildActionMask = 2147483647;
108 | files = (
109 | );
110 | runOnlyForDeploymentPostprocessing = 0;
111 | };
112 | /* End PBXFrameworksBuildPhase section */
113 |
114 | /* Begin PBXGroup section */
115 | 3ABBC6131BE68FF500D563DF = {
116 | isa = PBXGroup;
117 | children = (
118 | 3ABBC6CA1BE695DA00D563DF /* Source */,
119 | 3ABBC6D61BE695DA00D563DF /* Tests */,
120 | 3ABBC61E1BE68FF500D563DF /* Products */,
121 | );
122 | sourceTree = "";
123 | };
124 | 3ABBC61E1BE68FF500D563DF /* Products */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 3ABBC6C91BE695DA00D563DF /* swift3D.framework */,
128 | 3ABBC6D21BE695DA00D563DF /* swift3DTests.xctest */,
129 | );
130 | name = Products;
131 | sourceTree = "";
132 | };
133 | 3ABBC6CA1BE695DA00D563DF /* Source */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 3AC30B141C0BDAA4006DD8AE /* Common.swift */,
137 | 3AC30B151C0BDAA4006DD8AE /* Exponential.swift */,
138 | 3AC30B161C0BDAA4006DD8AE /* Geometric.swift */,
139 | 3AC30B171C0BDAA4006DD8AE /* Matrix_Transform.swift */,
140 | 3AC30B181C0BDAA4006DD8AE /* Matrix.swift */,
141 | 3AC30B1A1C0BDAA4006DD8AE /* Trigonometric.swift */,
142 | 3AC30B2F1C0BDCF5006DD8AE /* swift3D.h */,
143 | 3ABBC6FF1BE6996800D563DF /* Supporting Files */,
144 | 3AC30B3E1C0CF618006DD8AE /* Quaternion.swift */,
145 | 3A0FA1AB1C1379E200BB7043 /* Vector.swift */,
146 | );
147 | name = Source;
148 | path = swift3D;
149 | sourceTree = "";
150 | };
151 | 3ABBC6D61BE695DA00D563DF /* Tests */ = {
152 | isa = PBXGroup;
153 | children = (
154 | 3AC30B331C0BE048006DD8AE /* swift3DTests.swift */,
155 | 3AF992621C381C560061E157 /* swift3DQuaterionTests.swift */,
156 | 3ABBC7001BE6997700D563DF /* Supporting Files */,
157 | 3AC30B3B1C0CF3B9006DD8AE /* glm */,
158 | 3AC30B3A1C0BE065006DD8AE /* glm-to-swift.h */,
159 | 3AC30B361C0BE05E006DD8AE /* glm-to-swift.mm */,
160 | 3AF992681C3849970061E157 /* glm-to-swift-quat.h */,
161 | 3AF992691C384A030061E157 /* glm-to-swift-quat.mm */,
162 | 3AC30B371C0BE05E006DD8AE /* swift3DTests-Bridging-Header.h */,
163 | );
164 | name = Tests;
165 | path = swift3DTests;
166 | sourceTree = "";
167 | };
168 | 3ABBC6FF1BE6996800D563DF /* Supporting Files */ = {
169 | isa = PBXGroup;
170 | children = (
171 | 3AC30B291C0BDAB5006DD8AE /* Info.plist */,
172 | );
173 | name = "Supporting Files";
174 | sourceTree = "";
175 | };
176 | 3ABBC7001BE6997700D563DF /* Supporting Files */ = {
177 | isa = PBXGroup;
178 | children = (
179 | 3AC30B321C0BE016006DD8AE /* Info.plist */,
180 | );
181 | name = "Supporting Files";
182 | sourceTree = "";
183 | };
184 | /* End PBXGroup section */
185 |
186 | /* Begin PBXHeadersBuildPhase section */
187 | 3ABBC6C61BE695DA00D563DF /* Headers */ = {
188 | isa = PBXHeadersBuildPhase;
189 | buildActionMask = 2147483647;
190 | files = (
191 | 3AC30B301C0BDCF5006DD8AE /* swift3D.h in Headers */,
192 | );
193 | runOnlyForDeploymentPostprocessing = 0;
194 | };
195 | 3ABBC6E21BE696DB00D563DF /* Headers */ = {
196 | isa = PBXHeadersBuildPhase;
197 | buildActionMask = 2147483647;
198 | files = (
199 | 3AC30B311C0BDCF5006DD8AE /* swift3D.h in Headers */,
200 | );
201 | runOnlyForDeploymentPostprocessing = 0;
202 | };
203 | /* End PBXHeadersBuildPhase section */
204 |
205 | /* Begin PBXNativeTarget section */
206 | 3ABBC6C81BE695DA00D563DF /* swift3D-Mac */ = {
207 | isa = PBXNativeTarget;
208 | buildConfigurationList = 3ABBC6DA1BE695DA00D563DF /* Build configuration list for PBXNativeTarget "swift3D-Mac" */;
209 | buildPhases = (
210 | 3ABBC6C41BE695DA00D563DF /* Sources */,
211 | 3ABBC6C51BE695DA00D563DF /* Frameworks */,
212 | 3ABBC6C61BE695DA00D563DF /* Headers */,
213 | 3ABBC6C71BE695DA00D563DF /* Resources */,
214 | );
215 | buildRules = (
216 | );
217 | dependencies = (
218 | );
219 | name = "swift3D-Mac";
220 | productName = swift3D;
221 | productReference = 3ABBC6C91BE695DA00D563DF /* swift3D.framework */;
222 | productType = "com.apple.product-type.framework";
223 | };
224 | 3ABBC6D11BE695DA00D563DF /* swift3DTests-Mac */ = {
225 | isa = PBXNativeTarget;
226 | buildConfigurationList = 3ABBC6DD1BE695DA00D563DF /* Build configuration list for PBXNativeTarget "swift3DTests-Mac" */;
227 | buildPhases = (
228 | 3ABBC6CE1BE695DA00D563DF /* Sources */,
229 | 3ABBC6CF1BE695DA00D563DF /* Frameworks */,
230 | 3ABBC6D01BE695DA00D563DF /* Resources */,
231 | );
232 | buildRules = (
233 | );
234 | dependencies = (
235 | 3ABBC6D51BE695DA00D563DF /* PBXTargetDependency */,
236 | );
237 | name = "swift3DTests-Mac";
238 | productName = swift3DTests;
239 | productReference = 3ABBC6D21BE695DA00D563DF /* swift3DTests.xctest */;
240 | productType = "com.apple.product-type.bundle.unit-test";
241 | };
242 | 3ABBC6E41BE696DB00D563DF /* swift3D-iOS */ = {
243 | isa = PBXNativeTarget;
244 | buildConfigurationList = 3ABBC6F61BE696DB00D563DF /* Build configuration list for PBXNativeTarget "swift3D-iOS" */;
245 | buildPhases = (
246 | 3ABBC6E01BE696DB00D563DF /* Sources */,
247 | 3ABBC6E11BE696DB00D563DF /* Frameworks */,
248 | 3ABBC6E21BE696DB00D563DF /* Headers */,
249 | 3ABBC6E31BE696DB00D563DF /* Resources */,
250 | );
251 | buildRules = (
252 | );
253 | dependencies = (
254 | );
255 | name = "swift3D-iOS";
256 | productName = swift3D;
257 | productType = "com.apple.product-type.framework";
258 | };
259 | 3ABBC6ED1BE696DB00D563DF /* swift3DTests-iOS */ = {
260 | isa = PBXNativeTarget;
261 | buildConfigurationList = 3ABBC6F91BE696DB00D563DF /* Build configuration list for PBXNativeTarget "swift3DTests-iOS" */;
262 | buildPhases = (
263 | 3ABBC6EA1BE696DB00D563DF /* Sources */,
264 | 3ABBC6EB1BE696DB00D563DF /* Frameworks */,
265 | 3ABBC6EC1BE696DB00D563DF /* Resources */,
266 | );
267 | buildRules = (
268 | );
269 | dependencies = (
270 | 3ABBC6F11BE696DB00D563DF /* PBXTargetDependency */,
271 | );
272 | name = "swift3DTests-iOS";
273 | productName = swift3DTests;
274 | productType = "com.apple.product-type.bundle.unit-test";
275 | };
276 | /* End PBXNativeTarget section */
277 |
278 | /* Begin PBXProject section */
279 | 3ABBC6141BE68FF500D563DF /* Project object */ = {
280 | isa = PBXProject;
281 | attributes = {
282 | LastSwiftUpdateCheck = 0710;
283 | LastUpgradeCheck = 0710;
284 | ORGANIZATIONNAME = "Adrian Krupa";
285 | TargetAttributes = {
286 | 3ABBC6C81BE695DA00D563DF = {
287 | CreatedOnToolsVersion = 7.1;
288 | };
289 | 3ABBC6D11BE695DA00D563DF = {
290 | CreatedOnToolsVersion = 7.1;
291 | };
292 | 3ABBC6E41BE696DB00D563DF = {
293 | CreatedOnToolsVersion = 7.1;
294 | };
295 | 3ABBC6ED1BE696DB00D563DF = {
296 | CreatedOnToolsVersion = 7.1;
297 | };
298 | };
299 | };
300 | buildConfigurationList = 3ABBC6171BE68FF500D563DF /* Build configuration list for PBXProject "swift3D" */;
301 | compatibilityVersion = "Xcode 3.2";
302 | developmentRegion = English;
303 | hasScannedForEncodings = 0;
304 | knownRegions = (
305 | en,
306 | );
307 | mainGroup = 3ABBC6131BE68FF500D563DF;
308 | productRefGroup = 3ABBC61E1BE68FF500D563DF /* Products */;
309 | projectDirPath = "";
310 | projectRoot = "";
311 | targets = (
312 | 3ABBC6C81BE695DA00D563DF /* swift3D-Mac */,
313 | 3ABBC6D11BE695DA00D563DF /* swift3DTests-Mac */,
314 | 3ABBC6E41BE696DB00D563DF /* swift3D-iOS */,
315 | 3ABBC6ED1BE696DB00D563DF /* swift3DTests-iOS */,
316 | );
317 | };
318 | /* End PBXProject section */
319 |
320 | /* Begin PBXResourcesBuildPhase section */
321 | 3ABBC6C71BE695DA00D563DF /* Resources */ = {
322 | isa = PBXResourcesBuildPhase;
323 | buildActionMask = 2147483647;
324 | files = (
325 | );
326 | runOnlyForDeploymentPostprocessing = 0;
327 | };
328 | 3ABBC6D01BE695DA00D563DF /* Resources */ = {
329 | isa = PBXResourcesBuildPhase;
330 | buildActionMask = 2147483647;
331 | files = (
332 | 3AC30B3C1C0CF3B9006DD8AE /* glm in Resources */,
333 | );
334 | runOnlyForDeploymentPostprocessing = 0;
335 | };
336 | 3ABBC6E31BE696DB00D563DF /* Resources */ = {
337 | isa = PBXResourcesBuildPhase;
338 | buildActionMask = 2147483647;
339 | files = (
340 | );
341 | runOnlyForDeploymentPostprocessing = 0;
342 | };
343 | 3ABBC6EC1BE696DB00D563DF /* Resources */ = {
344 | isa = PBXResourcesBuildPhase;
345 | buildActionMask = 2147483647;
346 | files = (
347 | 3AC30B3D1C0CF3B9006DD8AE /* glm in Resources */,
348 | );
349 | runOnlyForDeploymentPostprocessing = 0;
350 | };
351 | /* End PBXResourcesBuildPhase section */
352 |
353 | /* Begin PBXSourcesBuildPhase section */
354 | 3ABBC6C41BE695DA00D563DF /* Sources */ = {
355 | isa = PBXSourcesBuildPhase;
356 | buildActionMask = 2147483647;
357 | files = (
358 | 3AC30B271C0BDAA4006DD8AE /* Trigonometric.swift in Sources */,
359 | 3AC30B1B1C0BDAA4006DD8AE /* Common.swift in Sources */,
360 | 3AC30B231C0BDAA4006DD8AE /* Matrix.swift in Sources */,
361 | 3AC30B211C0BDAA4006DD8AE /* Matrix_Transform.swift in Sources */,
362 | 3AC30B3F1C0CF618006DD8AE /* Quaternion.swift in Sources */,
363 | 3AC30B1F1C0BDAA4006DD8AE /* Geometric.swift in Sources */,
364 | 3AC30B1D1C0BDAA4006DD8AE /* Exponential.swift in Sources */,
365 | 3A0FA1AC1C1379E200BB7043 /* Vector.swift in Sources */,
366 | );
367 | runOnlyForDeploymentPostprocessing = 0;
368 | };
369 | 3ABBC6CE1BE695DA00D563DF /* Sources */ = {
370 | isa = PBXSourcesBuildPhase;
371 | buildActionMask = 2147483647;
372 | files = (
373 | 3AF9926A1C384A030061E157 /* glm-to-swift-quat.mm in Sources */,
374 | 3AC30B341C0BE048006DD8AE /* swift3DTests.swift in Sources */,
375 | 3AC30B381C0BE05E006DD8AE /* glm-to-swift.mm in Sources */,
376 | 3AF992631C381C560061E157 /* swift3DQuaterionTests.swift in Sources */,
377 | );
378 | runOnlyForDeploymentPostprocessing = 0;
379 | };
380 | 3ABBC6E01BE696DB00D563DF /* Sources */ = {
381 | isa = PBXSourcesBuildPhase;
382 | buildActionMask = 2147483647;
383 | files = (
384 | 3AC30B281C0BDAA4006DD8AE /* Trigonometric.swift in Sources */,
385 | 3AC30B1C1C0BDAA4006DD8AE /* Common.swift in Sources */,
386 | 3AC30B241C0BDAA4006DD8AE /* Matrix.swift in Sources */,
387 | 3AC30B221C0BDAA4006DD8AE /* Matrix_Transform.swift in Sources */,
388 | 3AC30B401C0CF618006DD8AE /* Quaternion.swift in Sources */,
389 | 3AC30B201C0BDAA4006DD8AE /* Geometric.swift in Sources */,
390 | 3AC30B1E1C0BDAA4006DD8AE /* Exponential.swift in Sources */,
391 | 3A0FA1AD1C1379E200BB7043 /* Vector.swift in Sources */,
392 | );
393 | runOnlyForDeploymentPostprocessing = 0;
394 | };
395 | 3ABBC6EA1BE696DB00D563DF /* Sources */ = {
396 | isa = PBXSourcesBuildPhase;
397 | buildActionMask = 2147483647;
398 | files = (
399 | 3AF9926B1C384A030061E157 /* glm-to-swift-quat.mm in Sources */,
400 | 3AC30B351C0BE048006DD8AE /* swift3DTests.swift in Sources */,
401 | 3AC30B391C0BE05E006DD8AE /* glm-to-swift.mm in Sources */,
402 | 3AF992641C381C560061E157 /* swift3DQuaterionTests.swift in Sources */,
403 | );
404 | runOnlyForDeploymentPostprocessing = 0;
405 | };
406 | /* End PBXSourcesBuildPhase section */
407 |
408 | /* Begin PBXTargetDependency section */
409 | 3ABBC6D51BE695DA00D563DF /* PBXTargetDependency */ = {
410 | isa = PBXTargetDependency;
411 | target = 3ABBC6C81BE695DA00D563DF /* swift3D-Mac */;
412 | targetProxy = 3ABBC6D41BE695DA00D563DF /* PBXContainerItemProxy */;
413 | };
414 | 3ABBC6F11BE696DB00D563DF /* PBXTargetDependency */ = {
415 | isa = PBXTargetDependency;
416 | target = 3ABBC6E41BE696DB00D563DF /* swift3D-iOS */;
417 | targetProxy = 3ABBC6F01BE696DB00D563DF /* PBXContainerItemProxy */;
418 | };
419 | /* End PBXTargetDependency section */
420 |
421 | /* Begin XCBuildConfiguration section */
422 | 3ABBC62F1BE68FF500D563DF /* Debug */ = {
423 | isa = XCBuildConfiguration;
424 | buildSettings = {
425 | ALWAYS_SEARCH_USER_PATHS = NO;
426 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
427 | CLANG_CXX_LIBRARY = "libc++";
428 | CLANG_ENABLE_MODULES = YES;
429 | CLANG_ENABLE_OBJC_ARC = YES;
430 | CLANG_WARN_BOOL_CONVERSION = YES;
431 | CLANG_WARN_CONSTANT_CONVERSION = YES;
432 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
433 | CLANG_WARN_EMPTY_BODY = YES;
434 | CLANG_WARN_ENUM_CONVERSION = YES;
435 | CLANG_WARN_INT_CONVERSION = YES;
436 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
437 | CLANG_WARN_UNREACHABLE_CODE = YES;
438 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
439 | CODE_SIGN_IDENTITY = "-";
440 | COPY_PHASE_STRIP = NO;
441 | CURRENT_PROJECT_VERSION = 0.2.1;
442 | DEBUG_INFORMATION_FORMAT = dwarf;
443 | ENABLE_STRICT_OBJC_MSGSEND = YES;
444 | ENABLE_TESTABILITY = YES;
445 | GCC_C_LANGUAGE_STANDARD = gnu99;
446 | GCC_DYNAMIC_NO_PIC = NO;
447 | GCC_NO_COMMON_BLOCKS = YES;
448 | GCC_OPTIMIZATION_LEVEL = 0;
449 | GCC_PREPROCESSOR_DEFINITIONS = (
450 | "DEBUG=1",
451 | "$(inherited)",
452 | );
453 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
454 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
455 | GCC_WARN_UNDECLARED_SELECTOR = YES;
456 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
457 | GCC_WARN_UNUSED_FUNCTION = YES;
458 | GCC_WARN_UNUSED_VARIABLE = YES;
459 | MACOSX_DEPLOYMENT_TARGET = 10.9;
460 | MTL_ENABLE_DEBUG_INFO = YES;
461 | ONLY_ACTIVE_ARCH = YES;
462 | SDKROOT = macosx;
463 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
464 | VERSIONING_SYSTEM = "apple-generic";
465 | VERSION_INFO_PREFIX = "";
466 | };
467 | name = Debug;
468 | };
469 | 3ABBC6301BE68FF500D563DF /* Release */ = {
470 | isa = XCBuildConfiguration;
471 | buildSettings = {
472 | ALWAYS_SEARCH_USER_PATHS = NO;
473 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
474 | CLANG_CXX_LIBRARY = "libc++";
475 | CLANG_ENABLE_MODULES = YES;
476 | CLANG_ENABLE_OBJC_ARC = YES;
477 | CLANG_WARN_BOOL_CONVERSION = YES;
478 | CLANG_WARN_CONSTANT_CONVERSION = YES;
479 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
480 | CLANG_WARN_EMPTY_BODY = YES;
481 | CLANG_WARN_ENUM_CONVERSION = YES;
482 | CLANG_WARN_INT_CONVERSION = YES;
483 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
484 | CLANG_WARN_UNREACHABLE_CODE = YES;
485 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
486 | CODE_SIGN_IDENTITY = "-";
487 | COPY_PHASE_STRIP = NO;
488 | CURRENT_PROJECT_VERSION = 0.2.1;
489 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
490 | ENABLE_NS_ASSERTIONS = NO;
491 | ENABLE_STRICT_OBJC_MSGSEND = YES;
492 | GCC_C_LANGUAGE_STANDARD = gnu99;
493 | GCC_NO_COMMON_BLOCKS = YES;
494 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
495 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
496 | GCC_WARN_UNDECLARED_SELECTOR = YES;
497 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
498 | GCC_WARN_UNUSED_FUNCTION = YES;
499 | GCC_WARN_UNUSED_VARIABLE = YES;
500 | MACOSX_DEPLOYMENT_TARGET = 10.9;
501 | MTL_ENABLE_DEBUG_INFO = NO;
502 | SDKROOT = macosx;
503 | VERSIONING_SYSTEM = "apple-generic";
504 | VERSION_INFO_PREFIX = "";
505 | };
506 | name = Release;
507 | };
508 | 3ABBC6DB1BE695DA00D563DF /* Debug */ = {
509 | isa = XCBuildConfiguration;
510 | buildSettings = {
511 | ALWAYS_SEARCH_USER_PATHS = NO;
512 | CLANG_ENABLE_MODULES = YES;
513 | COMBINE_HIDPI_IMAGES = YES;
514 | DEFINES_MODULE = YES;
515 | DYLIB_COMPATIBILITY_VERSION = 1;
516 | DYLIB_CURRENT_VERSION = 1;
517 | DYLIB_INSTALL_NAME_BASE = "@rpath";
518 | FRAMEWORK_VERSION = A;
519 | INFOPLIST_FILE = Source/Info.plist;
520 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
521 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
522 | MACOSX_DEPLOYMENT_TARGET = 10.11;
523 | PRODUCT_BUNDLE_IDENTIFIER = "Adrian-Krupa.swift3D";
524 | PRODUCT_NAME = swift3D;
525 | SKIP_INSTALL = YES;
526 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
527 | };
528 | name = Debug;
529 | };
530 | 3ABBC6DC1BE695DA00D563DF /* Release */ = {
531 | isa = XCBuildConfiguration;
532 | buildSettings = {
533 | ALWAYS_SEARCH_USER_PATHS = NO;
534 | CLANG_ENABLE_MODULES = YES;
535 | COMBINE_HIDPI_IMAGES = YES;
536 | DEFINES_MODULE = YES;
537 | DYLIB_COMPATIBILITY_VERSION = 1;
538 | DYLIB_CURRENT_VERSION = 1;
539 | DYLIB_INSTALL_NAME_BASE = "@rpath";
540 | FRAMEWORK_VERSION = A;
541 | INFOPLIST_FILE = Source/Info.plist;
542 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
543 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
544 | MACOSX_DEPLOYMENT_TARGET = 10.11;
545 | PRODUCT_BUNDLE_IDENTIFIER = "Adrian-Krupa.swift3D";
546 | PRODUCT_NAME = swift3D;
547 | SKIP_INSTALL = YES;
548 | SWIFT_OPTIMIZATION_LEVEL = "-O";
549 | };
550 | name = Release;
551 | };
552 | 3ABBC6DE1BE695DA00D563DF /* Debug */ = {
553 | isa = XCBuildConfiguration;
554 | buildSettings = {
555 | CLANG_ENABLE_MODULES = YES;
556 | COMBINE_HIDPI_IMAGES = YES;
557 | INFOPLIST_FILE = Tests/Info.plist;
558 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
559 | MACOSX_DEPLOYMENT_TARGET = 10.11;
560 | PRODUCT_BUNDLE_IDENTIFIER = "Adrian-Krupa.swift3DTests";
561 | PRODUCT_NAME = swift3DTests;
562 | SWIFT_OBJC_BRIDGING_HEADER = "Tests/swift3DTests-Bridging-Header.h";
563 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
564 | };
565 | name = Debug;
566 | };
567 | 3ABBC6DF1BE695DA00D563DF /* Release */ = {
568 | isa = XCBuildConfiguration;
569 | buildSettings = {
570 | CLANG_ENABLE_MODULES = YES;
571 | COMBINE_HIDPI_IMAGES = YES;
572 | INFOPLIST_FILE = Tests/Info.plist;
573 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
574 | MACOSX_DEPLOYMENT_TARGET = 10.11;
575 | PRODUCT_BUNDLE_IDENTIFIER = "Adrian-Krupa.swift3DTests";
576 | PRODUCT_NAME = swift3DTests;
577 | SWIFT_OBJC_BRIDGING_HEADER = "Tests/swift3DTests-Bridging-Header.h";
578 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
579 | };
580 | name = Release;
581 | };
582 | 3ABBC6F71BE696DB00D563DF /* Debug */ = {
583 | isa = XCBuildConfiguration;
584 | buildSettings = {
585 | CLANG_ENABLE_MODULES = YES;
586 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
587 | DEFINES_MODULE = YES;
588 | DYLIB_COMPATIBILITY_VERSION = 1;
589 | DYLIB_CURRENT_VERSION = 1;
590 | DYLIB_INSTALL_NAME_BASE = "@rpath";
591 | INFOPLIST_FILE = Source/Info.plist;
592 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
593 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
594 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
595 | PRODUCT_BUNDLE_IDENTIFIER = "Adrian-Krupa.swift3D";
596 | PRODUCT_NAME = swift3D;
597 | SDKROOT = iphoneos;
598 | SKIP_INSTALL = YES;
599 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
600 | TARGETED_DEVICE_FAMILY = "1,2";
601 | };
602 | name = Debug;
603 | };
604 | 3ABBC6F81BE696DB00D563DF /* Release */ = {
605 | isa = XCBuildConfiguration;
606 | buildSettings = {
607 | CLANG_ENABLE_MODULES = YES;
608 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
609 | DEFINES_MODULE = YES;
610 | DYLIB_COMPATIBILITY_VERSION = 1;
611 | DYLIB_CURRENT_VERSION = 1;
612 | DYLIB_INSTALL_NAME_BASE = "@rpath";
613 | INFOPLIST_FILE = Source/Info.plist;
614 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
615 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
616 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
617 | PRODUCT_BUNDLE_IDENTIFIER = "Adrian-Krupa.swift3D";
618 | PRODUCT_NAME = swift3D;
619 | SDKROOT = iphoneos;
620 | SKIP_INSTALL = YES;
621 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
622 | TARGETED_DEVICE_FAMILY = "1,2";
623 | VALIDATE_PRODUCT = YES;
624 | };
625 | name = Release;
626 | };
627 | 3ABBC6FA1BE696DB00D563DF /* Debug */ = {
628 | isa = XCBuildConfiguration;
629 | buildSettings = {
630 | CLANG_ENABLE_MODULES = YES;
631 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
632 | INFOPLIST_FILE = Tests/Info.plist;
633 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
634 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
635 | PRODUCT_BUNDLE_IDENTIFIER = "Adrian-Krupa.swift3DTests";
636 | PRODUCT_NAME = swift3DTests;
637 | SDKROOT = iphoneos;
638 | SWIFT_OBJC_BRIDGING_HEADER = "Tests/swift3DTests-Bridging-Header.h";
639 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
640 | };
641 | name = Debug;
642 | };
643 | 3ABBC6FB1BE696DB00D563DF /* Release */ = {
644 | isa = XCBuildConfiguration;
645 | buildSettings = {
646 | CLANG_ENABLE_MODULES = YES;
647 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
648 | INFOPLIST_FILE = Tests/Info.plist;
649 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
650 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
651 | PRODUCT_BUNDLE_IDENTIFIER = "Adrian-Krupa.swift3DTests";
652 | PRODUCT_NAME = swift3DTests;
653 | SDKROOT = iphoneos;
654 | SWIFT_OBJC_BRIDGING_HEADER = "Tests/swift3DTests-Bridging-Header.h";
655 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
656 | VALIDATE_PRODUCT = YES;
657 | };
658 | name = Release;
659 | };
660 | /* End XCBuildConfiguration section */
661 |
662 | /* Begin XCConfigurationList section */
663 | 3ABBC6171BE68FF500D563DF /* Build configuration list for PBXProject "swift3D" */ = {
664 | isa = XCConfigurationList;
665 | buildConfigurations = (
666 | 3ABBC62F1BE68FF500D563DF /* Debug */,
667 | 3ABBC6301BE68FF500D563DF /* Release */,
668 | );
669 | defaultConfigurationIsVisible = 0;
670 | defaultConfigurationName = Release;
671 | };
672 | 3ABBC6DA1BE695DA00D563DF /* Build configuration list for PBXNativeTarget "swift3D-Mac" */ = {
673 | isa = XCConfigurationList;
674 | buildConfigurations = (
675 | 3ABBC6DB1BE695DA00D563DF /* Debug */,
676 | 3ABBC6DC1BE695DA00D563DF /* Release */,
677 | );
678 | defaultConfigurationIsVisible = 0;
679 | defaultConfigurationName = Release;
680 | };
681 | 3ABBC6DD1BE695DA00D563DF /* Build configuration list for PBXNativeTarget "swift3DTests-Mac" */ = {
682 | isa = XCConfigurationList;
683 | buildConfigurations = (
684 | 3ABBC6DE1BE695DA00D563DF /* Debug */,
685 | 3ABBC6DF1BE695DA00D563DF /* Release */,
686 | );
687 | defaultConfigurationIsVisible = 0;
688 | defaultConfigurationName = Release;
689 | };
690 | 3ABBC6F61BE696DB00D563DF /* Build configuration list for PBXNativeTarget "swift3D-iOS" */ = {
691 | isa = XCConfigurationList;
692 | buildConfigurations = (
693 | 3ABBC6F71BE696DB00D563DF /* Debug */,
694 | 3ABBC6F81BE696DB00D563DF /* Release */,
695 | );
696 | defaultConfigurationIsVisible = 0;
697 | defaultConfigurationName = Release;
698 | };
699 | 3ABBC6F91BE696DB00D563DF /* Build configuration list for PBXNativeTarget "swift3DTests-iOS" */ = {
700 | isa = XCConfigurationList;
701 | buildConfigurations = (
702 | 3ABBC6FA1BE696DB00D563DF /* Debug */,
703 | 3ABBC6FB1BE696DB00D563DF /* Release */,
704 | );
705 | defaultConfigurationIsVisible = 0;
706 | defaultConfigurationName = Release;
707 | };
708 | /* End XCConfigurationList section */
709 | };
710 | rootObject = 3ABBC6141BE68FF500D563DF /* Project object */;
711 | }
712 |
--------------------------------------------------------------------------------