SceneKitのSCNGeometryで線を描いた時に色をつけることができない。
下記のソースコード下部のLineクラスのプロパティであるlineNodeをシーンに追加した際に線色を白に指定しているにも関わらず黒く表示されてしまいます。現状どこが間違っているのか見当がつかない状況です。
Lineクラス内のgeometryにmaterialを追加すれば反映されるはずだと思っているのですが、コードを実行した際にそうならないようです。
下記コードはxcodeのGameテンプレートを書き換えたものです。
swift4.2になります。
import UIKit
import SpriteKit
import GameplayKit
import SceneKit
class GameViewController: UIViewController {
var scene:SCNScene!
var selectedNode:SCNNode!
@IBOutlet weak var sceneView: SCNView!
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") {
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
}
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
//まずは基本となるSCNSceneを追加します。これが無いと始まりません
scene = SCNScene()
//SCNNodeを追加しますが、このSCNNodeに物体としてのSCNBoxを作成して関連づけます。
let boxGeometry = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.1)
let boxNode = SCNNode(geometry: boxGeometry)
scene.rootNode.addChildNode(boxNode)
sceneView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
sceneView.center = self.view.center
sceneView.scene = scene
sceneView.autoenablesDefaultLighting = true;
sceneView.allowsCameraControl = true;
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.camera?.zFar = 100
cameraNode.camera?.zNear = 0
scene.rootNode.addChildNode(cameraNode)
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 10)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.objTap(_:)))
sceneView.addGestureRecognizer(tapGesture)
sceneView.backgroundColor = .gray
//lineクラスのテスト
let p1 = SCNVector3(2, 2, 0)
let p2 = SCNVector3(-2, 2, 0)
let p3 = SCNVector3(-2, -2, 0)
let p4 = SCNVector3(2, -2, 0)
let line = Line()
line.addPoint(vector: p1)
line.addPoint(vector: p2)
line.addPoint(vector: p3)
line.addPoint(vector: p4)
line.makeGeometry()
scene.rootNode.addChildNode(line.lineNode)
}
@objc
func objTap(_ gestureRecognize: UIGestureRecognizer){
let p = gestureRecognize.location(in: sceneView)
let hitResults = sceneView.hitTest(p, options: [:])
if hitResults.count > 0 {
let result = hitResults[0]
self.selectedNode = result.node
}
if self.selectedNode != nil{
let sphereGeometry = SCNSphere(radius: 0.2)
self.selectedNode.geometry = sphereGeometry
}
}
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return .allButUpsideDown
} else {
return .all
}
}
override var prefersStatusBarHidden: Bool {
return true
}
}
class Line{
var points: [SCNVector3] = []
var lineNode:SCNNode = SCNNode()
var source:SCNGeometrySource!
var indices: [UInt32]!
var maxPointsNum:Int = 100
func addPoint(vector:SCNVector3){
points.append(vector)
if points.count > self.maxPointsNum{
points.remove(at: 0)
}
}
func makeGeometry(){
source = SCNGeometrySource(vertices: points)
indices = {var rtn = [UInt32]();for i in 0..<points.count-1{rtn += [UInt32(i), UInt32(i+1)]};return rtn}()
let element = SCNGeometryElement(indices: indices, primitiveType: .line)
let geometry = SCNGeometry(sources: [source], elements: [element])
let material = SCNMaterial()
material.diffuse.contents = UIColor.white
geometry.materials = [material]
lineNode.geometry = geometry
}
}