Compare commits

...

24 Commits

Author SHA1 Message Date
Volodymyr Boichentsov 3a043b41c6
Update Package.swift 2019-12-27 23:14:25 +00:00
Volodymyr Boichentsov 8512600e7d
Merge pull request #8 from 3D4Medical/feature/version-2
Feature/version 2
2019-12-27 22:55:04 +00:00
Volodymyr Boichentsov a8916f6e60
Create swift.yml 2019-12-27 22:52:57 +00:00
Volodymyr Boichentsov 0bef3b8633
Merge pull request #7 from sakrist/feature/version-2
Fixes in version 2
2019-12-27 22:49:56 +00:00
Volodymyr Boichentsov 46fd54f726 update package file 2019-12-27 22:42:11 +00:00
Volodymyr Boichentsov 31dea75e7c extended simple test 2019-12-27 22:14:11 +00:00
Volodymyr Boichentsov 8c02951c65 add "available(OSX 10.12, iOS 10.0, *)" 2019-12-27 10:46:38 +00:00
Volodymyr Boichentsov 9a4685ba98 check on define DRACO for draco 2019-12-27 10:35:41 +00:00
Volodymyr Boichentsov 8e65bf0f64 remove draco include 2019-12-27 10:26:28 +00:00
Volodymyr Boichentsov 8c0d86d542 fix simple tests 2019-12-27 10:04:59 +00:00
Volodymyr Boichentsov 956583145d exclude draco from linkage 2019-12-03 23:31:19 +00:00
Volodymyr Boichentsov bcb7294eb1 Draco as macros 2019-12-03 22:31:03 +00:00
Sergey Novikov 19c3089f7e lint fixes 2019-12-03 11:41:39 +00:00
Sergey Novikov f6c9d76e03 error saving for callback 2019-12-02 14:31:38 +00:00
Sergey Novikov af4c4926c5 fix for recursion 2019-11-28 11:34:54 +00:00
Sergey Novikov 463a27bc55 checking existing node in scene of no 2019-11-27 09:29:32 +00:00
Sergey Novikov 6b5faed6f6 optional scene in delegate methods 2019-11-14 17:44:13 +00:00
Sergey Novikov e69d2f12ff public api for scn method 2019-11-13 17:03:53 +00:00
Sergey Novikov 9e0a0a4dcb public methods for ver 2 cache 2019-11-12 15:52:34 +00:00
Sergey Novikov 0aed670c0c remove callback for textures, root node for converter, white colour for empty material 2019-11-08 13:16:39 +00:00
Sergey Novikov aacc3a5ad0 remove async version 2019-11-06 13:53:26 +00:00
Sergey Novikov f9575a721c async loading. failed 2019-11-06 10:50:38 +00:00
Sergey Novikov e49ed1f3b9 stash for new version. 2019-11-05 17:15:55 +00:00
Sergey Novikov ed9d49fc09 extend required extensions 2019-10-24 17:34:57 +01:00
52 changed files with 1193 additions and 1237 deletions

15
.github/workflows/swift.yml vendored Normal file
View File

@ -0,0 +1,15 @@
name: Swift
on: [push]
jobs:
build:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- name: Build
run: swift build -v
- name: Run tests
run: swift test -v

4
.gitignore vendored
View File

@ -1,6 +1,4 @@
.DS_Store
/.build
/Packages
gltf_scenekit.xcodeproj/project.xcworkspace/xcuserdata
gltf_scenekit.xcodeproj/xcuserdata
glTFSceneKit.xcodeproj/xcuserdata
**/xcuserdata

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "Draco"]
path = Draco
url = https://github.com/3d4medical/DracoSwiftPackage.git

1
Draco

@ -1 +0,0 @@
Subproject commit 10caef92253b10439b3bc560ecef4a79804f612a

View File

@ -1,16 +0,0 @@
{
"object": {
"pins": [
{
"package": "Draco",
"repositoryURL": "https://github.com/3d4medical/DracoSwiftPackage.git",
"state": {
"branch": null,
"revision": "0dac933ae63d023d2ba87decb2a5485beac7f548",
"version": "0.0.9"
}
}
]
},
"version": 1
}

View File

@ -1,19 +1,18 @@
// swift-tools-version:4.0
// swift-tools-version:5.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "glTFSceneKit",
platforms: [
.macOS(.v10_12), .iOS(.v10),
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "glTFSceneKit",
targets: ["glTFSceneKit"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/3d4medical/DracoSwiftPackage.git", from: "0.0.9"),
targets: ["glTFSceneKit"])
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@ -23,10 +22,8 @@ let package = Package(
dependencies: []),
.testTarget(
name: "glTFSceneKitTests",
dependencies: ["glTFSceneKit"]),
dependencies: ["glTFSceneKit"])
]
)
// swift build -Xswiftc "-target" -Xswiftc "x86_64-apple-macosx10.12"
// swift build -Xswiftc "-target" -Xswiftc "x86_64-apple-macosx10.13"

View File

@ -32,13 +32,9 @@
#### Extensions
- [X] KHR_draco_mesh_compression - Draco (supported draft version, need to fix when indices is short)
- [ ] KHR_draco_mesh_compression - Draco (supported draft version, need rework. temporary disabled)
- [X] 3D4M_compressed_texture - [Draft of unofficial extension.](https://github.com/sakrist/glTF/tree/extensions/compressed_texture/extensions/2.0/Vendor/3D4M_compressed_texture)
## Dependecies
- [DracoSwiftPackage](https://github.com/3D4Medical/DracoSwiftPackage) - custom Draco package for decode
Example:
```swift
@ -47,5 +43,12 @@ import glTFSceneKit
let directory = "..." // path to folder where is gltf file located
let decoder = JSONDecoder()
let glTF = try? decoder.decode(GLTF.self, from: jsonData)
let scene = glTF?.convert(view:sceneView, directoryPath:directory)
if let converter = GLTFConverter(glTF: glTF) {
let scene = converter.convert(to: view.scene!, geometryCompletionHandler: {
// Geometries are loaded and textures are may still in loading process.
}) { (error) in
// Fully converted to SceneKit
// TODO: handle error.
}
}
```

View File

@ -8,6 +8,7 @@
import Foundation
import SceneKit
@available(OSX 10.12, iOS 10.0, *)
extension GLTFConverter {
func parseAnimations() throws {
@ -30,93 +31,93 @@ extension GLTFConverter {
func constructAnimation(sampler: GLTFAnimationSampler, target: GLTFAnimationChannelTarget ) throws {
let targetIndex = target.node!
guard let node:SCNNode = self.cache_nodes?[targetIndex] else {
throw GLTFError("constructAnimation: Can't find target node with \(targetIndex), sampler:\(sampler) target:\(target)")
}
guard let accessorInput = glTF.accessors?[sampler.input] else {
throw GLTFError("Input accessor could not be found for sampler.input \(sampler.input)")
}
guard let accessorOutput = glTF.accessors?[sampler.output] else {
throw GLTFError("Output accessor could not be found for sampler.output \(sampler.output)")
}
var keyTimesFloat = [Float]()
if let (bufferView, interleaved) = try determineAcessor(accessorInput),
let data = try loadAcessor(accessorInput, bufferView, interleaved) {
keyTimesFloat = dataAsArray(data, accessorInput.componentType, accessorInput.type) as! [Float]
}
let duration = Double(keyTimesFloat.last!)
let f_duration = Float(duration)
let keyTimes: [NSNumber] = keyTimesFloat.map { NSNumber(value: $0 / f_duration ) }
var values_ = [Any]()
if let (bufferView, interleaved) = try determineAcessor(accessorOutput),
let data = try loadAcessor(accessorInput, bufferView, interleaved) {
values_ = dataAsArray(data, accessorOutput.componentType, accessorOutput.type)
}
var groupDuration:Double = 0
var caanimations:[CAAnimation] = [CAAnimation]()
if target.path == .weights {
let weightPaths = node.value(forUndefinedKey: "weightPaths") as? [String]
groupDuration = duration
var keyAnimations = [CAKeyframeAnimation]()
for path in weightPaths! {
let animation = CAKeyframeAnimation()
animation.keyPath = path
animation.keyTimes = keyTimes
animation.duration = duration
keyAnimations.append(animation)
}
let step = keyAnimations.count
let dataLength = values_.count / step
guard dataLength == keyTimes.count else {
throw GLTFError("data count mismatch: \(dataLength) != \(keyTimes.count)")
}
for i in 0..<keyAnimations.count {
var valueIndex = i
var v = [NSNumber]()
v.reserveCapacity(dataLength)
for _ in 0..<dataLength {
v.append(NSNumber(value: (values_[valueIndex] as! Float) ))
valueIndex += step
}
keyAnimations[i].values = v
}
caanimations = keyAnimations
} else {
let keyFrameAnimation = CAKeyframeAnimation()
self.animationDuration = max(self.animationDuration, duration)
keyFrameAnimation.keyPath = target.path.scn()
keyFrameAnimation.keyTimes = keyTimes
keyFrameAnimation.values = values_
keyFrameAnimation.repeatCount = .infinity
keyFrameAnimation.duration = duration
caanimations.append(keyFrameAnimation)
groupDuration = self.animationDuration
}
let group = (node.value(forUndefinedKey: "group") as? CAAnimationGroup) ?? CAAnimationGroup()
node.setValue(group, forUndefinedKey: "group")
var animations = group.animations ?? []
animations.append(contentsOf: caanimations)
group.animations = animations
group.duration = groupDuration
group.repeatCount = .infinity
node.addAnimation(group, forKey: target.path.rawValue)
// let targetIndex = target.node!
// guard let node:SCNNode = self.cache_nodes?[targetIndex] else {
// throw GLTFError("constructAnimation: Can't find target node with \(targetIndex), sampler:\(sampler) target:\(target)")
// }
//
// guard let accessorInput = glTF.accessors?[sampler.input] else {
// throw GLTFError("Input accessor could not be found for sampler.input \(sampler.input)")
// }
// guard let accessorOutput = glTF.accessors?[sampler.output] else {
// throw GLTFError("Output accessor could not be found for sampler.output \(sampler.output)")
// }
//
// var keyTimesFloat = [Float]()
// if let (bufferView, interleaved) = try determineAcessor(accessorInput),
// let data = try loadAcessor(accessorInput, bufferView, interleaved) {
// keyTimesFloat = dataAsArray(data, accessorInput.componentType, accessorInput.type) as! [Float]
// }
// let duration = Double(keyTimesFloat.last!)
// let f_duration = Float(duration)
// let keyTimes: [NSNumber] = keyTimesFloat.map { NSNumber(value: $0 / f_duration ) }
//
// var values_ = [Any]()
// if let (bufferView, interleaved) = try determineAcessor(accessorOutput),
// let data = try loadAcessor(accessorInput, bufferView, interleaved) {
// values_ = dataAsArray(data, accessorOutput.componentType, accessorOutput.type)
// }
//
// var groupDuration:Double = 0
//
// var caanimations:[CAAnimation] = [CAAnimation]()
// if target.path == .weights {
// let weightPaths = node.value(forUndefinedKey: "weightPaths") as? [String]
//
// groupDuration = duration
//
// var keyAnimations = [CAKeyframeAnimation]()
// for path in weightPaths! {
// let animation = CAKeyframeAnimation()
// animation.keyPath = path
// animation.keyTimes = keyTimes
// animation.duration = duration
// keyAnimations.append(animation)
// }
//
// let step = keyAnimations.count
// let dataLength = values_.count / step
// guard dataLength == keyTimes.count else {
// throw GLTFError("data count mismatch: \(dataLength) != \(keyTimes.count)")
// }
//
// for i in 0..<keyAnimations.count {
// var valueIndex = i
// var v = [NSNumber]()
// v.reserveCapacity(dataLength)
// for _ in 0..<dataLength {
// v.append(NSNumber(value: (values_[valueIndex] as! Float) ))
// valueIndex += step
// }
// keyAnimations[i].values = v
// }
//
// caanimations = keyAnimations
//
// } else {
// let keyFrameAnimation = CAKeyframeAnimation()
//
// self.animationDuration = max(self.animationDuration, duration)
//
// keyFrameAnimation.keyPath = target.path.scn()
// keyFrameAnimation.keyTimes = keyTimes
// keyFrameAnimation.values = values_
// keyFrameAnimation.repeatCount = .infinity
// keyFrameAnimation.duration = duration
//
// caanimations.append(keyFrameAnimation)
//
// groupDuration = self.animationDuration
// }
//
// let group = (node.value(forUndefinedKey: "group") as? CAAnimationGroup) ?? CAAnimationGroup()
// node.setValue(group, forUndefinedKey: "group")
// var animations = group.animations ?? []
// animations.append(contentsOf: caanimations)
// group.animations = animations
// group.duration = groupDuration
// group.repeatCount = .infinity
// node.addAnimation(group, forKey: target.path.rawValue)
}
func loadSkin(_ skin: Int, _ scnNode: SCNNode) {
@ -128,40 +129,40 @@ extension GLTFConverter {
switch componentType {
case .BYTE:
values = data.array() as [Int8]
break
case .UNSIGNED_BYTE:
values = data.array() as [UInt8]
break
case .SHORT:
values = data.array() as [Int16]
break
case .UNSIGNED_SHORT:
values = data.array() as [UInt16]
break
case .UNSIGNED_INT:
values = data.array() as [UInt32]
break
case .FLOAT:
do {
switch type {
case .SCALAR:
values = data.array() as [Float]
break
case .VEC2:
values = data.array() as [SCNVector2]
break
case .VEC3:
values = data.array() as [GLKVector3]
for i in 0..<values.count {
values[i] = SCNVector3FromGLKVector3(values[i] as! GLKVector3)
}
break
case .VEC4:
values = data.array() as [GLKVector4]
for i in 0..<values.count {
values[i] = SCNVector4FromGLKVector4(values[i] as! GLKVector4)
}
break
case .MAT2:
break
case .MAT3:
@ -171,17 +172,16 @@ extension GLTFConverter {
for i in 0..<values.count {
values[i] = SCNMatrix4FromGLKMatrix4(values[i] as! GLKMatrix4)
}
break
}
}
break
}
return values
}
}
extension GLTFAnimationChannelTargetPath {
fileprivate func scn() -> String {
switch self {
@ -196,5 +196,3 @@ extension GLTFAnimationChannelTargetPath {
}
}
}

View File

@ -13,6 +13,8 @@ enum CTLevel:Int {
case last
case all
}
@available(OSX 10.12, iOS 10.0, *)
extension GLTF {
func loadCompressedTexture(descriptor: GLTF_3D4MCompressedTextureExtension, loadLevel: CTLevel, completionHandler: @escaping (Any?, Error?) -> Void ) {
@ -20,14 +22,14 @@ extension GLTF {
let width = descriptor.width
let height = descriptor.height
if (width == 0 || height == 0) {
if width == 0 || height == 0 {
completionHandler(nil, GLTFError("GLTF_3D4MCompressedTextureExtension: Failed to load texture, inappropriate texture size."))
return
}
let (bytesPerRow, pixelFormat) = _get_bpp_pixelFormat(descriptor.compression)
if (pixelFormat == .invalid ) {
if pixelFormat == .invalid {
completionHandler(nil, GLTFError("GLTF_3D4MCompressedTextureExtension: Failed to load texture, unsupported compression format \(descriptor.compression)."))
return
}
@ -58,7 +60,7 @@ extension GLTF {
error_ = error
}
} else {
print(error)
error_ = error
}
completionHandler(textureResult, error_)
}
@ -76,7 +78,12 @@ extension GLTF {
if buffer.data != nil {
datas.append(buffer.data!)
do {
if !buffer_.uri!.contains("lacrimal")
&& !buffer_.uri!.contains("Bursa") {
textureResult = try self._createMetalTexture(sizeWidth, sizeHeight, pixelFormat, datas, bytesPerRow)
} else {
}
} catch {
error_ = error
}
@ -125,8 +132,8 @@ extension GLTF {
}
}
width = max(width >> 1, 1);
height = max(height >> 1, 1);
width = max(width >> 1, 1)
height = max(height >> 1, 1)
}
return texture
@ -155,202 +162,198 @@ extension GLTF {
return image
}
fileprivate func _get_bpp_pixelFormat(_ compression: GLTF_3D4MCompressedTextureExtensionCompression) -> ((Int, Int) -> Int, MTLPixelFormat) {
var bytesPerRow: (Int, Int) -> Int = {_, _ in return 0 }
var pixelFormat:MTLPixelFormat = .invalid;
var pixelFormat: MTLPixelFormat = .invalid
#if os(macOS)
if (compression == .COMPRESSED_RGBA_S3TC_DXT1) {
if compression == .COMPRESSED_RGBA_S3TC_DXT1 {
pixelFormat = .bc1_rgba
bytesPerRow = {width, height in return ((width + 3) / 4) * 8 };
} else if (compression == .COMPRESSED_SRGB_ALPHA_S3TC_DXT1) {
bytesPerRow = {width, height in return ((width + 3) / 4) * 8 }
} else if compression == .COMPRESSED_SRGB_ALPHA_S3TC_DXT1 {
pixelFormat = .bc1_rgba_srgb
bytesPerRow = {width, height in return ((width + 3) / 4) * 8 };
} else if (compression == .COMPRESSED_RGBA_S3TC_DXT3) {
bytesPerRow = {width, height in return ((width + 3) / 4) * 8 }
} else if compression == .COMPRESSED_RGBA_S3TC_DXT3 {
pixelFormat = .bc2_rgba
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 };
} else if (compression == .COMPRESSED_SRGB_ALPHA_S3TC_DXT3) {
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 }
} else if compression == .COMPRESSED_SRGB_ALPHA_S3TC_DXT3 {
pixelFormat = .bc2_rgba_srgb
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 };
} else if (compression == .COMPRESSED_RGBA_S3TC_DXT5) {
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 }
} else if compression == .COMPRESSED_RGBA_S3TC_DXT5 {
pixelFormat = .bc3_rgba
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 };
} else if (compression == .COMPRESSED_SRGB_ALPHA_S3TC_DXT5) {
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 }
} else if compression == .COMPRESSED_SRGB_ALPHA_S3TC_DXT5 {
pixelFormat = .bc3_rgba_srgb
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 };
} else if (compression == .COMPRESSED_RGBA_BPTC_UNORM) {
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 }
} else if compression == .COMPRESSED_RGBA_BPTC_UNORM {
pixelFormat = .bc7_rgbaUnorm
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 };
} else if (compression == .COMPRESSED_SRGB_ALPHA_BPTC_UNORM) {
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 }
} else if compression == .COMPRESSED_SRGB_ALPHA_BPTC_UNORM {
pixelFormat = .bc7_rgbaUnorm_srgb
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 };
bytesPerRow = {width, height in return ((width + 3) / 4) * 16 }
}
#elseif os(iOS) || os(tvOS)
switch compression {
case .ETC1_RGB8_OES:
assert(false, " \(compression) not supported yet")
break
case .COMPRESSED_RGB8_ETC2:
assert(false, " \(compression) not supported yet")
break
case .COMPRESSED_SRGB8_ETC2:
assert(false, " \(compression) not supported yet")
break
case .COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
assert(false, " \(compression) not supported yet")
break
case .COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
assert(false, " \(compression) not supported yet")
break
case .COMPRESSED_RGBA8_ETC2_EAC:
assert(false, " \(compression) not supported yet")
break
case .COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
assert(false, " \(compression) not supported yet")
break
case .COMPRESSED_SRGB_PVRTC_2BPPV1:
pixelFormat = .pvrtc_rgb_2bpp_srgb
break
case .COMPRESSED_SRGB_PVRTC_4BPPV1:
pixelFormat = .pvrtc_rgb_4bpp_srgb
break
case .COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1:
pixelFormat = .pvrtc_rgba_2bpp_srgb
break
case .COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1:
pixelFormat = .pvrtc_rgba_4bpp_srgb
break
case .COMPRESSED_RGB_PVRTC_4BPPV1:
pixelFormat = .pvrtc_rgb_4bpp
break
case .COMPRESSED_RGB_PVRTC_2BPPV1:
pixelFormat = .pvrtc_rgb_2bpp
break
case .COMPRESSED_RGBA_PVRTC_4BPPV1:
pixelFormat = .pvrtc_rgba_4bpp
break
case .COMPRESSED_RGBA_PVRTC_2BPPV1:
pixelFormat = .pvrtc_rgba_2bpp
break
case .COMPRESSED_RGBA_ASTC_4x4:
pixelFormat = .astc_4x4_ldr
bytesPerRow = {width, height in return (width + 4 - 1) / 4 * 16 };
break
bytesPerRow = {width, height in return (width + 4 - 1) / 4 * 16 }
case .COMPRESSED_RGBA_ASTC_5x4:
pixelFormat = .astc_5x4_ldr
bytesPerRow = {width, height in return (width + 5 - 1) / 5 * 16 };
break
bytesPerRow = {width, height in return (width + 5 - 1) / 5 * 16 }
case .COMPRESSED_RGBA_ASTC_5x5:
pixelFormat = .astc_5x5_ldr
bytesPerRow = {width, height in return (width + 5 - 1) / 5 * 16 };
break
bytesPerRow = {width, height in return (width + 5 - 1) / 5 * 16 }
case .COMPRESSED_RGBA_ASTC_6x5:
pixelFormat = .astc_6x5_ldr
bytesPerRow = {width, height in return (width + 6 - 1) / 6 * 16 };
break
bytesPerRow = {width, height in return (width + 6 - 1) / 6 * 16 }
case .COMPRESSED_RGBA_ASTC_6x6:
pixelFormat = .astc_6x6_ldr
bytesPerRow = {width, height in return (width + 6 - 1) / 6 * 16 };
break
bytesPerRow = {width, height in return (width + 6 - 1) / 6 * 16 }
case .COMPRESSED_RGBA_ASTC_8x5:
pixelFormat = .astc_8x5_ldr
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 };
break
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 }
case .COMPRESSED_RGBA_ASTC_8x6:
pixelFormat = .astc_8x6_ldr
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 };
break
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 }
case .COMPRESSED_RGBA_ASTC_8x8:
pixelFormat = .astc_8x8_ldr
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 };
break
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 }
case .COMPRESSED_RGBA_ASTC_10x5:
pixelFormat = .astc_10x5_ldr
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 };
break
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 }
case .COMPRESSED_RGBA_ASTC_10x6:
pixelFormat = .astc_10x6_ldr
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 };
break
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 }
case .COMPRESSED_RGBA_ASTC_10x8:
pixelFormat = .astc_10x8_ldr
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 };
break
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 }
case .COMPRESSED_RGBA_ASTC_10x10:
pixelFormat = .astc_10x10_ldr
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 };
break
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 }
case .COMPRESSED_RGBA_ASTC_12x10:
pixelFormat = .astc_12x10_ldr
bytesPerRow = {width, height in return (width + 12 - 1) / 12 * 16 };
break
bytesPerRow = {width, height in return (width + 12 - 1) / 12 * 16 }
case .COMPRESSED_RGBA_ASTC_12x12:
pixelFormat = .astc_12x12_ldr
bytesPerRow = {width, height in return (width + 12 - 1) / 12 * 16 };
break
bytesPerRow = {width, height in return (width + 12 - 1) / 12 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_4x4:
pixelFormat = .astc_4x4_srgb
bytesPerRow = {width, height in return (width + 4 - 1) / 4 * 16 };
break
bytesPerRow = {width, height in return (width + 4 - 1) / 4 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_5x4:
pixelFormat = .astc_5x4_srgb
bytesPerRow = {width, height in return (width + 5 - 1) / 5 * 16 };
break
bytesPerRow = {width, height in return (width + 5 - 1) / 5 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_5x5:
pixelFormat = .astc_5x5_srgb
bytesPerRow = {width, height in return (width + 5 - 1) / 5 * 16 };
break
bytesPerRow = {width, height in return (width + 5 - 1) / 5 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_6x5:
pixelFormat = .astc_6x5_srgb
bytesPerRow = {width, height in return (width + 6 - 1) / 6 * 16 };
break
bytesPerRow = {width, height in return (width + 6 - 1) / 6 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_6x6:
pixelFormat = .astc_6x6_srgb
bytesPerRow = {width, height in return (width + 6 - 1) / 6 * 16 };
break
bytesPerRow = {width, height in return (width + 6 - 1) / 6 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_8x5:
pixelFormat = .astc_8x5_srgb
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 };
break
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_8x6:
pixelFormat = .astc_8x6_srgb
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 };
break
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_8x8:
pixelFormat = .astc_8x8_srgb
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 };
break
bytesPerRow = {width, height in return (width + 8 - 1) / 8 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_10x5:
pixelFormat = .astc_10x5_srgb
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 };
break
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_10x6:
pixelFormat = .astc_10x6_srgb
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 };
break
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_10x8:
pixelFormat = .astc_10x8_srgb
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 };
break
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_10x10:
pixelFormat = .astc_10x10_srgb
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 };
break
bytesPerRow = {width, height in return (width + 10 - 1) / 10 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_12x10:
pixelFormat = .astc_12x10_srgb
bytesPerRow = {width, height in return (width + 12 - 1) / 12 * 16 };
break
bytesPerRow = {width, height in return (width + 12 - 1) / 12 * 16 }
case .COMPRESSED_SRGB8_ALPHA8_ASTC_12x12:
pixelFormat = .astc_12x12_srgb
bytesPerRow = {width, height in return (width + 12 - 1) / 12 * 16 };
break
bytesPerRow = {width, height in return (width + 12 - 1) / 12 * 16 }
default:
assert(false, " \(compression) can't bbe supported on iOS")
break
}
#endif

View File

@ -9,7 +9,7 @@ import Foundation
import SceneKit
// https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md
#if DRACO
extension GLTF {
func convertDracoMesh(_ dracoMesh: GLTFKHRDracoMeshCompressionExtension, triangleStrip: Bool = true) throws -> (SCNGeometryElement?, [SCNGeometrySource]?) {
@ -24,7 +24,7 @@ extension GLTF {
let (indicesData, verticies, stride) = uncompressDracoData(data, triangleStrip: triangleStrip)
let indexSize = MemoryLayout<UInt32>.size;
let indexSize = MemoryLayout<UInt32>.size
let primitiveCount = (triangleStrip) ? ((indicesData.count / indexSize) - 2) : (indicesData.count / (indexSize * 3))
@ -33,7 +33,6 @@ extension GLTF {
primitiveCount: primitiveCount,
bytesPerIndex: indexSize)
let byteStride = (bufferView.byteStride != nil) ? bufferView.byteStride! : (stride * 4)
let count = verticies.count / byteStride
var byteOffset = 0
@ -104,3 +103,4 @@ extension GLTF {
return (nil, nil)
}
}
#endif

View File

@ -8,7 +8,7 @@
import Foundation
import SceneKit
@available(OSX 10.12, iOS 10.0, *)
extension GLTF {
// MARK: - Material
@ -27,7 +27,7 @@ extension GLTF {
scnMaterial.lightingModel = .physicallyBased
if let baseTextureInfo = pbr.baseColorTexture {
TextureStorageManager.loadTexture(gltf:self, delegate: delegate, index:baseTextureInfo.index, property: scnMaterial.diffuse, callback: textureChangedCallback)
TextureStorageManager.loadTexture(gltf: self, delegate: delegate, index: baseTextureInfo.index, property: scnMaterial.diffuse)
} else {
let color = (pbr.baseColorFactor.count < 4) ? [1, 1, 1, 1] : (pbr.baseColorFactor)
scnMaterial.diffuse.contents = OSColor(red: CGFloat(color[0]), green: CGFloat(color[1]), blue: CGFloat(color[2]), alpha: CGFloat(color[3]))
@ -109,7 +109,6 @@ extension GLTF {
}
}
extension GLTFSampler {
fileprivate func magFilterScene() -> SCNFilterMode {
if self.magFilter != nil {
@ -181,4 +180,3 @@ extension GLTFSamplerWrapT {
}
}
}

View File

@ -10,12 +10,17 @@ import Foundation
import SceneKit
import os
@available(OSX 10.12, iOS 10.0, *)
let log_scenekit = OSLog(subsystem: "org.glTFSceneKit", category: "scene")
let dracoExtensionKey = "KHR_draco_mesh_compression"
let compressedTextureExtensionKey = "3D4M_compressed_texture"
let supportedExtensions = [dracoExtensionKey, compressedTextureExtensionKey]
let meshExtensionKey = "3D4M_mesh"
#if DRACO
let dracoExtensionKey = "KHR_draco_mesh_compression"
let supportedExtensions = [dracoExtensionKey, compressedTextureExtensionKey, meshExtensionKey]
#else
let supportedExtensions = [compressedTextureExtensionKey, meshExtensionKey]
#endif
struct ConvertionProgressMask: OptionSet {
let rawValue: Int
@ -29,14 +34,14 @@ struct ConvertionProgressMask : OptionSet {
}
}
@objc public protocol SceneLoadingDelegate {
@objc optional func scene(_ didLoadScene: SCNScene )
@objc optional func scene(_ scene: SCNScene, didCreate camera: SCNCamera)
@objc optional func scene(_ scene: SCNScene, didCreate node: SCNNode)
@objc optional func scene(_ scene: SCNScene, didCreate material: SCNMaterial, for node: SCNNode)
@objc optional func scene(_ didLoadScene: SCNScene? )
@objc optional func scene(_ scene: SCNScene?, didCreate camera: SCNCamera)
@objc optional func scene(_ scene: SCNScene?, didCreate node: SCNNode)
@objc optional func scene(_ scene: SCNScene?, didCreate material: SCNMaterial, for node: SCNNode)
}
@available(OSX 10.12, iOS 10.0, *)
extension GLTF {
struct Keys {

View File

@ -9,7 +9,6 @@
import Foundation
/// The root object for a glTF asset.
@objcMembers
open class GLTF: NSObject, Codable {

View File

@ -64,6 +64,25 @@ import Foundation
case MAT3
case MAT4
public var rawIntValue: Int {
switch self {
case .SCALAR:
return 0
case .VEC2:
return 1
case .VEC3:
return 2
case .VEC4:
return 3
case .MAT2:
return 4
case .MAT3:
return 5
case .MAT4:
return 6
}
}
public var rawValue: String {
switch self {
case .SCALAR:
@ -106,7 +125,6 @@ import Foundation
}
/// A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's `vertexAttribPointer()` defines an attribute in a buffer.
@objcMembers
open class GLTFAccessor: NSObject, Codable {
@ -138,7 +156,7 @@ open class GLTFAccessor : NSObject, Codable {
public var name: String?
/// Specifies whether integer data values should be normalized.
public var normalized:Bool
public var normalized: Bool = false
/// Sparse storage of attributes that deviate from their initialization value.
public var sparse: GLTFAccessorSparse?
@ -161,6 +179,18 @@ open class GLTFAccessor : NSObject, Codable {
case type
}
public init (bufferView: Int?,
byteOffset: Int,
componentType: GLTFAccessorComponentType,
count: Int,
type: GLTFAccessorType) {
self.bufferView = bufferView
self.byteOffset = byteOffset
self.componentType = componentType
self.count = count
self.type = type
}
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
bufferView = try? container.decode(Int.self, forKey: .bufferView)

View File

@ -9,7 +9,6 @@
import Foundation
/// Sparse storage of attributes that deviate from their initialization value.
@objcMembers
open class GLTFAccessorSparse: NSObject, Codable {

View File

@ -40,7 +40,6 @@ import Foundation
}
/// Indices of those attributes that deviate from their initialization value.
@objcMembers
open class GLTFAccessorSparseIndices: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// Array of size `accessor.sparse.count` times number of components storing the displaced accessor attributes pointed by `accessor.sparse.indices`.
@objcMembers
open class GLTFAccessorSparseValues: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// A keyframe animation.
@objcMembers
open class GLTFAnimation: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// Targets an animation's sampler at a node's property.
@objcMembers
open class GLTFAnimationChannel: NSObject, Codable {

View File

@ -45,7 +45,6 @@ import Foundation
}
/// The index of the node and TRS property that an animation channel targets.
@objcMembers
open class GLTFAnimationChannelTarget: NSObject, Codable {

View File

@ -43,7 +43,6 @@ import Foundation
}
}
/// Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target).
@objcMembers
open class GLTFAnimationSampler: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// Metadata about the glTF asset.
@objcMembers
open class GLTFAsset: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// A buffer points to binary geometry, animation, or skins.
@objcMembers
open class GLTFBuffer: NSObject, Codable {

View File

@ -35,7 +35,6 @@ import Foundation
}
/// A view into a buffer generally representing a subset of the buffer.
@objcMembers
open class GLTFBufferView: NSObject, Codable {

View File

@ -35,7 +35,6 @@ import Foundation
}
/// A camera's projection. A node can reference a camera to apply a transform to place the camera in the scene.
@objcMembers
open class GLTFCamera: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// An orthographic camera containing properties to create an orthographic projection matrix.
@objcMembers
open class GLTFCameraOrthographic: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// A perspective camera containing properties to create a perspective projection matrix.
@objcMembers
open class GLTFCameraPerspective: NSObject, Codable {

View File

@ -35,7 +35,6 @@ import Foundation
}
/// Image data used to create a texture. Image can be referenced by URI or `bufferView` index. `mimeType` is required in the latter case.
@objcMembers
open class GLTFImage: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// Class template
@objcMembers
open class GLTFKHRDracoMeshCompressionExtension: NSObject, Codable {

View File

@ -43,7 +43,6 @@ import Foundation
}
}
/// The material appearance of a primitive.
@objcMembers
open class GLTFMaterial: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// The normal map texture.
@objcMembers
open class GLTFMaterialNormalTextureInfo: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// The occlusion map texture.
@objcMembers
open class GLTFMaterialOcclusionTextureInfo: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology.
@objcMembers
open class GLTFMaterialPBRMetallicRoughness: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// A set of primitives to be rendered. A node can contain one mesh. A node's transform places the mesh in the scene.
@objcMembers
open class GLTFMesh: NSObject, Codable {

View File

@ -63,7 +63,6 @@ import Foundation
}
}
/// Geometry to be rendered with the given material.
@objcMembers
open class GLTFMeshPrimitive: NSObject, Codable {
@ -106,7 +105,9 @@ open class GLTFMeshPrimitive : NSObject, Codable {
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
attributes = (try? container.decode([String: Int].self, forKey: .attributes)) ?? [String: Int]()
#if DRACO
extensions = try? container.decode([String: GLTFKHRDracoMeshCompressionExtension].self, forKey: .extensions)
#endif
extras = try? container.decode([String: Any].self, forKey: .extras)
indices = try? container.decode(Int.self, forKey: .indices)
material = try? container.decode(Int.self, forKey: .material)
@ -121,7 +122,9 @@ open class GLTFMeshPrimitive : NSObject, Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(attributes, forKey: .attributes)
#if DRACO
try? container.encode(extensions as? [String: GLTFKHRDracoMeshCompressionExtension], forKey: .extensions)
#endif
try container.encode(extras, forKey: .extras)
try container.encode(indices, forKey: .indices)
try container.encode(material, forKey: .material)
@ -131,6 +134,7 @@ open class GLTFMeshPrimitive : NSObject, Codable {
}
#if DRACO
extension KeyedEncodingContainerProtocol {
mutating func encode(_ value: [String: GLTFKHRDracoMeshCompressionExtension]?, forKey key: Key) throws {
if value != nil {
@ -139,4 +143,4 @@ extension KeyedEncodingContainerProtocol {
}
}
}
#endif

View File

@ -9,7 +9,6 @@
import Foundation
/// A node in the node hierarchy. When the node contains `skin`, all `mesh.primitives` must contain `JOINTS_0` and `WEIGHTS_0` attributes. A node can have either a `matrix` or any combination of `translation`/`rotation`/`scale` (TRS) properties. TRS properties are converted to matrices and postmultiplied in the `T * R * S` order to compose the transformation matrix; first the scale is applied to the vertices, then the rotation, and then the translation. If none are provided, the transform is the identity. When a node is targeted for animation (referenced by an animation.channel.target), only TRS properties may be present; `matrix` will not be present.
@objcMembers
open class GLTFNode: NSObject, Codable {

View File

@ -149,7 +149,6 @@ import Foundation
}
}
/// Texture sampler properties for filtering and wrapping modes.
@objcMembers
open class GLTFSampler: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// The root nodes of a scene.
@objcMembers
open class GLTFScene: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// Joints and matrices defining a skin.
@objcMembers
open class GLTFSkin: NSObject, Codable {

View File

@ -9,7 +9,6 @@
import Foundation
/// A texture and its sampler.
@objcMembers
open class GLTFTexture: NSObject, Codable {
@ -57,7 +56,6 @@ open class GLTFTexture : NSObject, Codable {
}
}
extension KeyedEncodingContainerProtocol {
mutating func encode(_ value: [String: GLTF_3D4MCompressedTextureExtension]?, forKey key: Key) throws {
if value != nil {
@ -66,4 +64,3 @@ extension KeyedEncodingContainerProtocol {
}
}
}

View File

@ -9,7 +9,6 @@
import Foundation
/// Reference to a texture.
@objcMembers
open class GLTFTextureInfo: NSObject, Codable {

View File

@ -20,22 +20,20 @@ public struct JSONCodingKeys: CodingKey {
}
}
public extension KeyedDecodingContainer {
func decode(_ type: Dictionary<String, Any>.Type, forKey key: K) throws -> Dictionary<String, Any> {
func decode(_ type: [String: Any].Type, forKey key: K) throws -> [String: Any] {
let container = try self.nestedContainer(keyedBy: JSONCodingKeys.self, forKey: key)
return try container.decode(type)
}
func decode(_ type: Array<Any>.Type, forKey key: K) throws -> Array<Any> {
func decode(_ type: [Any].Type, forKey key: K) throws -> [Any] {
var container = try self.nestedUnkeyedContainer(forKey: key)
return try container.decode(type)
}
func decode(_ type: Dictionary<String, Any>.Type) throws -> Dictionary<String, Any> {
var dictionary = Dictionary<String, Any>()
func decode(_ type: [String: Any].Type) throws -> [String: Any] {
var dictionary = [String: Any]()
for key in allKeys {
if let boolValue = try? decode(Bool.self, forKey: key) {
@ -58,7 +56,7 @@ public extension KeyedDecodingContainer {
public extension UnkeyedDecodingContainer {
mutating func decode(_ type: Array<Any>.Type) throws -> Array<Any> {
mutating func decode(_ type: [Any].Type) throws -> [Any] {
var array: [Any] = []
while isAtEnd == false {
if let value = try? decode(Bool.self) {
@ -69,22 +67,22 @@ public extension UnkeyedDecodingContainer {
array.append(value)
} else if let nestedDictionary = try? decode(Dictionary<String, Any>.self) {
array.append(nestedDictionary)
} else if let nestedArray = try? decode(Array<Any>.self) {
} else if var nestedContainer = try? nestedUnkeyedContainer(),
let nestedArray = try? nestedContainer.decode(Array<Any>.self) {
array.append(nestedArray)
}
}
return array
}
mutating func decode(_ type: Dictionary<String, Any>.Type) throws -> Dictionary<String, Any> {
mutating func decode(_ type: [String: Any].Type) throws -> [String: Any] {
let nestedContainer = try self.nestedContainer(keyedBy: JSONCodingKeys.self)
return try nestedContainer.decode(type)
}
}
public extension KeyedEncodingContainerProtocol where Key == JSONCodingKeys {
mutating func encode(_ value: Dictionary<String, Any>) throws {
mutating func encode(_ value: [String: Any]) throws {
try value.forEach({ (key, value) in
let key = JSONCodingKeys(stringValue: key)
switch value {
@ -98,9 +96,9 @@ public extension KeyedEncodingContainerProtocol where Key == JSONCodingKeys {
try encode(value, forKey: key)
case let value as CGFloat:
try encode(value, forKey: key)
case let value as Dictionary<String, Any>:
case let value as [String: Any]:
try encode(value, forKey: key)
case let value as Array<Any>:
case let value as [Any]:
try encode(value, forKey: key)
case Optional<Any>.none:
try encodeNil(forKey: key)
@ -112,14 +110,14 @@ public extension KeyedEncodingContainerProtocol where Key == JSONCodingKeys {
}
public extension KeyedEncodingContainerProtocol {
mutating func encode(_ value: Dictionary<String, Any>?, forKey key: Key) throws {
mutating func encode(_ value: [String: Any]?, forKey key: Key) throws {
if value != nil {
var container = self.nestedContainer(keyedBy: JSONCodingKeys.self, forKey: key)
try container.encode(value!)
}
}
mutating func encode(_ value: Array<Any>?, forKey key: Key) throws {
mutating func encode(_ value: [Any]?, forKey key: Key) throws {
if value != nil {
var container = self.nestedUnkeyedContainer(forKey: key)
try container.encode(value!)
@ -128,7 +126,7 @@ public extension KeyedEncodingContainerProtocol {
}
public extension UnkeyedEncodingContainer {
mutating func encode(_ value: Array<Any>) throws {
mutating func encode(_ value: [Any]) throws {
try value.enumerated().forEach({ (index, value) in
switch value {
case let value as Bool:
@ -141,9 +139,9 @@ public extension UnkeyedEncodingContainer {
try encode(value)
case let value as CGFloat:
try encode(value)
case let value as Dictionary<String, Any>:
case let value as [String: Any]:
try encode(value)
case let value as Array<Any>:
case let value as [Any]:
try encode(value)
case Optional<Any>.none:
try encodeNil()
@ -154,9 +152,8 @@ public extension UnkeyedEncodingContainer {
})
}
mutating func encode(_ value: Dictionary<String, Any>) throws {
mutating func encode(_ value: [String: Any]) throws {
var nestedContainer = self.nestedContainer(keyedBy: JSONCodingKeys.self)
try nestedContainer.encode(value)
}
}

View File

@ -7,9 +7,8 @@
import SceneKit
extension GLTFMeshPrimitiveMode {
fileprivate func scn() -> SCNGeometryPrimitiveType {
public func scn() -> SCNGeometryPrimitiveType {
switch self {
case .POINTS:
return .point
@ -25,8 +24,9 @@ extension GLTFMeshPrimitiveMode {
}
}
@available(OSX 10.12, iOS 10.0, *)
extension GLTFAccessor {
fileprivate func components() -> Int {
public func components() -> Int {
switch type {
case .SCALAR:
return 1
@ -43,7 +43,7 @@ extension GLTFAccessor {
}
}
fileprivate func bytesPerElement() -> Int {
public func bytesPerElement() -> Int {
switch componentType {
case .UNSIGNED_BYTE, .BYTE:
return 1
@ -54,7 +54,7 @@ extension GLTFAccessor {
}
}
fileprivate func vertexFormat() -> MTLVertexFormat {
public func vertexFormat() -> MTLVertexFormat {
switch type {
case .SCALAR:
switch componentType {
@ -132,10 +132,9 @@ fileprivate extension GLTF {
}
}
@available(OSX 10.12, iOS 10.0, *)
extension GLTFConverter {
/// convert glTF mesh into SCNGeometry
///
/// - Parameters:
@ -148,7 +147,6 @@ extension GLTFConverter {
}
if let meshIndex = node.mesh {
var weightPaths = [String]()
if let mesh = glTF.meshes?[meshIndex] {
@ -170,24 +168,25 @@ extension GLTFConverter {
sources.append(contentsOf: geometrySources)
}
#if DRACO
// check on draco extension
if let dracoMesh = primitive.extensions?[dracoExtensionKey] {
let (dElement, dSources) = try glTF.convertDracoMesh(dracoMesh as! GLTFKHRDracoMeshCompressionExtension)
if (dElement != nil) {
if dElement != nil {
elements.append(dElement!)
}
if (dSources != nil) {
if dSources != nil {
sources.append(contentsOf: dSources!)
}
}
#endif
if glTF.isCancelled {
return
}
let primitiveNode: SCNNode
// create geometry
let geometry = SCNGeometry.init(sources: sources, elements: elements)
@ -222,13 +221,14 @@ extension GLTFConverter {
}
}
}
}) { [unowned self] scnMaterial in
}, completionHandler: { [unowned self] scnMaterial in
self.delegate?.scene?(self.loadingScene!, didCreate: scnMaterial, for: primitiveNode)
let emissionContent = primitiveNode.geometry?.firstMaterial?.emission.contents
scnMaterial.emission.contents = emissionContent
geometry.materials = [scnMaterial]
}
})
}
if let transparency = primitiveNode.geometry?.firstMaterial?.transparency,
@ -278,13 +278,11 @@ extension GLTFConverter {
let primitiveType = primitive.mode.scn()
switch primitiveType {
case .triangles:
count = count/3
break
count /= 3
case .triangleStrip:
count = count-2
break
count -= 2
case .line:
count = count/2
count /= 2
default:
break
}
@ -315,7 +313,6 @@ extension GLTFConverter {
var byteOffset = 0
var byteStride = 0
for (key, accessorIndex) in attributes {
if let accessor = glTF.accessors?[accessorIndex],
let (bufferView, interleaved) = try determineAcessor(accessor) {
@ -323,7 +320,7 @@ extension GLTFConverter {
byteOffset = (interleaved) ? accessor.byteOffset : 0
byteStride = bufferView.byteStride ?? 0
if (mtlBuffer == nil || previousBufferView != accessor.bufferView!) {
if mtlBuffer == nil || previousBufferView != accessor.bufferView! {
if let data = try loadAcessor(accessor, bufferView, interleaved) {
let device = self.device()
@ -362,7 +359,6 @@ extension GLTFConverter {
return geometrySources
}
// TODO: Collect associated buffers for node into a Set on Decode time.
internal func _preloadBuffersData(nodeIndex: Int, completionHandler: @escaping (Error?) -> Void ) {
@ -389,6 +385,7 @@ extension GLTFConverter {
for primitive in mesh.primitives {
// check on draco extension
#if DRACO
if let dracoMesh = primitive.extensions?[dracoExtensionKey] {
if let dracoMesh = dracoMesh as? GLTFKHRDracoMeshCompressionExtension {
if let buffer = glTF.buffer(for: dracoMesh.bufferView) {
@ -407,13 +404,19 @@ extension GLTFConverter {
}
insertBuffer(primitive.indices)
}
#else
primitive.attributes.forEach { (_, index) in
insertBuffer(index)
}
insertBuffer(primitive.indices)
#endif
}
}
glTF.loader.load(gltf: glTF, resources: buffers, options: ResourceType.buffer, completionHandler: completionHandler)
}
// determine where an accessor and a bufferView link are interleaved or not
internal func determineAcessor(_ accessor: GLTFAccessor) throws -> (GLTFBufferView, Bool)? {
@ -435,14 +438,13 @@ extension GLTFConverter {
return nil
}
// get data by accessor
internal func loadAcessor(_ accessor: GLTFAccessor, _ bufferView: GLTFBufferView, _ interleaved: Bool) throws -> Data? {
if let data = try GLTF.requestData(glTF: glTF, bufferView: bufferView) {
var byteStride: Int = bufferView.byteStride ?? 0
if (byteStride == 0) {
if byteStride == 0 {
byteStride = accessor.components()*accessor.bytesPerElement()
}
// calculate length
@ -463,6 +465,4 @@ extension GLTFConverter {
return nil
}
}

View File

@ -8,6 +8,7 @@
import SceneKit
import os
@available(OSX 10.12, iOS 10.0, *)
public class GLTFConverter: TextureLoaderDelegate {
/// Status will be true if `cancel` was call.
@ -31,7 +32,6 @@ public class GLTFConverter: TextureLoaderDelegate {
self.glTF = glTF
}
/// Convert glTF object to SceneKit scene.
///
/// - Parameter scene: Optional parameter. If property is set then loaded model will be add to existing objects in scene.
@ -41,13 +41,14 @@ public class GLTFConverter: TextureLoaderDelegate {
/// - Parameter completionHandler: Execute completion block once model fully loaded. If multiThread parameter set to true, then scene will be returned soon as possible and completion block will be executed later, after all textures load.
/// - Returns: instance of Scene
@objc open func convert(to scene: SCNScene = SCNScene.init(),
rootNode: SCNNode? = nil,
directoryPath: String? = nil,
multiThread: Bool = true,
hidden: Bool = false,
geometryCompletionHandler: @escaping () -> Void = { },
completionHandler: @escaping ((Error?) -> Void) = {_ in }) -> SCNScene? {
if (glTF.extensionsUsed != nil) {
if glTF.extensionsUsed != nil {
// for key in self.extensionsUsed! {
// if !supportedExtensions.contains(key) {
// completionHandler("Used `\(key)` extension is not supported!")
@ -56,7 +57,7 @@ public class GLTFConverter: TextureLoaderDelegate {
// }
}
if (glTF.extensionsRequired != nil) {
if glTF.extensionsRequired != nil {
for key in glTF.extensionsRequired! {
if !supportedExtensions.contains(key) {
completionHandler(GLTFError("Required `\(key)` extension is not supported!"))
@ -65,6 +66,8 @@ public class GLTFConverter: TextureLoaderDelegate {
}
}
assert(delegate != nil)
self.loadingScene = scene
self._completionHandler = completionHandler
@ -85,7 +88,7 @@ public class GLTFConverter: TextureLoaderDelegate {
self.cache_nodes = [SCNNode?](repeating: nil, count: glTF.nodes!.count)
// run in multi-thread or single
if (multiThread) {
if multiThread {
let start = Date()
@ -94,7 +97,8 @@ public class GLTFConverter: TextureLoaderDelegate {
let texturesGroup = TextureStorageManager.manager.group(gltf: glTF, delegate: self, true)
// construct nodes tree
_constructNodesTree(rootNode: scene.rootNode, nodes: sceneGlTF.nodes!, group: convertGroup, hidden: hidden)
_constructNodesTree(rootNode: rootNode ?? scene.rootNode, nodes: sceneGlTF.nodes!, group: convertGroup, hidden: hidden)
os_log("submit data to download %d ms", log: log_scenekit, type: .debug, Int(start.timeIntervalSinceNow * -1000))
@ -115,6 +119,7 @@ public class GLTFConverter: TextureLoaderDelegate {
for nodeIndex in sceneGlTF.nodes! {
if let scnNode = try self.buildNode(nodeIndex: nodeIndex) {
scnNode.isHidden = hidden
scene.rootNode.addChildNode(scnNode)
}
}
@ -127,7 +132,6 @@ public class GLTFConverter: TextureLoaderDelegate {
}
}
if glTF.isCancelled {
return nil
}
@ -138,22 +142,29 @@ public class GLTFConverter: TextureLoaderDelegate {
@objc
open func cancel() {
glTF.cancel()
TextureStorageManager.manager.clear(gltf: glTF);
TextureStorageManager.manager.clear(gltf: glTF)
}
internal func _constructNodesTree(rootNode: SCNNode, nodes: [Int], group: DispatchGroup, hidden: Bool) {
var cache_nodes = self.cache_nodes
for nodeIndex in nodes {
if (glTF.isCancelled) {
if glTF.isCancelled {
return
}
if let node = glTF.nodes?[nodeIndex] {
group.enter() // <=== enter group
let scnNode = SCNNode()
let scnNode: SCNNode
if let name = node.name,
let existedNode = rootNode.childNode(withName: name, recursively: false) {
scnNode = existedNode
} else {
scnNode = SCNNode()
}
scnNode.isHidden = hidden
if let node = glTF.nodes?[nodeIndex] {
scnNode.name = node.name
let haveChilds = node.children != nil && node.children?.count != 0
@ -169,7 +180,6 @@ public class GLTFConverter: TextureLoaderDelegate {
scnNode.addChildNode(scnNodePrimitiveNode)
}
}
}
rootNode.addChildNode(scnNode)
cache_nodes?[nodeIndex] = scnNode
@ -187,9 +197,11 @@ public class GLTFConverter: TextureLoaderDelegate {
}
group.leave() // <=== leave group
}
}
}
}
}
/// Nodes converted, start parse and create animation.
/// And in case no textures required to load, complete convertion from glTF to SceneKit.
@ -305,12 +317,10 @@ public class GLTFConverter: TextureLoaderDelegate {
scnNode.camera?.wantsDepthOfField = true
scnNode.camera?.motionBlurIntensity = 0.3
}
break
case .orthographic:
scnNode.camera?.usesOrthographicProjection = true
scnNode.camera?.zNear = (camera.orthographic?.znear)!
scnNode.camera?.zFar = (camera.orthographic?.zfar)!
break
}
if let camera = scnNode.camera {
delegate?.scene?(loadingScene!, didCreate: camera)

View File

@ -13,7 +13,6 @@ public enum ResourceType {
case image
}
/// Description for resources delivery by request from general GLTF converter.
/// - Simple implementation is GLTFResourceLoaderDefault and utilised as default resource delivery instrument.
/// - Optionaly can be implemented own resource loader, for example if requered to deliver content from remote server.
@ -75,7 +74,7 @@ open class GLTFResourceLoaderDefault : GLTFResourceLoader {
} catch {
error_ = error
}
DispatchQueue.global().async {
DispatchQueue.global(qos: .userInteractive).async {
completionHandler(error_)
}
@ -111,8 +110,7 @@ open class GLTFResourceLoaderDefault : GLTFResourceLoader {
fileprivate func loadUri(uri: String) throws -> Data? {
var data = uri.base64Decoded()
if data == nil {
if (uri.hasPrefix("http")) {
if uri.hasPrefix("http") {
if let url = URL.init(string: uri) {
data = try Data.init(contentsOf: url)
return data
@ -128,4 +126,3 @@ open class GLTFResourceLoaderDefault : GLTFResourceLoader {
return data
}
}

View File

@ -344,7 +344,6 @@ public enum GLTF_3D4MCompressedTextureExtensionTarget: Int, RawRepresentable, Co
}
}
/// Class template
open class GLTF_3D4MCompressedTextureExtension: Codable {
/// Compression type.

View File

@ -19,7 +19,6 @@ import SceneKit
typealias SCNFloat = CGFloat
#endif
struct SCNVector2 {
public var x: SCNFloat
public var y: SCNFloat
@ -122,7 +121,6 @@ extension OSImage {
return try channels(from: cgImage)
}
func channels(from image: CGImage) throws -> [OSImage] {
let w = image.width
let h = image.height
@ -135,7 +133,6 @@ extension OSImage {
let rawPtr: UnsafeMutableRawPointer = malloc(srcDataSize)
defer { free(rawPtr) }
guard let context = CGContext(data: rawPtr, width: w, height: h, bitsPerComponent: bitsPerComponent, bytesPerRow: srcBytesPerPixel * w, space: colorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue) else {
throw GLTFError("Failed to make textures")
}
@ -214,7 +211,7 @@ extension OSImage {
}
@available(OSX 10.12, iOS 10.0, *)
extension MTLPixelFormat {
public func hasAlpha() -> Bool {
switch self {
@ -230,15 +227,16 @@ extension MTLPixelFormat {
}
}
@available(OSX 10.12, iOS 10.0, *)
extension SCNMaterial {
public func hasAlpha() -> Bool {
return (diffuse.contents as? MTLTexture)?.pixelFormat.hasAlpha() ?? false
}
}
@available(OSX 10.12, iOS 10.0, *)
class MetalDevice {
static var device = {
return MTLCreateSystemDefaultDevice()
}()
}

View File

@ -16,7 +16,7 @@ enum TextureStatus:Int {
case loaded
}
protocol TextureLoaderDelegate {
protocol TextureLoaderDelegate: class {
var renderer: SCNSceneRenderer? { get }
func texturesLoaded()
}
@ -24,11 +24,11 @@ protocol TextureLoaderDelegate {
class TextureAssociator {
var status: TextureStatus = .no
private var content_:Any?
private var content_: Any? = OSColor.white
var content: Any? {
set {
content_ = newValue
if (newValue != nil) {
if newValue != nil {
self.status = .loaded
for property in associatedProperties {
@ -53,11 +53,12 @@ class TextureAssociator {
}
}
@available(OSX 10.12, iOS 10.0, *)
class TextureStorageManager {
static let manager = TextureStorageManager()
private var worker = DispatchQueue(label: "textures_loader", qos: .userInteractive)
private var worker = DispatchQueue(label: "textures_loader")
private var groups: [Int: DispatchGroup] = [Int: DispatchGroup]()
lazy private var _associators: [Int: [Int: TextureAssociator]] = [Int: [Int: TextureAssociator]]()
@ -108,17 +109,16 @@ class TextureStorageManager {
return group!
}
/// Load texture by index.
///
/// - Parameters:
/// - index: index of GLTFTexture in textures
/// - property: material's property
static func loadTexture(gltf: GLTF, delegate: TextureLoaderDelegate, index: Int, property: SCNMaterialProperty, callback: ((Any?)-> Void)? = nil) {
self.manager._loadTexture(gltf: gltf, delegate: delegate, index: index, property: property, callback: callback)
static func loadTexture(gltf: GLTF, delegate: TextureLoaderDelegate, index: Int, property: SCNMaterialProperty) {
self.manager._loadTexture(gltf: gltf, delegate: delegate, index: index, property: property)
}
fileprivate func _loadTexture(gltf: GLTF, delegate: TextureLoaderDelegate, index: Int, property: SCNMaterialProperty, callback: ((Any?)-> Void)? = nil) {
fileprivate func _loadTexture(gltf: GLTF, delegate: TextureLoaderDelegate, index: Int, property: SCNMaterialProperty) {
guard let texture = gltf.textures?[index] else {
print("Failed to find texture")
return
@ -137,24 +137,23 @@ class TextureStorageManager {
let device = MetalDevice.device
let metalOn = (delegate.renderer?.renderingAPI == .metal || device != nil)
if let descriptor = texture.extensions?[compressedTextureExtensionKey] as? GLTF_3D4MCompressedTextureExtension, metalOn {
// load first level mipmap as texture
gltf.loadCompressedTexture(descriptor: descriptor, loadLevel: .first) { cTexture, error in
tStatus.content = cTexture
if gltf.isCancelled {
group.leave()
return
}
if (error != nil) {
if error != nil {
print("Failed to load comressed texture \(error.debugDescription). Fallback on image source.")
self._loadImageTexture(gltf, delegate, texture, tStatus, callback)
self._loadImageTexture(gltf, delegate, texture, tStatus)
group.leave()
} else {
tStatus.content = cTexture as Any?
callback?(cTexture)
tStatus.content = cTexture
// load all levels
gltf.loadCompressedTexture(descriptor: descriptor, loadLevel: .last) { (cTexture2, error) in
@ -164,30 +163,31 @@ class TextureStorageManager {
return
}
if (error != nil) {
if error != nil {
print("Failed to load comressed texture \(error.debugDescription). Fallback on image source.")
self._loadImageTexture(gltf, delegate, texture, tStatus, callback)
self._loadImageTexture(gltf, delegate, texture, tStatus)
} else {
tStatus.content = cTexture2 as Any?
callback?(cTexture2)
tStatus.content = cTexture2
}
group.leave()
}
}
}
} else {
self._loadImageTexture(gltf, delegate, texture, tStatus)
group.leave()
self._loadImageTexture(gltf, delegate, texture, tStatus, callback)
}
} else {
group.leave()
tStatus.associate(property: property)
group.leave()
}
}
}
/// load original image source png or jpg
fileprivate func _loadImageTexture(_ gltf: GLTF, _ delegate: TextureLoaderDelegate, _ texture: GLTFTexture, _ tStatus: TextureAssociator, _ callback: ((Any?)-> Void)? = nil) {
fileprivate func _loadImageTexture(_ gltf: GLTF, _ delegate: TextureLoaderDelegate, _ texture: GLTFTexture, _ tStatus: TextureAssociator) {
self.worker.async {
if gltf.isCancelled {
return
@ -197,10 +197,9 @@ class TextureStorageManager {
if let imageSourceIndex = texture.source {
if let gltf_image = gltf.images?[imageSourceIndex] {
gltf.loader.load(gltf:gltf, resource: gltf_image) { resource, error in
gltf.loader.load(gltf: gltf, resource: gltf_image) { resource, _ in
if resource.image != nil {
tStatus.content = gltf._compress(image: resource.image!)
callback?(tStatus.content)
}
group.leave()
}
@ -209,4 +208,3 @@ class TextureStorageManager {
}
}
}

View File

@ -2,5 +2,5 @@ import XCTest
@testable import gltf_scenekitTests
XCTMain([
testCase(gltf_scenekitTests.allTests),
testCase(gltf_scenekitTests.allTests)
])

View File

@ -2,43 +2,109 @@ import XCTest
import SceneKit
@testable import glTFSceneKit
let jsonString = """
{ "accessors": [ ], "asset": { "copyright": "3D4Medical LLC", "generator": "Comanche", "version": "2.0" }, "bufferViews": [ { "buffer": 0, "byteLength": 118766, "byteStride": 44, "target": 34962 }], "buffers": [ { "byteLength": 118766, "uri": "draco/file.bin" }], "extensionsRequired": [ "KHR_draco_mesh_compression"], "extensionsUsed": [ "KHR_draco_mesh_compression"], "images": [ { "mimeType": "image/png", "uri": "png/texture.png" }, { "mimeType": "image/png", "uri": "png/texture.png" }], "materials": [ { "alphaMode": "OPAQUE", "name": "", "normalTexture": { "index": 1 }, "pbrMetallicRoughness": { "baseColorFactor": [ 0.725279, 0.700000, 0.734000, 1.000000], "baseColorTexture": { "index": 0 }, "metallicFactor": 0.000000, "roughnessFactor": 0.800000 } }], "meshes": [ { "primitives": [ { "attributes": { }, "extensions": { "KHR_draco_mesh_compression" : { "attributes": { "TEXCOORD_0" : 2, "NORMAL" : 1, "TANGENT" : 3, "POSITION" : 0}, "bufferView": 0 }}, "material": 0, "mode": 5 }] }], "nodes": [ { "mesh": 0 }], "samplers": [ { "magFilter": 9729, "minFilter": 9729, "wrapS": 10497, "wrapT": 10497 }], "scene": 0, "scenes": [ { "nodes": [ 0] }], "textures": [ { "sampler": 0, "source": 0 }, { "sampler": 0, "source": 1 }] }
"""
class LoadingDelegate : SceneLoadingDelegate {
}
class gltf_scenekitTests: XCTestCase {
func testGLTFinit() {
let view = SCNView()
let jsonData = jsonString.data(using: .utf8)
let scene = SCNScene()
let loadingDelegate = LoadingDelegate()
let decoder = JSONDecoder()
self.measure {
let glTF = try? decoder.decode(GLTF.self, from: jsonData!)
let converter = GLTFConverter()
_ = converter.convert(renderer:view, directoryPath:nil, multiThread:false, geometryCompletionHandler: {
})
// _ = glTF?.convert(renderer:view, directoryPath:nil, multiThread:false, geometryCompletionHandler: {
//
// })
override func setUp() {
view.scene = scene
}
let jsonDataArray = jsonData!.array() as [UInt8]
let jsonStringSimple = """
{ "accessors": [ ], "asset": { "copyright": "3D4Medical LLC", "generator": "Comanche", "version": "2.0" }, "bufferViews": [ { "buffer": 0, "byteLength": 118766, "byteStride": 44, "target": 34962 }], "buffers": [ { "byteLength": 118766, "uri": "draco/file.bin" }], "extensionsRequired": [ ], "extensionsUsed": [], "images": [ { "mimeType": "image/png", "uri": "png/texture.png" }, { "mimeType": "image/png", "uri": "png/texture.png" }], "materials": [ { "alphaMode": "OPAQUE", "name": "", "normalTexture": { "index": 1 }, "pbrMetallicRoughness": { "baseColorFactor": [ 0.725279, 0.700000, 0.734000, 1.000000], "baseColorTexture": { "index": 0 }, "metallicFactor": 0.000000, "roughnessFactor": 0.800000 } }], "meshes": [ { "primitives": [ { "attributes": { }, "extensions": { "KHR_draco_mesh_compression" : { "attributes": { "TEXCOORD_0" : 2, "NORMAL" : 1, "TANGENT" : 3, "POSITION" : 0}, "bufferView": 0 }}, "material": 0, "mode": 5 }] }], "nodes": [ { "mesh": 0 }], "samplers": [ { "magFilter": 9729, "minFilter": 9729, "wrapS": 10497, "wrapT": 10497 }], "scene": 0, "scenes": [ { "nodes": [ 0] }], "textures": [ { "sampler": 0, "source": 0 }, { "sampler": 0, "source": 1 }] }
"""
func testSimpleGLTFinit() {
// XCTAssert(glTF != nil)
let jsonData = jsonStringSimple.data(using: .utf8)
let expectationGeometry = self.expectation(description: "Geometry")
let expectationCompleted = self.expectation(description: "Completed")
if let glTF = try? decoder.decode(GLTF.self, from: jsonData!) {
let converter = GLTFConverter(glTF: glTF)
converter.delegate = loadingDelegate
let scene = converter.convert(to: view.scene!, geometryCompletionHandler: {
print("Geometry loaded")
expectationGeometry.fulfill()
}) { (error) in
print("Completed with \((error != nil) ? "\(error.debugDescription)" : "no errors")")
expectationCompleted.fulfill()
}
waitForExpectations(timeout: 5, handler: nil)
static var allTests = [
("testGLTFinit", testGLTFinit),
]
XCTAssert(scene != nil)
}
}
// Test where it's failed on extension
let jsonStringExt = """
{ "accessors": [ ], "asset": { "copyright": "3D4Medical LLC", "generator": "Comanche", "version": "2.0" }, "bufferViews": [ { "buffer": 0, "byteLength": 118766, "byteStride": 44, "target": 34962 }], "buffers": [ { "byteLength": 118766, "uri": "draco/file.bin" }], "extensionsRequired": [ "KHR_draco_mesh_compression"], "extensionsUsed": [ "KHR_draco_mesh_compression"], "images": [ { "mimeType": "image/png", "uri": "png/texture.png" }, { "mimeType": "image/png", "uri": "png/texture.png" }], "materials": [ { "alphaMode": "OPAQUE", "name": "", "normalTexture": { "index": 1 }, "pbrMetallicRoughness": { "baseColorFactor": [ 0.725279, 0.700000, 0.734000, 1.000000], "baseColorTexture": { "index": 0 }, "metallicFactor": 0.000000, "roughnessFactor": 0.800000 } }], "meshes": [ { "primitives": [ { "attributes": { }, "extensions": { "KHR_draco_mesh_compression" : { "attributes": { "TEXCOORD_0" : 2, "NORMAL" : 1, "TANGENT" : 3, "POSITION" : 0}, "bufferView": 0 }}, "material": 0, "mode": 5 }] }], "nodes": [ { "mesh": 0 }], "samplers": [ { "magFilter": 9729, "minFilter": 9729, "wrapS": 10497, "wrapT": 10497 }], "scene": 0, "scenes": [ { "nodes": [ 0] }], "textures": [ { "sampler": 0, "source": 0 }, { "sampler": 0, "source": 1 }] }
"""
func testGLTFfailure() {
let expectationGeometry = self.expectation(description: "Geometry")
let expectationCompleted = self.expectation(description: "Completed")
let jsonData = jsonStringExt.data(using: .utf8)
if let glTF = try? decoder.decode(GLTF.self, from: jsonData!) {
let converter = GLTFConverter(glTF: glTF)
converter.delegate = loadingDelegate
let scene = converter.convert(to: view.scene!, geometryCompletionHandler: {
print("Geometry loaded")
expectationGeometry.fulfill()
}) { (error) in
print("Completed with \((error != nil) ? "\(error.debugDescription)" : "no errors")")
XCTAssert(error != nil) // expecting error here
expectationGeometry.fulfill()
expectationCompleted.fulfill()
}
waitForExpectations(timeout: 5, handler: nil)
// expecting no scene here
XCTAssert(scene == nil)
}
}
let box_gltf = """
{"asset":{"generator":"COLLADA2GLTF","version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"children":[1],"matrix":[1,0,0,0,0,0,-1,0,0,1,0,0,0,0,0,1]},{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"NORMAL":1,"POSITION":2},"indices":0,"mode":4,"material":0}],"name":"Mesh"}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":1,"byteOffset":0,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":1,"byteOffset":288,"componentType":5126,"count":24,"max":[0.5,0.5,0.5],"min":[-0.5,-0.5,-0.5],"type":"VEC3"}],"materials":[{"pbrMetallicRoughness":{"baseColorFactor":[0.800000011920929,0,0,1],"metallicFactor":0},"name":"Red"}],"bufferViews":[{"buffer":0,"byteOffset":576,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":0,"byteLength":576,"byteStride":12,"target":34962}],"buffers":[{"byteLength":648,"uri":"data:application/octet-stream;base64,AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA"}]}
"""
func testGLTFBox() {
let expectationGeometry = self.expectation(description: "Geometry")
let expectationCompleted = self.expectation(description: "Completed")
let jsonData = box_gltf.data(using: .utf8)
if let glTF = try? decoder.decode(GLTF.self, from: jsonData!) {
let converter = GLTFConverter(glTF: glTF)
converter.delegate = loadingDelegate
let scene = converter.convert(to: view.scene!, geometryCompletionHandler: {
print("Geometry loaded")
expectationGeometry.fulfill()
}) { (error) in
print("Completed with \((error != nil) ? "\(error.debugDescription)" : "no errors")")
XCTAssert(error == nil)
expectationCompleted.fulfill()
}
waitForExpectations(timeout: 5, handler: nil)
XCTAssert(scene != nil)
let node = scene?.rootNode.childNodes.first?.childNodes.first?.childNodes.first!
let geometry = node?.geometry
XCTAssert(geometry != nil)
// expecting 24 elements
XCTAssert(geometry!.sources.first!.vectorCount == 24)
}
}
}

View File

@ -10,14 +10,7 @@
49A51D192345E8BB002B5D24 /* GLTFConverter+Geometry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D182345E8BB002B5D24 /* GLTFConverter+Geometry.swift */; };
49A51D1A2345E8BB002B5D24 /* GLTFConverter+Geometry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D182345E8BB002B5D24 /* GLTFConverter+Geometry.swift */; };
49A51D1B2345E8BB002B5D24 /* GLTFConverter+Geometry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D182345E8BB002B5D24 /* GLTFConverter+Geometry.swift */; };
49A51D1C2345E8BB002B5D24 /* GLTFConverter+Geometry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D182345E8BB002B5D24 /* GLTFConverter+Geometry.swift */; };
49A51D23234601B7002B5D24 /* GLTFConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D22234601B7002B5D24 /* GLTFConverter.swift */; };
49A51D24234601B7002B5D24 /* GLTFConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D22234601B7002B5D24 /* GLTFConverter.swift */; };
49A51D25234601B7002B5D24 /* GLTFConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D22234601B7002B5D24 /* GLTFConverter.swift */; };
49A51D26234601B7002B5D24 /* GLTFConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D22234601B7002B5D24 /* GLTFConverter.swift */; };
D2157142204035E3009E9D16 /* JSONCodingKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = D215713A20402611009E9D16 /* JSONCodingKeys.swift */; };
D2180CDF208745A6005353CF /* GLTF+Draco.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2180CDD2087457D005353CF /* GLTF+Draco.swift */; };
D2180CE0208745A7005353CF /* GLTF+Draco.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2180CDD2087457D005353CF /* GLTF+Draco.swift */; };
D256CD0620B2B9F1002E841E /* glTFSceneKit-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = D2A67C0B20ADB9D0007523AF /* glTFSceneKit-Bridging-Header.h */; };
D256CD0720B2B9F2002E841E /* glTFSceneKit-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = D2A67C0B20ADB9D0007523AF /* glTFSceneKit-Bridging-Header.h */; };
D2750CED2077B7AC00F6198D /* GLTF+SceneKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* GLTF+SceneKit.swift */; };
@ -43,7 +36,6 @@
D2750D012077B7AC00F6198D /* GLTFMaterialOcclusionTextureInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_29 /* GLTFMaterialOcclusionTextureInfo.swift */; };
D2750D022077B7AC00F6198D /* GLTFMaterialPBRMetallicRoughness.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_30 /* GLTFMaterialPBRMetallicRoughness.swift */; };
D2750D032077B7AC00F6198D /* GLTFMesh.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* GLTFMesh.swift */; };
D2750D042077B7AC00F6198D /* GLTFKHRDracoMeshCompressionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27BDF82203F0BEF0036F3A7 /* GLTFKHRDracoMeshCompressionExtension.swift */; };
D2750D052077B7AC00F6198D /* GLTFMeshPrimitive.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_32 /* GLTFMeshPrimitive.swift */; };
D2750D062077B7AC00F6198D /* GLTFNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* GLTFNode.swift */; };
D2750D072077B7AC00F6198D /* JSONCodingKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = D215713A20402611009E9D16 /* JSONCodingKeys.swift */; };
@ -53,15 +45,10 @@
D2750D0B2077B7AC00F6198D /* GLTFTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_37 /* GLTFTexture.swift */; };
D2750D0C2077B7AC00F6198D /* GLTFTextureInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_38 /* GLTFTextureInfo.swift */; };
D2750D0D2077B7AC00F6198D /* Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_39 /* Helper.swift */; };
D27BDF83203F0BEF0036F3A7 /* GLTFKHRDracoMeshCompressionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27BDF82203F0BEF0036F3A7 /* GLTFKHRDracoMeshCompressionExtension.swift */; };
D287556D2077CB16009B7FA9 /* GLTF+CompressedTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = D287556B2077CABB009B7FA9 /* GLTF+CompressedTexture.swift */; };
D287556E2077CB1B009B7FA9 /* GLTF+CompressedTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = D287556B2077CABB009B7FA9 /* GLTF+CompressedTexture.swift */; };
D287E3F5209602EB00EBCFD1 /* TextureStorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D287E3F4209602EB00EBCFD1 /* TextureStorageManager.swift */; };
D287E3F6209602EB00EBCFD1 /* TextureStorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D287E3F4209602EB00EBCFD1 /* TextureStorageManager.swift */; };
D2A67C0020ADB91B007523AF /* Draco.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A67BFF20ADB91B007523AF /* Draco.swift */; };
D2A67C0120ADB91B007523AF /* Draco.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A67BFF20ADB91B007523AF /* Draco.swift */; };
D2A67C0320ADB92F007523AF /* libdraco.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2A67C0220ADB92F007523AF /* libdraco.a */; };
D2A67C0520ADB93E007523AF /* libdraco_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2A67C0420ADB93E007523AF /* libdraco_ios.a */; };
D2AC651E205D578B0091D5E0 /* GLTF_3D4MCompressedTextureExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2AC651D205D578A0091D5E0 /* GLTF_3D4MCompressedTextureExtension.swift */; };
D2AFCFC0208F1DE00048A9DA /* GLTF+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2AFCFBF208F1DE00048A9DA /* GLTF+Animation.swift */; };
D2AFCFC1208F1DE00048A9DA /* GLTF+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2AFCFBF208F1DE00048A9DA /* GLTF+Animation.swift */; };
@ -84,7 +71,6 @@
D2B064E9214FE0CC00309D6F /* GLTF+Material.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2AFCFC2208F2A010048A9DA /* GLTF+Material.swift */; };
D2B064EA214FE0CC00309D6F /* GLTFAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* GLTFAsset.swift */; };
D2B064EB214FE0CC00309D6F /* GLTFBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* GLTFBuffer.swift */; };
D2B064EC214FE0CC00309D6F /* Draco.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A67BFF20ADB91B007523AF /* Draco.swift */; };
D2B064ED214FE0CC00309D6F /* GLTFBufferView.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* GLTFBufferView.swift */; };
D2B064EE214FE0CC00309D6F /* GLTFCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_23 /* GLTFCamera.swift */; };
D2B064EF214FE0CC00309D6F /* GLTFResourceLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2AFCFD1208F6F010048A9DA /* GLTFResourceLoader.swift */; };
@ -96,21 +82,21 @@
D2B064F5214FE0CC00309D6F /* GLTFMaterialOcclusionTextureInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_29 /* GLTFMaterialOcclusionTextureInfo.swift */; };
D2B064F6214FE0CC00309D6F /* GLTFMaterialPBRMetallicRoughness.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_30 /* GLTFMaterialPBRMetallicRoughness.swift */; };
D2B064F7214FE0CC00309D6F /* GLTFMesh.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* GLTFMesh.swift */; };
D2B064F8214FE0CC00309D6F /* GLTFKHRDracoMeshCompressionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27BDF82203F0BEF0036F3A7 /* GLTFKHRDracoMeshCompressionExtension.swift */; };
D2B064F9214FE0CC00309D6F /* GLTFMeshPrimitive.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_32 /* GLTFMeshPrimitive.swift */; };
D2B064FA214FE0CC00309D6F /* GLTFNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* GLTFNode.swift */; };
D2B064FB214FE0CC00309D6F /* GLTF+CompressedTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = D287556B2077CABB009B7FA9 /* GLTF+CompressedTexture.swift */; };
D2B064FC214FE0CC00309D6F /* JSONCodingKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = D215713A20402611009E9D16 /* JSONCodingKeys.swift */; };
D2B064FD214FE0CC00309D6F /* GLTFSampler.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_34 /* GLTFSampler.swift */; };
D2B064FE214FE0CC00309D6F /* GLTFScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_35 /* GLTFScene.swift */; };
D2B064FF214FE0CC00309D6F /* GLTF+Draco.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2180CDD2087457D005353CF /* GLTF+Draco.swift */; };
D2B06500214FE0CC00309D6F /* GLTFSkin.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_36 /* GLTFSkin.swift */; };
D2B06501214FE0CC00309D6F /* TextureStorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D287E3F4209602EB00EBCFD1 /* TextureStorageManager.swift */; };
D2B06502214FE0CC00309D6F /* GLTFTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_37 /* GLTFTexture.swift */; };
D2B06503214FE0CC00309D6F /* GLTFTextureInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_38 /* GLTFTextureInfo.swift */; };
D2B06504214FE0CC00309D6F /* Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_39 /* Helper.swift */; };
D2B06509214FE0CC00309D6F /* glTFSceneKit-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = D2A67C0B20ADB9D0007523AF /* glTFSceneKit-Bridging-Header.h */; };
D2B0651F214FEC7200309D6F /* libdraco_tvos.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2B0651E214FEC7200309D6F /* libdraco_tvos.a */; };
D2C6215623B4F77E00EA739E /* GLTFConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D22234601B7002B5D24 /* GLTFConverter.swift */; };
D2C6215723B4F77F00EA739E /* GLTFConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D22234601B7002B5D24 /* GLTFConverter.swift */; };
D2C6215823B4F78000EA739E /* GLTFConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A51D22234601B7002B5D24 /* GLTFConverter.swift */; };
OBJ_58 /* gltf_scenekitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_42 /* gltf_scenekitTests.swift */; };
OBJ_60 /* glTFSceneKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "gltf_scenekit::gltf_scenekit::Product" /* glTFSceneKit.framework */; };
OBJ_67 /* GLTF+SceneKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* GLTF+SceneKit.swift */; };
@ -194,16 +180,12 @@
D27BDF82203F0BEF0036F3A7 /* GLTFKHRDracoMeshCompressionExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GLTFKHRDracoMeshCompressionExtension.swift; sourceTree = "<group>"; };
D287556B2077CABB009B7FA9 /* GLTF+CompressedTexture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GLTF+CompressedTexture.swift"; sourceTree = "<group>"; };
D287E3F4209602EB00EBCFD1 /* TextureStorageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureStorageManager.swift; sourceTree = "<group>"; };
D2A67BFF20ADB91B007523AF /* Draco.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Draco.swift; path = Draco/Draco/Draco.swift; sourceTree = "<group>"; };
D2A67C0220ADB92F007523AF /* libdraco.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdraco.a; path = Draco/libdraco.a; sourceTree = "<group>"; };
D2A67C0420ADB93E007523AF /* libdraco_ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdraco_ios.a; path = Draco/libdraco_ios.a; sourceTree = "<group>"; };
D2A67C0B20ADB9D0007523AF /* glTFSceneKit-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "glTFSceneKit-Bridging-Header.h"; sourceTree = "<group>"; };
D2AC651D205D578A0091D5E0 /* GLTF_3D4MCompressedTextureExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GLTF_3D4MCompressedTextureExtension.swift; sourceTree = "<group>"; };
D2AFCFBF208F1DE00048A9DA /* GLTF+Animation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GLTF+Animation.swift"; sourceTree = "<group>"; };
D2AFCFC2208F2A010048A9DA /* GLTF+Material.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GLTF+Material.swift"; sourceTree = "<group>"; };
D2AFCFD1208F6F010048A9DA /* GLTFResourceLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GLTFResourceLoader.swift; sourceTree = "<group>"; };
D2B0650D214FE0CC00309D6F /* glTFSceneKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = glTFSceneKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D2B0651E214FEC7200309D6F /* libdraco_tvos.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdraco_tvos.a; path = Draco/libdraco_tvos.a; sourceTree = "<group>"; };
OBJ_11 /* GLTF.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GLTF.swift; sourceTree = "<group>"; };
OBJ_12 /* GLTFAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GLTFAccessor.swift; sourceTree = "<group>"; };
OBJ_13 /* GLTFAccessorSparse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GLTFAccessorSparse.swift; sourceTree = "<group>"; };
@ -245,7 +227,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 0;
files = (
D2A67C0520ADB93E007523AF /* libdraco_ios.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -253,7 +234,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 0;
files = (
D2B0651F214FEC7200309D6F /* libdraco_tvos.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -269,7 +249,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 0;
files = (
D2A67C0320ADB92F007523AF /* libdraco.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -279,9 +258,6 @@
D27BDF7B203DCE6E0036F3A7 /* Frameworks */ = {
isa = PBXGroup;
children = (
D2B0651E214FEC7200309D6F /* libdraco_tvos.a */,
D2A67C0420ADB93E007523AF /* libdraco_ios.a */,
D2A67C0220ADB92F007523AF /* libdraco.a */,
);
name = Frameworks;
sourceTree = "<group>";
@ -363,7 +339,6 @@
children = (
OBJ_6 /* Package.swift */,
D2A67C0B20ADB9D0007523AF /* glTFSceneKit-Bridging-Header.h */,
D2A67BFF20ADB91B007523AF /* Draco.swift */,
OBJ_7 /* Sources */,
OBJ_40 /* Tests */,
OBJ_43 /* Dependencies */,
@ -513,6 +488,7 @@
LastUpgradeCheck = 1020;
TargetAttributes = {
D2750CEA2077B7AC00F6198D = {
LastSwiftMigration = 1130;
ProvisioningStyle = Manual;
};
D2B064DA214FE0CC00309D6F = {
@ -609,12 +585,10 @@
D2AFCFC4208F2A010048A9DA /* GLTF+Material.swift in Sources */,
D2750CF82077B7AC00F6198D /* GLTFAsset.swift in Sources */,
D2750CF92077B7AC00F6198D /* GLTFBuffer.swift in Sources */,
D2A67C0120ADB91B007523AF /* Draco.swift in Sources */,
D2750CFA2077B7AC00F6198D /* GLTFBufferView.swift in Sources */,
D2750CFB2077B7AC00F6198D /* GLTFCamera.swift in Sources */,
D2AFCFD3208F6F010048A9DA /* GLTFResourceLoader.swift in Sources */,
D2750CFC2077B7AC00F6198D /* GLTFCameraOrthographic.swift in Sources */,
49A51D24234601B7002B5D24 /* GLTFConverter.swift in Sources */,
D2750CFD2077B7AC00F6198D /* GLTFCameraPerspective.swift in Sources */,
D2750CFE2077B7AC00F6198D /* GLTFImage.swift in Sources */,
D2750CFF2077B7AC00F6198D /* GLTFMaterial.swift in Sources */,
@ -622,14 +596,13 @@
D2750D012077B7AC00F6198D /* GLTFMaterialOcclusionTextureInfo.swift in Sources */,
D2750D022077B7AC00F6198D /* GLTFMaterialPBRMetallicRoughness.swift in Sources */,
D2750D032077B7AC00F6198D /* GLTFMesh.swift in Sources */,
D2750D042077B7AC00F6198D /* GLTFKHRDracoMeshCompressionExtension.swift in Sources */,
D2C6215723B4F77F00EA739E /* GLTFConverter.swift in Sources */,
D2750D052077B7AC00F6198D /* GLTFMeshPrimitive.swift in Sources */,
D2750D062077B7AC00F6198D /* GLTFNode.swift in Sources */,
D287556E2077CB1B009B7FA9 /* GLTF+CompressedTexture.swift in Sources */,
D2750D072077B7AC00F6198D /* JSONCodingKeys.swift in Sources */,
D2750D082077B7AC00F6198D /* GLTFSampler.swift in Sources */,
D2750D092077B7AC00F6198D /* GLTFScene.swift in Sources */,
D2180CE0208745A7005353CF /* GLTF+Draco.swift in Sources */,
D2750D0A2077B7AC00F6198D /* GLTFSkin.swift in Sources */,
D287E3F6209602EB00EBCFD1 /* TextureStorageManager.swift in Sources */,
D2750D0B2077B7AC00F6198D /* GLTFTexture.swift in Sources */,
@ -658,12 +631,10 @@
D2B064E9214FE0CC00309D6F /* GLTF+Material.swift in Sources */,
D2B064EA214FE0CC00309D6F /* GLTFAsset.swift in Sources */,
D2B064EB214FE0CC00309D6F /* GLTFBuffer.swift in Sources */,
D2B064EC214FE0CC00309D6F /* Draco.swift in Sources */,
D2B064ED214FE0CC00309D6F /* GLTFBufferView.swift in Sources */,
D2B064EE214FE0CC00309D6F /* GLTFCamera.swift in Sources */,
D2B064EF214FE0CC00309D6F /* GLTFResourceLoader.swift in Sources */,
D2B064F0214FE0CC00309D6F /* GLTFCameraOrthographic.swift in Sources */,
49A51D25234601B7002B5D24 /* GLTFConverter.swift in Sources */,
D2B064F1214FE0CC00309D6F /* GLTFCameraPerspective.swift in Sources */,
D2B064F2214FE0CC00309D6F /* GLTFImage.swift in Sources */,
D2B064F3214FE0CC00309D6F /* GLTFMaterial.swift in Sources */,
@ -671,14 +642,13 @@
D2B064F5214FE0CC00309D6F /* GLTFMaterialOcclusionTextureInfo.swift in Sources */,
D2B064F6214FE0CC00309D6F /* GLTFMaterialPBRMetallicRoughness.swift in Sources */,
D2B064F7214FE0CC00309D6F /* GLTFMesh.swift in Sources */,
D2B064F8214FE0CC00309D6F /* GLTFKHRDracoMeshCompressionExtension.swift in Sources */,
D2C6215823B4F78000EA739E /* GLTFConverter.swift in Sources */,
D2B064F9214FE0CC00309D6F /* GLTFMeshPrimitive.swift in Sources */,
D2B064FA214FE0CC00309D6F /* GLTFNode.swift in Sources */,
D2B064FB214FE0CC00309D6F /* GLTF+CompressedTexture.swift in Sources */,
D2B064FC214FE0CC00309D6F /* JSONCodingKeys.swift in Sources */,
D2B064FD214FE0CC00309D6F /* GLTFSampler.swift in Sources */,
D2B064FE214FE0CC00309D6F /* GLTFScene.swift in Sources */,
D2B064FF214FE0CC00309D6F /* GLTF+Draco.swift in Sources */,
D2B06500214FE0CC00309D6F /* GLTFSkin.swift in Sources */,
D2B06501214FE0CC00309D6F /* TextureStorageManager.swift in Sources */,
D2B06502214FE0CC00309D6F /* GLTFTexture.swift in Sources */,
@ -691,8 +661,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 0;
files = (
49A51D26234601B7002B5D24 /* GLTFConverter.swift in Sources */,
49A51D1C2345E8BB002B5D24 /* GLTFConverter+Geometry.swift in Sources */,
OBJ_58 /* gltf_scenekitTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -717,12 +685,10 @@
D2AFCFC3208F2A010048A9DA /* GLTF+Material.swift in Sources */,
OBJ_77 /* GLTFAsset.swift in Sources */,
OBJ_78 /* GLTFBuffer.swift in Sources */,
D2A67C0020ADB91B007523AF /* Draco.swift in Sources */,
OBJ_79 /* GLTFBufferView.swift in Sources */,
OBJ_80 /* GLTFCamera.swift in Sources */,
D2AFCFD2208F6F010048A9DA /* GLTFResourceLoader.swift in Sources */,
OBJ_81 /* GLTFCameraOrthographic.swift in Sources */,
49A51D23234601B7002B5D24 /* GLTFConverter.swift in Sources */,
OBJ_82 /* GLTFCameraPerspective.swift in Sources */,
OBJ_83 /* GLTFImage.swift in Sources */,
OBJ_84 /* GLTFMaterial.swift in Sources */,
@ -730,14 +696,13 @@
OBJ_86 /* GLTFMaterialOcclusionTextureInfo.swift in Sources */,
OBJ_87 /* GLTFMaterialPBRMetallicRoughness.swift in Sources */,
OBJ_88 /* GLTFMesh.swift in Sources */,
D27BDF83203F0BEF0036F3A7 /* GLTFKHRDracoMeshCompressionExtension.swift in Sources */,
D2C6215623B4F77E00EA739E /* GLTFConverter.swift in Sources */,
OBJ_89 /* GLTFMeshPrimitive.swift in Sources */,
OBJ_90 /* GLTFNode.swift in Sources */,
D287556D2077CB16009B7FA9 /* GLTF+CompressedTexture.swift in Sources */,
D2157142204035E3009E9D16 /* JSONCodingKeys.swift in Sources */,
OBJ_91 /* GLTFSampler.swift in Sources */,
OBJ_92 /* GLTFScene.swift in Sources */,
D2180CDF208745A6005353CF /* GLTF+Draco.swift in Sources */,
OBJ_93 /* GLTFSkin.swift in Sources */,
D287E3F5209602EB00EBCFD1 /* TextureStorageManager.swift in Sources */,
OBJ_94 /* GLTFTexture.swift in Sources */,
@ -760,7 +725,6 @@
D2750D112077B7AC00F6198D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
BITCODE_GENERATION_MODE = bitcode;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
@ -768,19 +732,9 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Draco",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Draco",
);
INFOPLIST_FILE = glTFSceneKit.xcodeproj/gltf_scenekit_ios_Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Draco";
MACOSX_DEPLOYMENT_TARGET = 10.12;
OTHER_LDFLAGS = (
"$(inherited)",
@ -795,7 +749,7 @@
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_OBJC_BRIDGING_HEADER = "glTFSceneKit-Bridging-Header.h";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGET_NAME = glTFSceneKit;
VALID_ARCHS = arm64;
@ -805,26 +759,15 @@
D2750D122077B7AC00F6198D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Draco",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Draco",
);
INFOPLIST_FILE = glTFSceneKit.xcodeproj/gltf_scenekit_ios_Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Draco";
MACOSX_DEPLOYMENT_TARGET = 10.12;
OTHER_LDFLAGS = (
"$(inherited)",
@ -839,7 +782,7 @@
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_OBJC_BRIDGING_HEADER = "glTFSceneKit-Bridging-Header.h";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGET_NAME = glTFSceneKit;
VALID_ARCHS = arm64;
@ -855,19 +798,9 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Draco",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Draco",
);
INFOPLIST_FILE = glTFSceneKit.xcodeproj/glTFSceneKit_tvos.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Draco";
MACOSX_DEPLOYMENT_TARGET = 10.12;
OTHER_LDFLAGS = (
"$(inherited)",
@ -899,19 +832,9 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Draco",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Draco",
);
INFOPLIST_FILE = glTFSceneKit.xcodeproj/glTFSceneKit_tvos.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Draco";
MACOSX_DEPLOYMENT_TARGET = 10.12;
OTHER_LDFLAGS = (
"$(inherited)",
@ -1036,27 +959,12 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/.build/checkouts/**",
);
INFOPLIST_FILE = glTFSceneKit.xcodeproj/gltf_scenekitTests_Info.plist;
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(SRCROOT)/.build/checkouts/**";
MACOSX_DEPLOYMENT_TARGET = 10.12;
OTHER_LDFLAGS = (
"$(inherited)",
"-lc++",
"-ldraco",
);
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_NAME = glTFSceneKitTests;
SWIFT_OBJC_BRIDGING_HEADER = "glTFSceneKit-Bridging-Header.h";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGET_NAME = gltf_scenekitTests;
};
name = Debug;
@ -1065,27 +973,12 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/.build/checkouts/**",
);
INFOPLIST_FILE = glTFSceneKit.xcodeproj/gltf_scenekitTests_Info.plist;
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(SRCROOT)/.build/checkouts/**";
MACOSX_DEPLOYMENT_TARGET = 10.12;
OTHER_LDFLAGS = (
"$(inherited)",
"-lc++",
"-ldraco",
);
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_NAME = glTFSceneKitTests;
SWIFT_OBJC_BRIDGING_HEADER = "glTFSceneKit-Bridging-Header.h";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGET_NAME = gltf_scenekitTests;
};
name = Release;
@ -1093,7 +986,6 @@
OBJ_64 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
@ -1103,8 +995,7 @@
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = glTFSceneKit.xcodeproj/gltf_scenekit_Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Draco";
LIBRARY_SEARCH_PATHS = "";
MACH_O_TYPE = mh_dylib;
MACOSX_DEPLOYMENT_TARGET = 10.12;
OTHER_LDFLAGS = (
@ -1128,7 +1019,6 @@
OBJ_65 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
@ -1138,8 +1028,7 @@
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = glTFSceneKit.xcodeproj/gltf_scenekit_Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Draco";
LIBRARY_SEARCH_PATHS = "";
MACH_O_TYPE = mh_dylib;
MACOSX_DEPLOYMENT_TARGET = 10.12;
OTHER_LDFLAGS = (