我很想采用新的Swift语言,因为这似乎是Apple开发的前进方向.我对iOS 8中的新SceneKit支持印象深刻.我想在运行时以编程方式创建自定义几何,但我很难让Swift代码工作.然而,Objective C中的等效代码工作正常.
这可能是一个错误,或者我做错了什么.
我只是想创建并渲染一个三角形.为简单起见,我将忽略法线和纹理等.所以我只期待看到一个黑色的三角形.
Swift代码(不工作)
var verts = [SCNVector3(x: 0,y: 0,z: 0),SCNVector3(x: 1,y: 0,z: 0),SCNVector3(x: 0,y: 1,z: 0)]
let src = SCNGeometrySource(vertices: &verts, count: 3)
let indexes:Int[]=[0,1,2]
let dat = NSData(bytes: indexes, length: sizeofValue(indexes))
let ele = SCNGeometryElement(data:dat, primitiveType: .Triangles, primitiveCount: 1, bytesPerIndex: sizeof(Int))
let geo = SCNGeometry(sources: [src], elements: [ele])
let nd = SCNNode(geometry: geo)
scene.rootNode.addChildNode(nd)
Run Code Online (Sandbox Code Playgroud)
Objective C Code(确实有效)
SCNVector3 verts[] = { SCNVector3Make(0, 0, 0), SCNVector3Make(1, 0, 0), SCNVector3Make(0, 1, 0) };
SCNGeometrySource *src = [SCNGeometrySource geometrySourceWithVertices:verts …Run Code Online (Sandbox Code Playgroud) 我在一个应用程序中运行了一个SKView和一个MTKView,到目前为止一切运行良好.
唯一的问题是,这两种观点在视觉上都很差.他们只是并排.但我想让SKView内部的纯金属渲染与内部的一些SKNode一起移动.它是SKView内部的一种快速显示.
在金属方面运行了相当多的计算和渲染的东西.SKView应该为重型计算提供了一个很好的用户界面,并且为纯金属部件提供了极小但非常快速的渲染.
我已经考虑过将SceneKit与SpriteKit场景叠加使用,因为SCNRenderer提供了使用renderAtTime渲染自己的MTLCommandBuffer和MTLRenderPassDescriptor的可能性.
我实现了以下SCNSceneRendererDelegate方法并调用了我自己的render函数,它正在准备commandBuffer.
func renderer(renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: NSTimeInterval) {
nodeArray.render()
}
Run Code Online (Sandbox Code Playgroud)
在commandBuffer准备好之后,我调用了我的SCNRenderer的renderAtTime方法.试验和错误向我显示命令缓冲区必须在调用renderAtTime后提交.如果我在它崩溃应用之前这样做.如果我不这样做,它将冻结应用程序.
func bufferFinished(renderer:SCNRenderer, commandBuffer: MTLCommandBuffer, renderPassDescriptor: MTLRenderPassDescriptor){
let current=CFAbsoluteTimeGetCurrent()
renderer.renderAtTime(current, viewport: gameView.bounds, commandBuffer: commandBuffer, passDescriptor: renderPassDescriptor)
commandBuffer.commit()
}
Run Code Online (Sandbox Code Playgroud)
如果我这样做,应用程序正在运行,但没有显示其他金属上下文.我认为因为金属部分所以整个事情都很复杂.
是否有任何简单的示例,其中纯金属在SceneKit视图中呈现或更好地在SpriteKit视图中呈现?
在我的项目中,我有一个变换,我想在eulersAngles.
如何从 Swift 语言中x矩阵eulerAngles的变换中获得?44
我至少需要Pitch,我可能需要Yaw,我可能需要Roll。
我正在尝试使用Swift和Scenekit.构建Mac OS X应用程序.让3D场景工作似乎很容易.但是没有某种2D高分,雷达显示,速度指示器等的场景是什么?我希望SpriteKit场景能够无缝集成到SceneView中,但是我没有找到关于这个的文档.
我能想到的最明显和唯一的方法是将SKView放在SceneView上并分别渲染每个.但是有更优雅的方式吗?
我正在将一些Objective-C代码转换为Swift代码,我有以下问题:
Objective-C代码是
SCNNode *textNode = [SCNNode nodeWithGeometry:text];
textNode.transform = CATransform3DInvert(self.chartNode.worldTransform);
Run Code Online (Sandbox Code Playgroud)
这是我试过的转换代码:
let textNode = SCNNode(geometry: text)
textNode.transform = CATransform3DInvert(self.chartNode.worldTransform)
Run Code Online (Sandbox Code Playgroud)
但是,我收到一个错误:'SCNMatrix4无法转换为CATransform3D'
我意识到CATransform3DInvert接受CATransform3D类型的参数,而我包含的参数是SCNMatrix4类型.
我尝试了以下演员尝试:
textNode.transform = CATransform3DInvert(CATransform3D(self.chartNode.worldTransform))
Run Code Online (Sandbox Code Playgroud)
但这不起作用.
然后我发现CATransform3D和SCNMatrix4都是结构体,我不确定如何从一个结构转换到另一个结构(或者甚至可以在Swift中的结构之间进行转换?)
也许还有另一种更简单的方法?
任何帮助将不胜感激 - 谢谢.
所以,我使用SceneKit来渲染一组参数曲面(其总和构成一个对象).为了将这些放在屏幕上,我通过采样点和创建三角形来创建自定义几何.这是我如何做到这一点的快速视图.
Loop through the collection of surfaces
Generate a random color C
For each surface calculate a grid of N x N points (both positions and normals)
Assign all vertexes for that surface the color C
Add groups of 3 vertexes from this surface to the face index list
Run Code Online (Sandbox Code Playgroud)
这似乎有效.在我获得所有这些数据后,我将其转换为正确的结构(SCNGeometrySource和SCNGeometryElement)并制作SCNGeometry,如此
SCNGeometry(sources: [vertexSource, normalSource, colorSource], elements: [element])
Run Code Online (Sandbox Code Playgroud)
这样可以在屏幕上显示我的曲面作为单个几何元素.我的问题是,我有一些非常复杂的对象,我正在尝试使用它,并且在查看对象时移动相机的速度非常慢.渲染大约需要500毫秒.这使我的帧率和体验变得糟糕.
所以问题是,我可以采取哪些步骤来加速SceneKit的性能?我使用具有相同数据量的Three.js的WebGL做了同样的项目,并且能够使用轨道相机很好,所以我无法相信场景套件至少无法与之竞争.我可以调整和关闭哪些功能以加快性能?我使用的是三角形基本类型,轨道相机的allowsCameraControl = true,以及SCNView的金属.
对于那些好奇的人,我正在努力的模型为面部生成231,900个顶点和347,850个索引(11.1312 MB的顶点数据(位置和法线)和1.3914 MB的面部数据(基本上只是顶点的索引位置以便三角形.))
我正在创建并向SceneKit场景添加大量SCNNode,这会导致应用程序冻结一两秒钟.
我以为我可以通过将所有操作放在后台线程中来解决这个问题DispatchQueue.global(qos: .background).async(),但是没有骰子.它的行为完全相同.
我看到了这个答案并SCNView.prepare()在添加节点之前完成了节点,希望它会减慢后台线程并防止阻塞.它没有.
这是一个重现问题的测试函数:
func spawnNodesInBackground() {
// put all the action in a background thread
DispatchQueue.global(qos: .background).async {
var nodes = [SCNNode]()
for i in 0...5000 {
// create a simple SCNNode
let node = SCNNode()
node.position = SCNVector3(i, i, i)
let geometry = SCNSphere(radius: 1)
geometry.firstMaterial?.diffuse.contents = UIColor.white.cgColor
node.geometry = geometry
nodes.append(node)
}
// run the nodes through prepare()
self.mySCNView.prepare(nodes, completionHandler: { (Bool) in
// nodes are prepared, add them to …Run Code Online (Sandbox Code Playgroud) 在我的一个iOS App开发项目中,每当我试图在ARSCNView上推送视图时.应用程序冻结在下面是我的代码.如果您了解相同的解决方案,请建议适当的解决方案.
- >在sceneView控制器上推送视图时让应用程序冻结
let session = ARSession()
var sessionConfig: ARSessionConfiguration = ARWorldTrackingSessionConfiguration()
var use3DOFTracking = false {
didSet {
if use3DOFTracking {
sessionConfig = ARSessionConfiguration()
}
sessionConfig.isLightEstimationEnabled = true
session.run(sessionConfig)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupScene()
setupSession()
}
override func viewWillAppear(_ animated: Bool) {
self.tabBarController?.tabBar.isHidden = false
session.run(sessionConfig, options: [.resetTracking, .removeExistingAnchors])
}
override func viewDidDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
session.pause()
}
func setupScene() {
sceneView.delegate = self
sceneView.session = session
sceneView.antialiasingMode = .multisampling4X
sceneView.automaticallyUpdatesLighting …Run Code Online (Sandbox Code Playgroud) 我注意到如果你有一个空场景,然后用基于物理的光照加载3D模型,那么当对象出现时会有一点点凹凸不平.如果我之后添加一个不同的对象,那就不会发生口吃.
查看分析器,看起来默认的PBR着色器正在第一个慢帧中进行编译.是否可以预编译这些着色器,以便在我第一次渲染模型时不会发生这种情况?
类似的问题已经在其他框架中提出,比如Three.js.似乎是一个聪明的事情要防止.
在我在文档和互联网上阅读之后,我SCNBillboardConstraint会将节点旋转到始终面向pointOfView节点 - 在ARKit用户的相机的情况下.
问题是,当我添加SCNBillboardConstraint到子节点时,它消失了.节点只是SCNTexts添加为更复杂模型的子节点.层次结构如下所示:RootNode - > Text节点(其中两个).
在我将根节点添加到场景的根节点之后,我按以下方式添加此约束:
updateQueue.async {
self.sceneView.scene.rootNode.addChildNode(virtualObject)
self.sceneView.addOrUpdateAnchor(for: virtualObject)
self.addBillboardContraintsToText(object: virtualObject)
}
func addBillboardContraintsToText(object: VirtualObject) {
guard let storeNode = object.childNodes.first else {
return
}
for node in storeNode.childNodes {
if let geometry = node.geometry, geometry.isKind(of: SCNText.self) {
let billboard = SCNBillboardConstraint()
node.constraints = [billboard]
}
}
}
Run Code Online (Sandbox Code Playgroud)
文本节点的位置相对于其根节点设置正确,因此没有问题.当我添加一个,SCNLookAtConstraint但它的工作正常.
node.pivot = SCNMatrix4Rotate(node.pivot, Float.pi, 0, 1, 0)
let lookAt = SCNLookAtConstraint(target: sceneView.pointOfView)
lookAt.isGimbalLockEnabled = true
node.constraints = …Run Code Online (Sandbox Code Playgroud)