我正在使用SceneKit构建测试应用程序SCNParticleSystem.它有一个回调函数,允许您修改每个帧上的粒子属性.这个回调的签名是
typealias SCNParticleModifierBlock = (UnsafeMutablePointer<UnsafeMutablePointer<Void>>, UnsafeMutablePointer<Int>, Int, Int, Float) -> Void
Run Code Online (Sandbox Code Playgroud)
来自apple开发人员站点的参考 - SCNParticleSystem_Class
我不知道如何从Swift访问和修改此引用.如果这是C,那么**我可以像数组一样取消引用.
经过一番预测后,我已经达到了这个目的:
.....
particleSystem?.addModifierForProperties([SCNParticlePropertySize], atStage: SCNParticleModifierStage.PostDynamics, withBlock: doit2)
}
struct Foos {
var size:float_t
}
func doit2(data:UnsafeMutablePointer<UnsafeMutablePointer<Void>>, dataStride: UnsafeMutablePointer<Int>, start:Int, end:Int, deltaTime:Float) -> Void {
let myptr = UnsafeMutablePointer<UnsafeMutablePointer<Foos>>(data)
print("indexes",start,end)
for i in 0 ..< end {
print(i,myptr[i].memory.size)
}
}¸
Run Code Online (Sandbox Code Playgroud)
这适用于第一个粒子,但在第二个粒子上崩溃.第一次调用该函数时,有0个粒子,因此它会跳过循环.第二次有三个粒子,所以它试图将它们打印出来.第一个尺寸值为0.9,接缝合理.第二个大小的值显然是假的,然后它崩溃了,我进入调试器.
indexes 0 0
indexes 0 3
0 0.929816
1 1.51296e-39
(lldb)
Run Code Online (Sandbox Code Playgroud)
我可以告诉我,互联网上没有人使用这个功能.我找到的唯一参考是Apple的文档,它只为它提供ObjC示例,而不是Swift.
帮我!
我试图搞砸SceneKit并自学它.基本上,我正在创建一个带有3个矩形边和1个倾斜滑块的四边形.
我希望我的纹理在表面上伸展和变形/变形.
在线阅读一些内容,似乎我需要SCNProgram使用自定义顶点和片段着色器来获得效果.但是,我似乎无法让纹理在表面上传播.需要帮助.(我是图形编程的新手,因此试图教给我自己).
我的Swift代码创建几何和纹理如下:
func geometryCreate() -> SCNNode {
let verticesPosition = [
SCNVector3Make(0.0, 0.0, 0.0),
SCNVector3Make(5.0, 0.0, 0.0),
SCNVector3Make(5.0, 5.0, 0.0),
SCNVector3Make(0.0, 3.0, 0.0)
]
let textureCord = [CGPoint (x: 0.0,y: 0.0), CGPoint(x: 1.0,y: 0.0), CGPoint(x: 1.0,y: 1.0), CGPoint(x: 0.0,y: 1.0)]
let indices: [CInt] = [
0, 2, 3,
0, 1, 2
]
let vertexSource = SCNGeometrySource(vertices: verticesPosition, count: 4)
let srcTex = SCNGeometrySource(textureCoordinates: textureCord, count: 4)
let date = NSData(bytes: indices, length: sizeof(CInt) * …Run Code Online (Sandbox Code Playgroud) 我无法尝试使用纹理贴图在iOS模拟器上运行一个简单的四边形.我已经阅读了这里涉及类似事情的所有其他问题而且我被困住了.输出如下所示:
纹理是这样的:
我的代码是这样的:
// v1 +----+ v0
// | |
// v2 +----+ v3
SCNVector3 vertices[] = { SCNVector3Make( 5.0, 5.0, 0.0),
SCNVector3Make( -5.0, 5.0, 0.0),
SCNVector3Make( -5.0, -5.0, 0.0),
SCNVector3Make( 5.0, -5.0, 0.0)
};
SCNVector3 normals[] = { SCNVector3Make( 0.0f, 0.0f, 1.0),
SCNVector3Make( 0.0f, 0.0f, 1.0),
SCNVector3Make( 0.0f, 0.0f, 1.0),
SCNVector3Make( 0.0f, 0.0f, 1.0)
};
CGPoint textureCoordinates[] = { CGPointMake( 1.0, 1.0),
CGPointMake( 0.0, 1.0),
CGPointMake( 0.0, 0.0),
CGPointMake( 1.0, 0.0)
};
NSUInteger vertexCount = 4;
NSMutableData *indicesData = …Run Code Online (Sandbox Code Playgroud) 我无法让位置音频在SceneKit中工作.从Xcode生成的SceneKit游戏模板开始,我在handleTap方法的末尾添加了以下代码:
let ship = scnView.scene!.rootNode.childNode(withName: "ship", recursively: true)!
if let source = SCNAudioSource(fileNamed: "art.scnassets/monoAudioTest.wav")
{
source.volume = 1
source.isPositional = true
source.shouldStream = true
source.loops = true
source.load()
let player = SCNAudioPlayer(source: source)
ship.addAudioPlayer(player)
}
ship.runAction(SCNAction.move(to: SCNVector3(0, 0, -10000), duration: 8))
Run Code Online (Sandbox Code Playgroud)
音频播放但是当喷嘴远离相机时音量不会减小.我错过了一些步骤或做出了一些错误的假设吗?
交叉发布到Apple开发者论坛.
我在ARKit中有一个简单的SCNNode,我试图将它拖到手机上的任何地方.这是我的代码.
@objc func pan(recognizer :UIGestureRecognizer) {
guard let currentFrame = self.sceneView.session.currentFrame else {
return
}
var translation = matrix_identity_float4x4
translation.columns.3.z = -1.5
let sceneView = recognizer.view as! ARSCNView
let touchLocation = recognizer.location(in: sceneView)
let hitTestResult = sceneView.hitTest(touchLocation, options: [:])
if !hitTestResult.isEmpty {
print("hit result")
guard let hitResult = hitTestResult.first else {
return
}
let node = hitResult.node
node.simdTransform = matrix_multiply(currentFrame.camera.transform, translation)
}
}
Run Code Online (Sandbox Code Playgroud)
问题是阻力很慢而且不平滑.
我正在研究ARKit项目4个月了.我注意到在将一个子项添加到我的场景rootNode时,会有一个FPS丢弃.该设备冻结不到一秒钟.我做了很多研究和试验,注意到所有Apple的代码示例在放置对象时都会使这个FPS下降.无论是直接添加节点(scene.rootNode.addChild(child))还是在不同阶段(didUpdateAtTime,didApplyAnimations等等)的渲染器循环中添加节点都无关紧要.我发现一旦将一个对象添加到场景中,下一个添加的对象将立即呈现.我使用在SceneKit编辑器中创建的3D模型,克隆它以生成我的不同节点,然后将它们添加为子节点.我在放置物体之前做了这个装载工作.
仪器显示渲染器循环在冻结期间忙.
我找到的唯一解决方案是在开始整个体验之前将我的节点添加到加载屏幕后面的场景中.
这是游戏编程中使用它们之前渲染节点的正常行为吗?
多谢你们
我添加了一个UIRotationGestureRecognizer并希望使用它来旋转用户选择的节点.
目前,它围绕z轴旋转,如下所示:
private var startingRotation: CGFloat = 0
@objc private func handleRotation(_ rotation: UIRotationGestureRecognizer) {
guard let node = sceneView.hitTest(rotation.location(in: sceneView), options: nil).first?.node else {
return
}
if rotation.state == .began {
startingRotation = CGFloat(node.rotation.w)
}
node.rotation = SCNVector4(0, 0, 1, -Float(startingRotation + rotation.rotation))
}
Run Code Online (Sandbox Code Playgroud)
如果自放置节点后相机未移动,则此方法可正常工作.
但是,如果用户移动到节点的一侧,它将不再在相机所面对的轴上旋转.
如何围绕相机轴旋转?
我一直在阅读大量关于如何通过在屏幕上拖动对象来移动对象的StackOverflow答案.有些人使用针对.featurePoints的命中测试,有些人使用手势翻译或只是跟踪对象的lastPosition.但老实说..没有人按照每个人的期望它的方式工作.
对.featurePoints进行测试只会使对象四处跳跃,因为拖动手指时不会总是碰到一个特征点.我不明白为什么每个人都在暗示这一点.
像这样的解决方案:使用SceneKit在ARKit中拖动SCNNode
但是物体并没有真正跟随你的手指,并且你走了几步或改变物体或相机的角度的那一刻......并尝试移动物体.. x,z都是倒置的......并且完全有意义要做到这一点.
我真的想要像Apple Demo一样移动对象,但我看看Apple的代码......并且非常奇怪且过于复杂我甚至无法理解.他们移动物体如此美化的技术甚至不像每个人在网上提出的那样接近. https://developer.apple.com/documentation/arkit/handling_3d_interaction_and_ui_controls_in_augmented_reality
必须有一个更简单的方法来做到这一点.
我们有一个Metal用于渲染的应用程序.此应用程序在运行iOS11的设备上正常运行.在运行iOS12的设备上使用相同的应用程序时,我们开始出现故障,有时会在渲染中挂起.我们也试过重新编译iOS12并且得到了同样的不良行为.在控制台上,我们收到以下不同的消息:
2018-09-22 09:22:29.508576-0500 OurApp [1286:84481]由于执行期间的错误,命令缓冲区的执行被中止.丢弃(GPU错误/恢复的受害者)(IOAF代码5)
2018-09-22 09:29:55.654426-0500 OurApp [1286:84625]由于执行期间的错误,命令缓冲区的执行被中止.导致GPU挂起错误(IOAF代码3)
2018-09-22 09:34:37.718054-0500 OurApp [1286:87354]执行命令缓冲区因执行过程中的错误而中止.忽略(导致先前/过多的GPU错误)(IOAF代码4)
使用前两条消息,渲染看起来很奇怪,其中显示空白屏幕,然后最终渲染发生在屏幕上.使用最后一条消息,渲染实际上不会发生,并且消息将继续显示,直到我们移动到另一个视图.
此应用程序使用SceneKit,实例化a SCNView并使用默认值CIContext.它还使用基于物理的光照模型,该模型强制使用Metal渲染器.该应用程序具有简单的SCNNode几何形状,圆柱体.圆柱体的每个几何对象都获得正常纹理(总共3个).相同的漫反射,金属度和粗糙度值应用于圆柱体的所有几何对象.
有人遇到过这个问题吗?如果是这样,你是如何解决的?
谢谢
更新:当图像用作场景的照明环境时,似乎会出现问题:
let scene = SCNScene()
scene.lightingEnvironment.contents = UIImage(named: "ourLightingEnvironmentImage")
Run Code Online (Sandbox Code Playgroud)
当不使用照明环境时,问题就会消失.这开始看起来像一个Apple bug,我们将提交一个.我们陷入困境是因为我们需要照明环境来为我们的应用程序中的模型生成逼真的反射.
这是我遇到的错误,请查看所附图片以获取更多信息。
com.apple.scenekit.scnview-renderer(17):EXC_BAD_ACCESS(代码= 1,地址= 0xf000000010a10c10)
我可以在调用以下函数时重现此错误,但前提是此函数在一秒钟内被多次调用。如果用户快速点击该按钮以循环到下一辆可用的汽车,则会发生这种情况。
如您所见,我尝试将其包装在a中DispatchQueue以解决我的问题。
您还会注意到,我创建了一个Bool alreadyCyclingCars来跟踪该cycleCarNext()函数是否已完成,然后再允许再次调用它。
这个功能主要是通过所有的迭代unlockedCars中unlockedCars阵列。
如果汽车的类型与我们当前正在寻找的汽车相匹配,我会打破循环。
然后我们确定当前汽车的索引,以查看我需要显示的下一辆汽车是否是数组中的下一辆汽车(如果有)(如果没有),我们到达了数组的末尾,因此我显示了第一辆汽车在数组中。
有谁比我对此了解更多?真的很感谢,谢谢!
func cycleCarNext() {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
if !self.alreadyCyclingCars {
self.alreadyCyclingCars = true
var indexOfCurrentCar = 0
for (index, car) in UserData.shared.unlockedCars.enumerated() {
if car.type == self.overlayScene.currentCarOnDisplay {
indexOfCurrentCar = index
break
}
}
if indexOfCurrentCar < UserData.shared.unlockedCars.count - 1 {
let nextCar = UserData.shared.unlockedCars[indexOfCurrentCar+1]
self.playerNode.removeFromParentNode()
self.playerNode = …Run Code Online (Sandbox Code Playgroud)