- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试创建一个具有自定义形状的平面形式的自定义 SCNGeometry,它可以放置在 ARKit session 中。我在以下方法中使用选项 SCNGeometryPrimitiveTypePolygon 似乎工作正常:
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
}
创建此几何体后,我将其分配给 SCNNode:s .geometry
属性,并像往常一样将其添加到我的 AR 场景中:
let geometry = SCNGeometry.polygonPlane(vertices: verticesArray)
let node = SCNNode(geometry: geometry)
sceneView.scene.rootNode.addChildNode(node)
这适用于某些类型的平面形状。然而,我经常遇到崩溃,主要是在使用复杂的形状或许多顶点来勾勒平面形状时。我已经试验过了,看起来几何体是按预期创建的,没有任何错误,但是当节点被添加到场景中并即将被渲染时会发生错误。这是打印的错误:
-[MTLDebugDevice validateNewBufferArgs:options:]:467: failed assertion `Cannot create buffer of zero length.'
调试导航器中显示的内容:
最后是堆栈跟踪:
* 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 + 4
warning: failed to set breakpoint site at 0x21931425c for breakpoint -4.1: error sending the breakpoint request
warning: failed to set breakpoint site at 0x219314530 for breakpoint -4.2: error sending the breakpoint request
warning: failed to set breakpoint site at 0x2193141b4 for breakpoint -4.3: error sending the breakpoint request
warning: failed to set breakpoint site at 0x21931fcc4 for breakpoint -5.1: error sending the breakpoint request
我没有快速调试的经验,但在我看来问题出现在某些 Metal 框架代码中的第 4-6 帧中:
frame #4: 0x000000021c28e23c Metal`MTLReportFailure + 528
frame #5: 0x000000023f984108 MetalTools`-[MTLDebugDevice validateNewBufferArgs:options:] + 172
frame #6: 0x000000023f98430c MetalTools`-[MTLDebugDevice newBufferWithBytes:length:options:] + 128
感谢任何帮助/建议!
这是一个不会产生此错误的数组:
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)
]
这是我的应用程序使用此数组时的两个屏幕截图。如您所见,多边形位于平面内,因为所有顶点位置都是从该平面上的 HitTest 中选取的。不要介意剪裁颜色,因为它是由于 z-fighting 引起的,可以通过偏移平面轻松修复:
这是生成此错误的顶点数组的示例:
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)
]
这是使用该数组时的屏幕截图。蓝色平面是该方法起作用时的实例,但如果仔细观察,会发现一条红线。这条红线跟随上面错误数组的顶点,当使用相应几何体的多边形平面添加到场景时,它会立即使应用程序崩溃:
下面是@ARGeo 的 macOS 解决方案的代码,但稍作修改以适合我的 iOS 应用程序并使用任意数量的顶点。该代码适用于先前失败但在使用另一个顶点数组时再次失败的顶点数组。就像@ARGeo 建议的那样,我确保将此方法放在实际类中而不是扩展中,以防 MemoryLayout<Int32>.size
在扩展中使用时导致问题。
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)
}
上述代码失败的顶点数组示例:
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)
]
好的,所以我为上面的代码制作了一个 macOS 版本(这是 @ARGeo 提出的解决方案,但有一些小的变化,比如使用任意数量的顶点),即使在 iOS代码版本。但是,什么都没有呈现,我也没有收到任何我不知道原因的错误消息。添加行 cameraNode.camera?.zFar = 1000
以防 It's not visible due to clipping 时,程序会崩溃,并给出一个新的错误。如果 zFar
足够小(使用 zFar < 10
测试)它不会崩溃,在这种情况下也不会渲染多边形。错误打印是相同的 -[MTLDebugDevice validateNewBufferArgs:options:]:467: failed assertion 'Cannot create buffer of zero length.'
但调试导航器显示:
堆栈跟踪的最后一行是这样的:
* 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: 0x00007fff462f29e0
如果您想自己尝试一下,可以使用这里的代码。只需复制并粘贴到 macOS 项目中:
import SceneKit
import QuartzCore
class 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
}
}
我不知道是什么导致了这个问题,因为它似乎是一些内部渲染出了问题。我在调试方面也不是很有经验,所以我将不胜感激任何帮助,因为我无法进一步理解这一点。
最佳答案
解决方案(复制粘贴此 macOS 应用程序代码以在 ViewController.swift
中进行测试):
import SceneKit
class 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))
}
}
有用信息:
在 3D 图形中,处理多边形几何体的最佳和最可预测的方法是最初使用三边(三角形)和四边(四边形)面。有时,在极少数情况下,您可以使用五面体,但这可能会导致您产生阴影伪像。
可能导致 SceneKit
/Metal
错误的 Bad cases 是:
我应该说的更重要的一件事是:在渲染阶段,所有多边形总是变成三角形。如果渲染器或渲染引擎无法完成此转换,您将收到错误。
看看四边形如何有效地连接起来形成一个复杂的物体:
P.S. camera.zFar
用于 ARKit。
let currentFrame = sceneView.session.currentFrame
let node = SCNNode()
node.camera = SCNCamera()
var translation = matrix_identity_float4x4
translation.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 */
关于swift - 使用 SCNGeometryPrimitiveType 多边形崩溃/错误创建自定义 SCNGeometry 多边形平面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56773438/
我正在尝试在 SceneKit 中创建自定义几何形状,结果我的形状很好。唯一的问题是它是黑色的,即使我改变了颜色,它仍然是黑色的。我已经在 SceneKit 中测试了其他原始形状,结果是正常的。我以为
我制作了这个方法来抓取 UIImage 并将其转换为 3D 模型。然而,这意味着我添加了很多节点。我在想也许可以通过将所有几何图形添加到单个节点中来优化它。有办法实现吗? 这是代码 static in
试图弄清楚我如何创建一个多边形作为原始类型的 SCNGeometry,我的目标是添加多边形节点作为球体节点的子节点,并使其看起来像 map 套件的 MKPolygon,like in this exa
题 你如何定义 custom geometry from vertex data 上的 Material ,以便它呈现与“典型”SCNNodes 相同的效果? 细节 在这个场景中有 定向灯 使用 ph
我正在从网络服务器下载 collada 文件,并希望以编程方式映射纹理,但 SCNGeometry 为零。有人可以提出建议吗?下面是示例代码。 let url = URL(string: "h
我正在尝试使用 kvo 来观察节点的几何形状,因为 Scenekit 不提供某种回调来让我知道节点的详细程度何时已更新。这样做的目的是我的节点有空闲动画,当细节级别更改为最详细版本以外的任何内容时,我
我正在创建自定义 SCNGeometry。首先,我将其开发为平面。它会显示,我可以将颜色应用到它的漫反射内容,但如果我尝试应用任何东西,例如 UIImage 或 CALayer,它会显示为白色。 代码
我正在尝试创建自定义 SCNPlane可以具有任何多边形形式的类,因为常规 SCNPlane 只能是矩形。 我试图通过扩展 SCNGeometry 来实现这一点.下面是我使用的代码: extensio
这个问题在这里已经有了答案: Stroke Width with a SceneKit line primitive type (2 个答案) 关闭 5 年前。 我创建了一条线,但无法增加它的粗细。
我在 iOS 上使用 SceneKit,并且我有一个几何体要渲染为线框。所以基本上我只想画线,所以没有纹理。 我发现我可以使用 SCNMaterial 的 shaderModifiers 属性来完成此
好像我想通过组合一些 SCNBox 和 SCNPyramid 等来创建一些自定义形状,我可以通过设置正确的位置和几何形状将它们放在一起。然而我就是找不到一种方法将它们组合成一个可以在物理世界中修改或
我想将法线映射添加到 SCNGeometry。我有一个法线贴图图像 (PNG) 和第二组 UV 坐标,作为 GeometrySource 注入(inject)。 如果可能的话,我最喜欢的解决方案是为受
我使用 UIView 作为 SCNPlane 的漫反射 Material ,这样我就可以在我的 3D 场景中显示 2D 菜单。 这如我所料: var node:SCNNode = // A child
我在大学里接到了一个任务,要为 SCNGeometry Octahedron 添加一张图片作为纹理。这是我在 Swift 中的第一个项目。 对于带有 UIImage 类的 UIKit 有很多建议,但我
我想弄清楚如何在屏幕上显示一个 SCNScylinder,其中只有一个边框/描边/边缘可见。我场景中的一切都工作正常,我正在考虑将清晰的颜色应用于 specular.contents 是否需要使用 S
我正在尝试创建一个具有自定义形状的平面形式的自定义 SCNGeometry,它可以放置在 ARKit session 中。我在以下方法中使用选项 SCNGeometryPrimitiveTypePol
Apple 最近发布了 Model I/O Framework,可以理解,文档当前为 quite sparse许多类(class)仍未完全记录。 Model I/O talk建议在 SceneKit
我正在创建 AR 应用程序(Xcode 10.1、Swift 4.2.1)。 我想将 USDZ 3D 对象加载到一个空 SceneKit 的场景中,然后将其作为 MDL 网格进行处理。 这是我的代码:
我正在尝试将一个简单的文本标签放在一个(希望是所有类型的)内置 SCNGeometry 形状上,因为它们在屏幕上移动。我最接近成功的是通过 .firstMaterial.diffuse.content
将图像作为 Material 添加到预定义的 3D 对象(例如 Swift 中的立方体)对我来说效果很好。现在我正在尝试将图像作为 Material 添加到在运行时动态创建的多边形中。 我希望这样的事
我是一名优秀的程序员,十分优秀!