├── .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 | [![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://raw.githubusercontent.com/adriankrupa/Swift3D/master/LICENSE) 3 | ![CocoaPods](https://img.shields.io/cocoapods/v/Swift3D.svg) 4 | [![GitHub release](https://img.shields.io/github/release/adriankrupa/Swift3D.svg)](https://github.com/adriankrupa/Swift3D/releases) 5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | [![Build Status](https://travis-ci.org/adriankrupa/swift3D.svg?branch=master)](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 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/adriankrupa/swift3d/trend.png)](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 | --------------------------------------------------------------------------------