Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SwiftでVRMファイルを表示してみた話

Tatsuya Tanaka
February 28, 2019

 SwiftでVRMファイルを表示してみた話

https://github.com/tattn/VTuberKit
https://github.com/tattn/VRMKit

UnityなしでVRMを読み込んでVTuber機能をアプリに組み込めるライブラリを作りました
https://qiita.com/tattn/items/c2d4505064f78da93ef3

#potatotips 59
https://potatotips.connpass.com/event/119277/

Tatsuya Tanaka

February 28, 2019
Tweet

More Decks by Tatsuya Tanaka

Other Decks in Technology

Transcript

  1. SwiftͰόΠφϦσʔλΛಡΈࠐΉ let data = try Data(contentsOf: url) let version: UInt32

    = data.subdata(in: 0..<4) .withUnsafeBytes { $0.pointee } subdataͰόΠφϦσʔλΛ੾Γग़ͯ͠
 withUnsafeBytesͰద੾ͳσʔλܕͱͯ͠औΓग़͢
  2. Chunk 0ͷJSONΛಡΈࠐΉ let endOffset = offset + Int(length) let jsonData

    = data.subdata(in: offset..<endOffset) let decoder = JSONDecoder() self.jsonData = try decoder.decode(GLTF.self, from: jsonData) JSON෦෼ͷσʔλΛ੾Γग़ͯ͠ɺ
 JSONDecoderʹ౤͛Δ
  3. GLTFܕ public struct GLTF: Codable { let extensionsUsed: [String]? let

    extensionsRequired: [String]? let accessors: [Accessor]? let animations: [Animation]? let asset: Asset let buffers: [Buffer]? let bufferViews: [BufferView]? let cameras: [Camera]? let images: [Image]? let materials: [Material]? let meshes: [Mesh]? let nodes: [Node]? let samplers: [Sampler]? let _scene: Int? var scene: Int { return _scene ?? 0 } let scenes: [Scene]? let skins: [Skin]? let textures: [Texture]? let extensions: Extension? let extras: Extras? private enum CodingKeys: String, CodingKey { case extensionsUsed case extensionsRequired case accessors case animations case asset case buffers case bufferViews case cameras case images case materials case meshes case nodes case samplers case _scene = "scene" case scenes case skins case textures case extensions case extras } } εϥΠυͰ͸঺հ͕೉͍͠ͷͰ
 GitHubͰݟͯͶ IUUQTHJUIVCDPNUBUUO73.,JUCMPCNBTUFS4PVSDFT73.,JU73.(-5'TXJGU
  4. ϝογϡͷ࡞੒ (ൈਮ) let meshNode = SCNNode() for primitive in mesh.primitives

    { // primitive = GLTF.Mesh.Primitive let attributes: [SCNGeometrySource] = <௖఺ɾ๏ઢσʔλͷಡΈࠐΈ> let elements: [SCNGeometryElement] = <௖఺ΠϯσοΫεͷಡΈࠐΈ> let geometry = SCNGeometry(sources: attributes, elements: elements) geometry.materials = <ϚςϦΞϧͷಡΈࠐΈ> let primitiveNode = SCNNode() primitiveNode.geometry = geometry meshNode.addChildNode(primitiveNode) }
  5. ௖఺σʔλͷ࡞੒ (ൈਮ) let buffer = vrm.gltf.binaryBuffer let bufferView = buffer.subdata(in:

    byteOffset..<byteOffset + byteLength) let source = SCNGeometrySource(data: bufferView, semantic: .vertex, vectorCount: accessor.count, usesFloatComponents: true, componentsPerVector: 3, // x, y, z bytesPerComponent: 4, // float dataOffset: accessor.byteOffset, dataStride: 3 * 4)
  6. ීஈ͋·Γ࢖Θͳ͍໘ന͍Ϋϥε SCNGeometrySource = ௖఺΍๏ઢɺϘʔϯͳͲͷσʔλ SCNGeometryElement = ௖఺ΠϯσοΫε SCNMaterial / SCNMaterialProperty

    = ςΫενϟ΍ը૾ͳͲͷσʔλ SCNMorpher = ϞʔϑΟϯά (ද৘ͷมߋ) SCNSkinner = εΩχϯά (ϘʔϯΞχϝʔγϣϯ) CAKeyframeAnimation = ΩʔϑϨʔϜΞχϝʔγϣϯ