Compare commits
24 Commits
feature/im
...
develop
Author | SHA1 | Date |
---|---|---|
![]() |
3a043b41c6 | |
![]() |
8512600e7d | |
![]() |
a8916f6e60 | |
![]() |
0bef3b8633 | |
![]() |
46fd54f726 | |
![]() |
31dea75e7c | |
![]() |
8c02951c65 | |
![]() |
9a4685ba98 | |
![]() |
8e65bf0f64 | |
![]() |
8c0d86d542 | |
![]() |
956583145d | |
![]() |
bcb7294eb1 | |
![]() |
19c3089f7e | |
![]() |
f6c9d76e03 | |
![]() |
af4c4926c5 | |
![]() |
463a27bc55 | |
![]() |
6b5faed6f6 | |
![]() |
e69d2f12ff | |
![]() |
9e0a0a4dcb | |
![]() |
0aed670c0c | |
![]() |
aacc3a5ad0 | |
![]() |
f9575a721c | |
![]() |
e49ed1f3b9 | |
![]() |
ed9d49fc09 |
|
@ -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
|
|
@ -1,6 +1,4 @@
|
|||
.DS_Store
|
||||
/.build
|
||||
/Packages
|
||||
gltf_scenekit.xcodeproj/project.xcworkspace/xcuserdata
|
||||
gltf_scenekit.xcodeproj/xcuserdata
|
||||
glTFSceneKit.xcodeproj/xcuserdata
|
||||
**/xcuserdata
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "Draco"]
|
||||
path = Draco
|
||||
url = https://github.com/3d4medical/DracoSwiftPackage.git
|
1
Draco
1
Draco
|
@ -1 +0,0 @@
|
|||
Subproject commit 10caef92253b10439b3bc560ecef4a79804f612a
|
|
@ -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
|
||||
}
|
|
@ -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"
|
||||
|
|
15
README.md
15
README.md
|
@ -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.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// The root object for a glTF asset.
|
||||
@objcMembers
|
||||
open class GLTF: NSObject, Codable {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// Sparse storage of attributes that deviate from their initialization value.
|
||||
@objcMembers
|
||||
open class GLTFAccessorSparse: NSObject, Codable {
|
||||
|
|
|
@ -40,7 +40,6 @@ import Foundation
|
|||
|
||||
}
|
||||
|
||||
|
||||
/// Indices of those attributes that deviate from their initialization value.
|
||||
@objcMembers
|
||||
open class GLTFAccessorSparseIndices: NSObject, Codable {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// A keyframe animation.
|
||||
@objcMembers
|
||||
open class GLTFAnimation: NSObject, Codable {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// Targets an animation's sampler at a node's property.
|
||||
@objcMembers
|
||||
open class GLTFAnimationChannel: NSObject, Codable {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// Metadata about the glTF asset.
|
||||
@objcMembers
|
||||
open class GLTFAsset: NSObject, Codable {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// A buffer points to binary geometry, animation, or skins.
|
||||
@objcMembers
|
||||
open class GLTFBuffer: NSObject, Codable {
|
||||
|
|
|
@ -35,7 +35,6 @@ import Foundation
|
|||
|
||||
}
|
||||
|
||||
|
||||
/// A view into a buffer generally representing a subset of the buffer.
|
||||
@objcMembers
|
||||
open class GLTFBufferView: NSObject, Codable {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// An orthographic camera containing properties to create an orthographic projection matrix.
|
||||
@objcMembers
|
||||
open class GLTFCameraOrthographic: NSObject, Codable {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// A perspective camera containing properties to create a perspective projection matrix.
|
||||
@objcMembers
|
||||
open class GLTFCameraPerspective: NSObject, Codable {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// Class template
|
||||
@objcMembers
|
||||
open class GLTFKHRDracoMeshCompressionExtension: NSObject, Codable {
|
||||
|
|
|
@ -43,7 +43,6 @@ import Foundation
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// The material appearance of a primitive.
|
||||
@objcMembers
|
||||
open class GLTFMaterial: NSObject, Codable {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// The normal map texture.
|
||||
@objcMembers
|
||||
open class GLTFMaterialNormalTextureInfo: NSObject, Codable {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// The occlusion map texture.
|
||||
@objcMembers
|
||||
open class GLTFMaterialOcclusionTextureInfo: NSObject, Codable {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -149,7 +149,6 @@ import Foundation
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Texture sampler properties for filtering and wrapping modes.
|
||||
@objcMembers
|
||||
open class GLTFSampler: NSObject, Codable {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// The root nodes of a scene.
|
||||
@objcMembers
|
||||
open class GLTFScene: NSObject, Codable {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// Joints and matrices defining a skin.
|
||||
@objcMembers
|
||||
open class GLTFSkin: NSObject, Codable {
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
/// Reference to a texture.
|
||||
@objcMembers
|
||||
open class GLTFTextureInfo: NSObject, Codable {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -344,7 +344,6 @@ public enum GLTF_3D4MCompressedTextureExtensionTarget: Int, RawRepresentable, Co
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Class template
|
||||
open class GLTF_3D4MCompressedTextureExtension: Codable {
|
||||
/// Compression type.
|
||||
|
|
|
@ -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()
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,5 +2,5 @@ import XCTest
|
|||
@testable import gltf_scenekitTests
|
||||
|
||||
XCTMain([
|
||||
testCase(gltf_scenekitTests.allTests),
|
||||
testCase(gltf_scenekitTests.allTests)
|
||||
])
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = (
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue