import SceneKit类视图控制器:NSViewController,SCNSceneRendererDelegate {覆盖 func viewDidLoad() {super.viewDidLoad()让场景 = SCNScene()让 cameraNode = SCNNode()cameraNode.camera = SCNCamera()cameraNode.camera?.zFar = 1000scene.rootNode.addChildNode(cameraNode)cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)让 scnView = self.view as!SCN视图scnView.scene = 场景scnView.delegate = 自我scnView.allowsCameraControl = truescnView.showsStatistics = truescnView.backgroundColor = NSColor.darkGray功能模型(v01:SCNVector3,v02:SCNVector3,v03:SCNVector3,v04:SCNVector3,v05:SCNVector3,v06:SCNVector3,v07:SCNVector3,v08:SCNVector3,v09:SCNVector3,v10:SCNVector3,v11:SCNVector3,v12:SCNVector3,v13:SCNVector3,v14:SCNVector3,v15:SCNVector3,v16:SCNVector3,v17:SCNVector3,v18: SCNVector3) ->SCN节点{让 polyDraw = draw(vector01: v01,vector02: v02,vector03: v03,vector04: v04,vector05: v05,vector06: v06,vector07: v07,vector08: v08,vector09: v09,向量 10: v10,向量 11: v11,向量12:v12,向量 13: v13,向量 14: v14,向量 15: v15,向量 16: v16,向量 17: v17,向量 18: v18)让材料 = SCNMaterial()material.diffuse.contents = NSColor.greenmaterial.isDoubleSided = truepolyDraw.materials = [材料]让节点 = SCNNode(几何:polyDraw)node.scale = SCNVector3(x: 200, y: 200, z: 200)场景.rootNode.addChildNode(节点)返回节点}func draw(vector01: SCNVector3,vector02: SCNVector3,vector03: SCNVector3,vector04: SCNVector3,vector05: SCNVector3,vector06: SCNVector3,vector07: SCNVector3,vector08: SCNVector3,vector09: SCNVector3,向量10:SCNVector3,vector11: SCNVector3,vector12: SCNVector3,vector13: SCNVector3,vector14: SCNVector3,vector15: SCNVector3,vector16: SCNVector3,vector17: SCNVector3,vector18: SCNVector3) ->SCNGeometry {让 normalsPerFace = 1让索引: [Int32] = [18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10、11、12、13、14、15、16、17]让源 = SCNGeometrySource(vertices: [vector01,矢量02,矢量03,矢量04,矢量05,矢量06,矢量07,矢量08,矢量09,向量10,向量11,矢量12,矢量13,矢量14,矢量15,矢量16,矢量17,矢量18])让 vec = [vector01, vector02, vector03,矢量04, 矢量05, 矢量06,矢量07, 矢量08, 矢量09,向量10、向量11、向量12、矢量13, 矢量14, 矢量15,vector16, vector17, vector18].map { [SCNVector3](重复:$0,计数:normalsPerFace) }.flatMap{ $0 }让法线:[SCNVector3] = vec让 normalSource = SCNGeometrySource(normals: normals)让 point01 = CGPoint(x: CGFloat(vector01.x), y: CGFloat(vector01.y))让 point02 = CGPoint(x: CGFloat(vector02.x), y: CGFloat(vector02.y))让 point03 = CGPoint(x: CGFloat(vector03.x), y: CGFloat(vector03.y))让 point04 = CGPoint(x: CGFloat(vector04.x), y: CGFloat(vector04.y))让 point05 = CGPoint(x: CGFloat(vector05.x), y: CGFloat(vector05.y))让 point06 = CGPoint(x: CGFloat(vector06.x), y: CGFloat(vector06.y))让 point07 = CGPoint(x: CGFloat(vector07.x), y: CGFloat(vector07.y))让 point08 = CGPoint(x: CGFloat(vector08.x), y: CGFloat(vector08.y))让 point09 = CGPoint(x: CGFloat(vector09.x), y: CGFloat(vector09.y))让 point10 = CGPoint(x: CGFloat(vector10.x), y: CGFloat(vector10.y))让 point11 = CGPoint(x: CGFloat(vector11.x), y: CGFloat(vector11.y))让 point12 = CGPoint(x: CGFloat(vector12.x), y: CGFloat(vector12.y))让 point13 = CGPoint(x: CGFloat(vector13.x), y: CGFloat(vector13.y))让 point14 = CGPoint(x: CGFloat(vector14.x), y: CGFloat(vector14.y))让 point15 = CGPoint(x: CGFloat(vector15.x), y: CGFloat(vector15.y))让 point16 = CGPoint(x: CGFloat(vector16.x), y: CGFloat(vector16.y))让 point17 = CGPoint(x: CGFloat(vector17.x), y: CGFloat(vector17.y))让 point18 = CGPoint(x: CGFloat(vector18.x), y: CGFloat(vector18.y))让 texCoord = SCNGeometrySource(textureCoordinates:[point01, point02, point03, point04, point05, point06,point07, point08, point09, point10, point11, point12,点 13、点 14、点 15、点 16、点 17、点 18])让数据 = 数据(字节:索引,计数:indices.count * MemoryLayout.size)让元素 = SCNGeometryElement(数据:数据,原始类型:.polygon,原始数量:1,bytesPerIndex: MemoryLayout.size)让几何 = SCNGeometry(来源:[来源,正常来源,texCoord],元素:[元素])返回几何}_ = 模型(v01:SCNVector3(x:0.08866002,y:-0.00773552,z:-0.09841499),v02:SCNVector3(x:0.08873053,y:-0.01492687,z:-0.09837532),v03:SCNVector3(x:0.08873053,y:-0.01492687,z:-0.09837532),v04:SCNVector3(x:0.08846086,y:-0.02434851,z:-0.09852711),v05:SCNVector3(x:0.08749959,y:-0.03475155,z:-0.09906833),v06: SCNVector3(x: 0.08527064, y: -0.04331201, z: -0.10032329),v07:SCNVector3(x:0.08125973,y:-0.04962304,z:-0.10258152),v08:SCNVector3(x:0.07674095,y:-0.05456349,z:-0.10512567),v09:SCNVector3(x:0.07041831,y:-0.05790819,z:-0.10868551),v10:SCNVector3(x:0.06373097,y:-0.05820452,z:-0.11245064),v11:SCNVector3(x:0.05844573,y:-0.05779012,z:-0.11542635),v12: SCNVector3(x: 0.05448552, y: -0.05334358, z: -0.11765605),v13: SCNVector3(x: 0.05290238, y: -0.04610482, z: -0.11854740),v14:SCNVector3(x:0.05353430,y:-0.03637475,z:-0.11819161),v15:SCNVector3(x:0.05589097,y:-0.02788102,z:-0.11686475),v16: SCNVector3(x: 0.05910149, y: -0.02275178, z: -0.11505718),v17: SCNVector3(x: 0.06234538, y: -0.02150976, z: -0.11323079),v18: SCNVector3(x: 0.06506948, y: -0.02217681, z: -0.11169703))}}有用信息:在 3D 图形中,处理多边形几何的最佳和最可预测的方法是最初使用三边(三角形)和四边(四边形)面.有时,在极少数情况下,您可以使用五个面,但这可能会导致您产生阴影伪影.P.S. camera.zFar 适用于 ARKit.让 currentFrame = sceneView.session.currentFrame让节点 = SCNNode()node.camera = SCNCamera()var 翻译 = matrix_identity_float4x4translation.columns.3.z = -0.1/* 10 cm */node.simdTransform = matrix_multiply((currentFrame?.camera.transform)!,翻译)node.camera?.zFar = 1000/* 设置不超过1000米 */I'm trying to create a custom SCNGeometry in the form of a plane with custom shape, which could be placed in an ARKit session. I'm using the option SCNGeometryPrimitiveTypePolygon in the following method which seems to work fine: extension SCNGeometry { static func polygonPlane(vertices: [SCNVector3]) -> SCNGeometry { var indices: [Int32] = [Int32(vertices.count)] var index: Int32 = 0 for _ in vertices { indices.append(index) index += 1 } let vertexSource = SCNGeometrySource(vertices: vertices) let indexData = Data(bytes: indices, count: indices.count * MemoryLayout<Int32>.size) let element = SCNGeometryElement(data: indexData, primitiveType: .polygon, primitiveCount: 1, bytesPerIndex: MemoryLayout<Int32>.size) let geometry = SCNGeometry(sources: [vertexSource], elements: [element]) let material = SCNMaterial() material.diffuse.contents = UIColor.blue material.isDoubleSided = true geometry.firstMaterial = material return geometry }After creating this geometry I assign it to a SCNNode:s .geometry property and add it to my AR scene as usual: let geometry = SCNGeometry.polygonPlane(vertices: verticesArray)let node = SCNNode(geometry: geometry)sceneView.scene.rootNode.addChildNode(node)This works well for some types of plane shapes. However I often get a crash, mostly when using complex shapes or many vertices to outline the plane shape. I've experimented and it seems as the geometry is created as expected without any errors, but the error occurs when the node is added to the scene and about to be rendered. This is the printed error: -[MTLDebugDevice validateNewBufferArgs:options:]:467: failed assertion `Cannot create buffer of zero length.'What appears in the debug navigator:And finally the stack trace:* thread #17, name = 'com.apple.scenekit.scnview-renderer', queue = 'com.apple.scenekit.renderingQueue.ARSCNView0x11be03ed0', stop reason = signal SIGABRT * frame #0: 0x0000000219cad0cc libsystem_kernel.dylib`__pthread_kill + 8 frame #1: 0x0000000219d23a88 libsystem_pthread.dylib`pthread_kill + 300 frame #2: 0x0000000219c0614c libsystem_c.dylib`abort + 144 frame #3: 0x0000000219bd3274 libsystem_c.dylib`__assert_rtn + 224 frame #4: 0x000000021c28e23c Metal`MTLReportFailure + 528 frame #5: 0x000000023f984108 MetalTools`-[MTLDebugDevice validateNewBufferArgs:options:] + 172 frame #6: 0x000000023f98430c MetalTools`-[MTLDebugDevice newBufferWithBytes:length:options:] + 128 frame #7: 0x000000022e323b48 SceneKit`-[SCNMTLResourceManager _bufferForData:bytesPerIndex:] + 404 frame #8: 0x000000022e323f14 SceneKit`-[SCNMTLResourceManager renderResourceForMeshElement:] + 416 frame #9: 0x000000022e3243c0 SceneKit`-[SCNMTLResourceManager renderResourceForMesh:dataKind:] + 692 frame #10: 0x000000022e364980 SceneKit`_execute(SCNMTLRenderContext*, DrawCommand) + 916 frame #11: 0x000000022e3644a0 SceneKit`-[SCNMTLRenderContext drawRenderElement:withPass:] + 608 frame #12: 0x000000022e3630d4 SceneKit`-[SCNMTLRenderContext processRendererElements:count:engineIterationContext:] + 1044 frame #13: 0x000000022e4afc54 SceneKit`C3D::DrawNodesPass::_renderEye(long) + 472 frame #14: 0x000000022e4afa00 SceneKit`C3D::DrawNodesPass::execute(C3D::RenderArgs const&) + 260 frame #15: 0x000000022e54a1b4 SceneKit`C3D::MainPass::execute(C3D::RenderArgs const&) + 176 frame #16: 0x000000022e318904 SceneKit`C3D::__renderSlice(C3D::RenderGraph*, C3D::RenderPass*, unsigned short&, C3D::RenderGraph::GraphNode const&, C3D::RenderGraph::Stage*&, C3D::RenderArgs) + 1156 frame #17: 0x000000022e319cd0 SceneKit`C3D::RenderGraph::execute() + 3896 frame #18: 0x000000022e42fd8c SceneKit`-[SCNRenderer _renderSceneWithEngineContext:sceneTime:] + 2364 frame #19: 0x000000022e42ff44 SceneKit`-[SCNRenderer _drawSceneWithNewRenderer:] + 312 frame #20: 0x000000022e43056c SceneKit`-[SCNRenderer _drawScene:] + 72 frame #21: 0x000000022e4309bc SceneKit`-[SCNRenderer _drawAtTime:] + 760 frame #22: 0x000000022e4dfecc SceneKit`-[SCNView _drawAtTime:] + 492 frame #23: 0x000000022e37c15c SceneKit`__69-[NSObject(SCN_DisplayLinkExtensions) SCN_setupDisplayLinkWithQueue:]_block_invoke + 60 frame #24: 0x000000022e4a1c50 SceneKit`__36-[SCNDisplayLink _callbackWithTime:]_block_invoke + 88 frame #25: 0x0000000104d74778 libdispatch.dylib`_dispatch_client_callout + 20 frame #26: 0x0000000104d82fc0 libdispatch.dylib`_dispatch_lane_barrier_sync_invoke_and_complete + 160 frame #27: 0x000000022e4a1bb8 SceneKit`-[SCNDisplayLink _callbackWithTime:] + 268 frame #28: 0x0000000104e082d4 GPUToolsCore`-[DYDisplayLinkInterposer forwardDisplayLinkCallback:] + 204 frame #29: 0x000000021e53aea8 QuartzCore`CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 632 frame #30: 0x000000021e608858 QuartzCore`display_timer_callback(__CFMachPort*, void*, long, void*) + 276 frame #31: 0x000000021a083058 CoreFoundation`__CFMachPortPerform + 192 frame #32: 0x000000021a0aaaf0 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 60 frame #33: 0x000000021a0aa1e8 CoreFoundation`__CFRunLoopDoSource1 + 444 frame #34: 0x000000021a0a4d80 CoreFoundation`__CFRunLoopRun + 2060 frame #35: 0x000000021a0a4254 CoreFoundation`CFRunLoopRunSpecific + 452 frame #36: 0x000000021aa8404c Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304 frame #37: 0x000000022e37c518 SceneKit`__49-[SCNView(SCNDisplayLink) _initializeDisplayLink]_block_invoke + 444 frame #38: 0x000000022e37c684 SceneKit`__SCNRenderThread_start__ + 104 frame #39: 0x0000000219d22908 libsystem_pthread.dylib`_pthread_body + 132 frame #40: 0x0000000219d22864 libsystem_pthread.dylib`_pthread_start + 48 frame #41: 0x0000000219d2adcc libsystem_pthread.dylib`thread_start + 4warning: failed to set breakpoint site at 0x21931425c for breakpoint -4.1: error sending the breakpoint requestwarning: failed to set breakpoint site at 0x219314530 for breakpoint -4.2: error sending the breakpoint requestwarning: failed to set breakpoint site at 0x2193141b4 for breakpoint -4.3: error sending the breakpoint requestwarning: failed to set breakpoint site at 0x21931fcc4 for breakpoint -5.1: error sending the breakpoint requestI'm not experienced in debugging in swift but it seems to me the problem occurs somewhere in frame #4-6 within some metal-framework code: frame #4: 0x000000021c28e23c Metal`MTLReportFailure + 528 frame #5: 0x000000023f984108 MetalTools`-[MTLDebugDevice validateNewBufferArgs:options:] + 172 frame #6: 0x000000023f98430c MetalTools`-[MTLDebugDevice newBufferWithBytes:length:options:] + 128Thankful for any help/suggestions!---- EDIT 1 ----Here is an array which does not generate this error:vertices = [ //Array that should work SCNVector3(x: -0.06110339, y: -0.00659544, z: -0.18046863), SCNVector3(x: -0.06406027, y: -0.008907169, z: -0.18053372), SCNVector3(x: -0.06406027, y: -0.008907169, z: -0.18053372), SCNVector3(x: -0.06701318, y: -0.013257578, z: -0.18059872), SCNVector3(x: -0.069427274, y: -0.017816536, z: -0.18065183), SCNVector3(x: -0.07077661, y: -0.02299612, z: -0.18068156), SCNVector3(x: -0.07138735, y: -0.029295363, z: -0.18069498), SCNVector3(x: -0.07159121, y: -0.035330035, z: -0.1806995), SCNVector3(x: -0.06850778, y: -0.039139934, z: -0.1806316), SCNVector3(x: -0.059540674, y: -0.039537176, z: -0.18043421), SCNVector3(x: -0.04808737, y: -0.035914123, z: -0.1801821), SCNVector3(x: -0.045074403, y: -0.035180397, z: -0.1801158) ]Here are two screenshots from my app when using this array. As you can see the polygon lies within the plane since all vertex positions are picked from a hit test on that plane. Don't mind the clipping colors since it's due to z-fighting and can easily be fixed by offsetting the planes:Here is an example of a vertices array which generates this error:vertices = [ //Array that should not work SCNVector3(x: 0.08866002, y: -0.007735528, z: -0.09841499), SCNVector3(x: 0.08873053, y: -0.014926873, z: -0.09837532), SCNVector3(x: 0.08873053, y: -0.014926873, z: -0.09837532), SCNVector3(x: 0.08846086, y: -0.024348512, z: -0.09852711), SCNVector3(x: 0.08749959, y: -0.034751557, z: -0.09906833), SCNVector3(x: 0.08527064, y: -0.043312013, z: -0.10032329), SCNVector3(x: 0.08125973, y: -0.049623042, z: -0.10258152), SCNVector3(x: 0.07674095, y: -0.054563493, z: -0.10512567), SCNVector3(x: 0.07041831, y: -0.057908192, z: -0.10868551), SCNVector3(x: 0.06373097, y: -0.058204524, z: -0.112450644), SCNVector3(x: 0.058445737, y: -0.057790123, z: -0.115426354), SCNVector3(x: 0.054485526, y: -0.05334358, z: -0.11765605), SCNVector3(x: 0.052902386, y: -0.04610482, z: -0.1185474), SCNVector3(x: 0.053534307, y: -0.036374755, z: -0.118191615), SCNVector3(x: 0.055890974, y: -0.027881026, z: -0.11686475), SCNVector3(x: 0.059101492, y: -0.022751786, z: -0.115057185), SCNVector3(x: 0.062345386, y: -0.02150976, z: -0.113230795), SCNVector3(x: 0.06506948, y: -0.022176817, z: -0.11169703) ]And here is a screenshot from when using that array. The blue planes are instances when the method worked, but if you look closely there is a red line. This red line is following the vertices of the bad array above, which crashes the app instantly when the polygon plane using the corresponding geometry is added to the scene:---- EDIT 2 ----Below is the code for @ARGeo's macOS solution, but slightly modified to fit my iOS app and to use an arbitrary amount of vertices. The code works for the vertices array that previously failed but fails again when using another vertices array. Like @ARGeo proposed I made sure to place this method inside of the actual class and not in an extension in case MemoryLayout<Int32>.size is causing the issue when used inside an extension.private func createPolygon(){ func model(vertices: [SCNVector3]) -> SCNNode { let polyDraw = draw(vertices: vertices) let material = SCNMaterial() material.diffuse.contents = UIColor.green material.isDoubleSided = true material.diffuse.contentsTransform = .init(m11: 0.1, m12: 0, m13: 0, m14: 0, m21: 0, m22: 0.1, m23: 0, m24: 0, m31: 0, m32: 0, m33: 0, m34: 0, m41: 0, m42: 0, m43: 0, m44: 1) material.diffuse.wrapS = .repeat material.diffuse.wrapT = .repeat polyDraw.materials = [material] let node = SCNNode(geometry: polyDraw) //node.scale = SCNVector3(x: 200, y: 200, z: 200) sceneView.scene.rootNode.addChildNode(node) return node } func draw(vertices: [SCNVector3]) -> SCNGeometry { let normalsPerFace = 1 var indices: [Int32] = [] indices.append(Int32(vertices.count)) //Add the rest of the indices 0 to vertices.count-1 for i in 0 ... vertices.count-1 { indices.append(Int32(i)) } let source = SCNGeometrySource(vertices: vertices) let vec = vertices.map { [SCNVector3](repeating: $0, count: normalsPerFace) }.flatMap{ $0 } let normals: [SCNVector3] = vec let normalSource = SCNGeometrySource(normals: normals) var cgps: [CGPoint] = [] vertices.forEach { (vertex) in cgps.append(CGPoint(x: CGFloat(vertex.x), y: CGFloat(vertex.y))) } let textcoord = SCNGeometrySource(textureCoordinates: cgps) let data = Data(bytes: indices, count: indices.count * MemoryLayout<Int32>.size) let element = SCNGeometryElement(data: data, primitiveType: .polygon, primitiveCount: 1, bytesPerIndex: MemoryLayout<Int32>.size) return SCNGeometry(sources: [source, normalSource, textcoord], elements: [element]) } //Previous fail, now success with ARGeo's code let vertices = [SCNVector3(x: 0.08866002, y: -0.00773552, z: -0.09841499), SCNVector3(x: 0.08873053, y: -0.01492687, z: -0.09837532), SCNVector3(x: 0.08873053, y: -0.01492687, z: -0.09837532), SCNVector3(x: 0.08846086, y: -0.02434851, z: -0.09852711), SCNVector3(x: 0.08749959, y: -0.03475155, z: -0.09906833), SCNVector3(x: 0.08527064, y: -0.04331201, z: -0.10032329), SCNVector3(x: 0.08125973, y: -0.04962304, z: -0.10258152), SCNVector3(x: 0.07674095, y: -0.05456349, z: -0.10512567), SCNVector3(x: 0.07041831, y: -0.05790819, z: -0.10868551), SCNVector3(x: 0.06373097, y: -0.05820452, z: -0.11245064), SCNVector3(x: 0.05844573, y: -0.05779012, z: -0.11542635), SCNVector3(x: 0.05448552, y: -0.05334358, z: -0.11765605), SCNVector3(x: 0.05290238, y: -0.04610482, z: -0.11854740), SCNVector3(x: 0.05353430, y: -0.03637475, z: -0.11819161), SCNVector3(x: 0.05589097, y: -0.02788102, z: -0.11686475), SCNVector3(x: 0.05910149, y: -0.02275178, z: -0.11505718), SCNVector3(x: 0.06234538, y: -0.02150976, z: -0.11323079), SCNVector3(x: 0.06506948, y: -0.02217681, z: -0.11169703) ] _ = model(vertices: vertices)}Example of vertices array for which the code above fails:vertices = [ SCNVector3(x: 0.08291423, y: -0.08406013, z: -0.60201955), SCNVector3(x: 0.077855, y: -0.083336316, z: -0.60234916), SCNVector3(x: 0.077855, y: -0.083336316, z: -0.60234916), SCNVector3(x: 0.06817482, y: -0.08799789, z: -0.6029798), SCNVector3(x: 0.055873748, y: -0.09737456, z: -0.6037812), SCNVector3(x: 0.042388167, y: -0.108595274, z: -0.60465986), SCNVector3(x: 0.031522393, y: -0.119523935, z: -0.6053677), SCNVector3(x: 0.024102041, y: -0.13026507, z: -0.6058511), SCNVector3(x: 0.021609604, y: -0.13820335, z: -0.6060136), SCNVector3(x: 0.022751667, y: -0.14294992, z: -0.60593915), SCNVector3(x: 0.025871918, y: -0.14491153, z: -0.6057359), SCNVector3(x: 0.0338943, y: -0.14688163, z: -0.6052132), SCNVector3(x: 0.041132875, y: -0.15027393, z: -0.60474163), SCNVector3(x: 0.047307685, y: -0.15410759, z: -0.6043393), SCNVector3(x: 0.054541387, y: -0.1566292, z: -0.603868), SCNVector3(x: 0.06140149, y: -0.15919833, z: -0.60342115), SCNVector3(x: 0.06551884, y: -0.16264887, z: -0.6031529) ]---- EDIT 3 ----Okay so I made a macOS version for the code above (which is the solution @ARGeo proposed but with some minor changes, like using an arbitrary amount of vertices) which does not crash when using the above array, even though the iOS code version does. However nothing is rendered and I'm not getting any error messages which I don't know the reason for. When adding the line cameraNode.camera?.zFar = 1000 in case It's not visible due to clipping, the program crashes instead, giving a new error. It does not crash if zFar is small enough (tested with zFar < 10), in which case the polygon is not rendered either. The error print is the same -[MTLDebugDevice validateNewBufferArgs:options:]:467: failed assertion 'Cannot create buffer of zero length.' but the debug navigator shows this:and the stack trace's final rows are this:* thread #8, name = 'CVDisplayLink', queue = 'com.apple.scenekit.renderingQueue.SCNView0x101306480', stop reason = signal SIGABRT * frame #0: 0x00007fff671b62c6 libsystem_kernel.dylib`__pthread_kill + 10 frame #1: 0x000000010053680d libsystem_pthread.dylib`pthread_kill + 284 frame #2: 0x00007fff671206a6 libsystem_c.dylib`abort + 127 frame #3: 0x00007fff670e920d libsystem_c.dylib`__assert_rtn + 324 frame #4: 0x00007fff3fd1b68e Metal`MTLReportFailure + 567 frame #5: 0x00007fff599f9d98 MetalTools`-[MTLDebugDevice validateNewBufferArgs:options:] + 207 frame #6: 0x00007fff599f9f28 MetalTools`-[MTLDebugDevice newBufferWithBytes:length:options:] + 107 frame #7: 0x00007fff462f265b SceneKit`-[SCNMTLResourceManager _bufferForData:bytesPerIndex:] + 414 frame #8: 0x00007fff462f29e0Here is the code which is used if you want to try it out yourself. Just copy and paste into macOS project:import SceneKitimport QuartzCoreclass GameViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() let scene = SCNScene() let cameraNode = SCNNode() cameraNode.camera = SCNCamera() scene.rootNode.addChildNode(cameraNode) cameraNode.position = SCNVector3(x: 0, y: 0, z: 15) // This line crashes the app! But w/o it the polygon plane would probably clip and be invisible. cameraNode.camera?.zFar = 1000 let ambientLightNode = SCNNode() ambientLightNode.light = SCNLight() ambientLightNode.light!.type = .ambient ambientLightNode.light!.intensity = 10000 ambientLightNode.light!.color = NSColor.darkGray scene.rootNode.addChildNode(ambientLightNode) func model(vertices: [SCNVector3]) -> SCNNode { let polyDraw = draw(vertices: vertices) let material = SCNMaterial() material.diffuse.contents = NSColor.green material.isDoubleSided = true material.diffuse.contentsTransform = .init(m11: 0.1, m12: 0, m13: 0, m14: 0, m21: 0, m22: 0.1, m23: 0, m24: 0, m31: 0, m32: 0, m33: 0, m34: 0, m41: 0, m42: 0, m43: 0, m44: 1) material.diffuse.wrapS = .repeat material.diffuse.wrapT = .repeat polyDraw.materials = [material] let node = SCNNode(geometry: polyDraw) node.scale = SCNVector3(x: 200, y: 200, z: 200) scene.rootNode.addChildNode(node) return node } func draw(vertices: [SCNVector3]) -> SCNGeometry { let normalsPerFace = 1 var indices: [Int32] = [] indices.append(Int32(vertices.count)) //Add the rest of the indices 0 to vertices.count-1 for i in 0 ... vertices.count-1 { indices.append(Int32(i)) } let source = SCNGeometrySource(vertices: vertices) let vec = vertices.map { [SCNVector3](repeating: $0, count: normalsPerFace) }.flatMap{ $0 } let normals: [SCNVector3] = vec let normalSource = SCNGeometrySource(normals: normals) var cgps: [CGPoint] = [] vertices.forEach { (vertex) in cgps.append(CGPoint(x: CGFloat(vertex.x), y: CGFloat(vertex.y))) } let textcoord = SCNGeometrySource(textureCoordinates: cgps) let data = Data(bytes: indices, count: indices.count * MemoryLayout<Int32>.size) let element = SCNGeometryElement(data: data, primitiveType: .polygon, primitiveCount: 1, bytesPerIndex: MemoryLayout<Int32>.size) return SCNGeometry(sources: [source, normalSource, textcoord], elements: [element]) } //Previous fail, now success with ARGeo's code// let vertices = [SCNVector3(x: 0.08866002, y: -0.00773552, z: -0.09841499),// SCNVector3(x: 0.08873053, y: -0.01492687, z: -0.09837532),// SCNVector3(x: 0.08873053, y: -0.01492687, z: -0.09837532),// SCNVector3(x: 0.08846086, y: -0.02434851, z: -0.09852711),// SCNVector3(x: 0.08749959, y: -0.03475155, z: -0.09906833),// SCNVector3(x: 0.08527064, y: -0.04331201, z: -0.10032329),// SCNVector3(x: 0.08125973, y: -0.04962304, z: -0.10258152),// SCNVector3(x: 0.07674095, y: -0.05456349, z: -0.10512567),// SCNVector3(x: 0.07041831, y: -0.05790819, z: -0.10868551),// SCNVector3(x: 0.06373097, y: -0.05820452, z: -0.11245064),// SCNVector3(x: 0.05844573, y: -0.05779012, z: -0.11542635),// SCNVector3(x: 0.05448552, y: -0.05334358, z: -0.11765605),// SCNVector3(x: 0.05290238, y: -0.04610482, z: -0.11854740),// SCNVector3(x: 0.05353430, y: -0.03637475, z: -0.11819161),// SCNVector3(x: 0.05589097, y: -0.02788102, z: -0.11686475),// SCNVector3(x: 0.05910149, y: -0.02275178, z: -0.11505718),// SCNVector3(x: 0.06234538, y: -0.02150976, z: -0.11323079),// SCNVector3(x: 0.06506948, y: -0.02217681, z: -0.11169703)// ] //Array which fails when the cameras zFar property //is too big (>10 or something). //If zFar is small enough it does not crash, //but then nothing is rendered. let vertices = [ SCNVector3(x: 0.08291423, y: -0.08406013, z: -0.60201955), SCNVector3(x: 0.077855, y: -0.083336316, z: -0.60234916), SCNVector3(x: 0.077855, y: -0.083336316, z: -0.60234916), SCNVector3(x: 0.06817482, y: -0.08799789, z: -0.6029798), SCNVector3(x: 0.055873748, y: -0.09737456, z: -0.6037812), SCNVector3(x: 0.042388167, y: -0.108595274, z: -0.60465986), SCNVector3(x: 0.031522393, y: -0.119523935, z: -0.6053677), SCNVector3(x: 0.024102041, y: -0.13026507, z: -0.6058511), SCNVector3(x: 0.021609604, y: -0.13820335, z: -0.6060136), SCNVector3(x: 0.022751667, y: -0.14294992, z: -0.60593915), SCNVector3(x: 0.025871918, y: -0.14491153, z: -0.6057359), SCNVector3(x: 0.0338943, y: -0.14688163, z: -0.6052132), SCNVector3(x: 0.041132875, y: -0.15027393, z: -0.60474163), SCNVector3(x: 0.047307685, y: -0.15410759, z: -0.6043393), SCNVector3(x: 0.054541387, y: -0.1566292, z: -0.603868), SCNVector3(x: 0.06140149, y: -0.15919833, z: -0.60342115), SCNVector3(x: 0.06551884, y: -0.16264887, z: -0.6031529) ] _ = model(vertices: vertices) let scnView = self.view as! SCNView scnView.scene = scene scnView.allowsCameraControl = true scnView.showsStatistics = true scnView.backgroundColor = NSColor.darkGray }}I have no idea what is causing this issue, as it seems to be some internal rendering going wrong. I'm also not very experienced with debugging so I would appreciate any help as I'm unable to make any further sense of this. 解决方案 SOLUTION (Copy-paste this macOS app code for testing in ViewController.swift):import SceneKitclass ViewController: NSViewController, SCNSceneRendererDelegate { override func viewDidLoad() { super.viewDidLoad() let scene = SCNScene() let cameraNode = SCNNode() cameraNode.camera = SCNCamera() cameraNode.camera?.zFar = 1000 scene.rootNode.addChildNode(cameraNode) cameraNode.position = SCNVector3(x: 0, y: 0, z: 15) let scnView = self.view as! SCNView scnView.scene = scene scnView.delegate = self scnView.allowsCameraControl = true scnView.showsStatistics = true scnView.backgroundColor = NSColor.darkGray func model( v01: SCNVector3, v02: SCNVector3, v03: SCNVector3, v04: SCNVector3, v05: SCNVector3, v06: SCNVector3, v07: SCNVector3, v08: SCNVector3, v09: SCNVector3, v10: SCNVector3, v11: SCNVector3, v12: SCNVector3, v13: SCNVector3, v14: SCNVector3, v15: SCNVector3, v16: SCNVector3, v17: SCNVector3, v18: SCNVector3) -> SCNNode { let polyDraw = draw(vector01: v01, vector02: v02, vector03: v03, vector04: v04, vector05: v05, vector06: v06, vector07: v07, vector08: v08, vector09: v09, vector10: v10, vector11: v11, vector12: v12, vector13: v13, vector14: v14, vector15: v15, vector16: v16, vector17: v17, vector18: v18) let material = SCNMaterial() material.diffuse.contents = NSColor.green material.isDoubleSided = true polyDraw.materials = [material] let node = SCNNode(geometry: polyDraw) node.scale = SCNVector3(x: 200, y: 200, z: 200) scene.rootNode.addChildNode(node) return node } func draw(vector01: SCNVector3, vector02: SCNVector3, vector03: SCNVector3, vector04: SCNVector3, vector05: SCNVector3, vector06: SCNVector3, vector07: SCNVector3, vector08: SCNVector3, vector09: SCNVector3, vector10: SCNVector3, vector11: SCNVector3, vector12: SCNVector3, vector13: SCNVector3, vector14: SCNVector3, vector15: SCNVector3, vector16: SCNVector3, vector17: SCNVector3, vector18: SCNVector3) -> SCNGeometry { let normalsPerFace = 1 let indices: [Int32] = [18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] let source = SCNGeometrySource(vertices: [vector01, vector02, vector03, vector04, vector05, vector06, vector07, vector08, vector09, vector10, vector11, vector12, vector13, vector14, vector15, vector16, vector17, vector18]) let vec = [vector01, vector02, vector03, vector04, vector05, vector06, vector07, vector08, vector09, vector10, vector11, vector12, vector13, vector14, vector15, vector16, vector17, vector18].map { [SCNVector3](repeating: $0, count: normalsPerFace) }.flatMap{ $0 } let normals: [SCNVector3] = vec let normalSource = SCNGeometrySource(normals: normals) let point01 = CGPoint(x: CGFloat(vector01.x), y: CGFloat(vector01.y)) let point02 = CGPoint(x: CGFloat(vector02.x), y: CGFloat(vector02.y)) let point03 = CGPoint(x: CGFloat(vector03.x), y: CGFloat(vector03.y)) let point04 = CGPoint(x: CGFloat(vector04.x), y: CGFloat(vector04.y)) let point05 = CGPoint(x: CGFloat(vector05.x), y: CGFloat(vector05.y)) let point06 = CGPoint(x: CGFloat(vector06.x), y: CGFloat(vector06.y)) let point07 = CGPoint(x: CGFloat(vector07.x), y: CGFloat(vector07.y)) let point08 = CGPoint(x: CGFloat(vector08.x), y: CGFloat(vector08.y)) let point09 = CGPoint(x: CGFloat(vector09.x), y: CGFloat(vector09.y)) let point10 = CGPoint(x: CGFloat(vector10.x), y: CGFloat(vector10.y)) let point11 = CGPoint(x: CGFloat(vector11.x), y: CGFloat(vector11.y)) let point12 = CGPoint(x: CGFloat(vector12.x), y: CGFloat(vector12.y)) let point13 = CGPoint(x: CGFloat(vector13.x), y: CGFloat(vector13.y)) let point14 = CGPoint(x: CGFloat(vector14.x), y: CGFloat(vector14.y)) let point15 = CGPoint(x: CGFloat(vector15.x), y: CGFloat(vector15.y)) let point16 = CGPoint(x: CGFloat(vector16.x), y: CGFloat(vector16.y)) let point17 = CGPoint(x: CGFloat(vector17.x), y: CGFloat(vector17.y)) let point18 = CGPoint(x: CGFloat(vector18.x), y: CGFloat(vector18.y)) let texCoord = SCNGeometrySource(textureCoordinates: [point01, point02, point03, point04, point05, point06, point07, point08, point09, point10, point11, point12, point13, point14, point15, point16, point17, point18]) let data = Data(bytes: indices, count: indices.count * MemoryLayout<Int32>.size) let element = SCNGeometryElement(data: data, primitiveType: .polygon, primitiveCount: 1, bytesPerIndex: MemoryLayout<Int32>.size) let geometry = SCNGeometry(sources: [source, normalSource, texCoord], elements: [element]) return geometry } _ = model(v01: SCNVector3(x: 0.08866002, y: -0.00773552, z: -0.09841499), v02: SCNVector3(x: 0.08873053, y: -0.01492687, z: -0.09837532), v03: SCNVector3(x: 0.08873053, y: -0.01492687, z: -0.09837532), v04: SCNVector3(x: 0.08846086, y: -0.02434851, z: -0.09852711), v05: SCNVector3(x: 0.08749959, y: -0.03475155, z: -0.09906833), v06: SCNVector3(x: 0.08527064, y: -0.04331201, z: -0.10032329), v07: SCNVector3(x: 0.08125973, y: -0.04962304, z: -0.10258152), v08: SCNVector3(x: 0.07674095, y: -0.05456349, z: -0.10512567), v09: SCNVector3(x: 0.07041831, y: -0.05790819, z: -0.10868551), v10: SCNVector3(x: 0.06373097, y: -0.05820452, z: -0.11245064), v11: SCNVector3(x: 0.05844573, y: -0.05779012, z: -0.11542635), v12: SCNVector3(x: 0.05448552, y: -0.05334358, z: -0.11765605), v13: SCNVector3(x: 0.05290238, y: -0.04610482, z: -0.11854740), v14: SCNVector3(x: 0.05353430, y: -0.03637475, z: -0.11819161), v15: SCNVector3(x: 0.05589097, y: -0.02788102, z: -0.11686475), v16: SCNVector3(x: 0.05910149, y: -0.02275178, z: -0.11505718), v17: SCNVector3(x: 0.06234538, y: -0.02150976, z: -0.11323079), v18: SCNVector3(x: 0.06506948, y: -0.02217681, z: -0.11169703)) }}USEFUL INFO:In 3D graphics the best and most predictable way to work with polygonal geometry is to initially use three-sided (triangles) and four-sided (quadrangles) faces. Sometimes, in rare cases, you can use five-sided faces but this can lead you to shading artefacts.Bad cases that can potentially lead to errors in SceneKit/Metal are:Lamina FacesNon-Manifold GeometryNon-planar Faces (your case)Concave Faces"Turned inside out" Faces i.e. wrong connection's order (your case)Faces with HolesFaces with Edges that have a zero lengthetc...And one more important thing I should say is: at rendering stage all polygons always turn into triangles. If renderer or rendering engine can't fulfil this transformation you'll get errors.Look how four-sided polygons are competently connected to form a complex object:P.S. camera.zFar for ARKit.let currentFrame = sceneView.session.currentFramelet node = SCNNode()node.camera = SCNCamera()var translation = matrix_identity_float4x4translation.columns.3.z = -0.1 /* 10 cm */node.simdTransform = matrix_multiply((currentFrame?.camera.transform)!, translation)node.camera?.zFar = 1000 /* Set no more than 1000 meters */ 这篇关于使用 SCNGeometryPrimitiveType 多边形崩溃/错误创建自定义 SCNGeometry 多边形平面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
06-23 20:22