标签: scenekit

将SceneKit对象放在SCNCamera当前方向的前面

我想在用户点击屏幕时创建一个新的SceneKit节点,并让它以预定距离直接出现在摄像机前面.对于测试,这将是一个SCNText读取"你在这里点击"的读数.它也应该与视线成直角 - 也就是说,"面向相机".

那么,鉴于self.camera.orientationSCNVector4(或类似),我该如何:

  1. 产生SCNVector3,将节点置于摄像机的"前方"给定距离?
  2. 生成SCNVector4(或SCNQuaternion),它定向节点,使其"面对"相机?

我怀疑(2)的答案是它与`self.camera.orientation相同?但是(1)让我有点失落.

我看到了许多类似的问题,比如这个,但没有答案.

scenekit swift3

12
推荐指数
3
解决办法
2万
查看次数

从单应性或使用solvePnP()函数估计相机姿势

我正在尝试在照片上构建静态增强现实场景,在平面和图像上的共面点之间有4个定义的对应关系.

这是一步一步的流程:

  1. 用户使用设备的相机添加图像.我们假设它包含一个用透视图捕获的矩形.
  2. 用户定义矩形的物理尺寸,它位于水平平面(根据SceneKit的YOZ).让我们假设它的中心是世界的起源(0,0,0),所以我们可以很容易地找到每个角的(x,y,z).
  3. 用户在图像坐标系中为矩形的每个角定义uv坐标.
  4. SceneKit场景使用相同大小的矩形创建,并以相同的透视可见.
  5. 可以在场景中添加和移动其他节点.

流

我还测量了iphone相机相对于A4纸中心的位置.所以对于这个镜头,位置是(0,14,42.5),以cm为单位测量.我的iPhone也稍微倾斜到桌子上(5-10度)

使用这些数据我已设置SCNCamera为在第三张图像上获得蓝色平面的所需视角:

let camera = SCNCamera()
camera.xFov = 66
camera.zFar = 1000
camera.zNear = 0.01

cameraNode.camera = camera
cameraAngle = -7 * CGFloat.pi / 180
cameraNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(cameraAngle))
cameraNode.position = SCNVector3(x: 0, y: 14, z: 42.5)
Run Code Online (Sandbox Code Playgroud)

这将为我提供比较我的结果的参考.

为了使用SceneKit构建AR,我需要:

  1. 调整SCNCamera的fov,使其与真实相机的fov相匹配.
  2. 使用世界点(x,0,z)和图像点(u,v)之间的4个相关误差计算相机节点的位置和旋转

方程

H - 单应性; K - 内在矩阵; [R | t] - 外在矩阵

我尝试了两种方法来找到相机的变换矩阵:使用OpenCV中的solvePnP和基于4个共面点的单应性手动计算.

手动方式:

1.找出单应性

单应

此步骤已成功完成,因为世界原点的UV坐标似乎是正确的.

2.内在矩阵

为了获得iPhone 6的内在矩阵,我使用了这个应用程序,它给出了100个640*480分辨率图像中的以下结果:

固有

假设输入图像具有4:3的宽高比,我可以根据分辨率缩放上述矩阵

Intrinsic2

我不确定,但感觉这是一个潜在的问题.我用cv :: calibrationMatrixValues来检查fovx的计算内在矩阵,结果是~50°,而它应该接近60°. …

opencv homography augmented-reality ios scenekit

12
推荐指数
1
解决办法
3122
查看次数

如何防止ARSCNView在方向更改期间旋转

我正在使用ARKit,我想允许用户在纵向和横向模式下使用该应用程序.我希望所有UI控件在方向更改时旋转,除了ARSCNView.我试图在相反的方向转换sceneView但是没有用.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)

        let targetRotation = coordinator.targetTransform
        let inverseRotation = targetRotation.inverted()

        coordinator.animate(alongsideTransition: { (context) in
            self.sceneView.transform = self.sceneView.transform.concatenating(inverseRotation)
            context.viewController(forKey: UITransitionContextViewControllerKey.from)
        }, completion: nil)

    }
Run Code Online (Sandbox Code Playgroud)

如何防止ARKit会话的场景视图旋转,同时允许所有其他UI控件在方向更改时旋转?

ios scenekit arkit arscnview

12
推荐指数
1
解决办法
904
查看次数

从scene.rootNode中删除SCNNode节点导致在SceneKit中崩溃

我试图从我的场景中删除表示路径的节点集.它们是SCNSphere几何节点和表示线的自定义几何的组合,使用SCNGeometrySource和SCNGeometryElement创建.

我没有在任何类型的数组中保留这些节点.相反,我按照名称搜索场景中rootNode的节点树的第一级,以及后续调用使它们淡出的动作序列,并且它们应该从根节点中删除它们自己.

代码如下:

func clearPath() {
    //
    let disappear = SCNAction.fadeOut(duration: 0.1)
    let remove = SCNAction.removeFromParentNode()
    let sequence = SCNAction.sequence([disappear, remove])

    if let pathNodesToRemove = pathNodes() {
        //
        for node in pathNodesToRemove {
            //
            node.removeAllActions()
            node.runAction(sequence)
        }
    }

    if let lineNodesToRemove = lineNodes() {
        for node in lineNodesToRemove {
            //
            node.removeAllActions()
            node.runAction(sequence)
        }
    }

    path.removeAll()
}
Run Code Online (Sandbox Code Playgroud)

哪里:

func pathNodes() -> [SCNNode]? {
    //

...        

    let nodes = rootNode.childNodes.filter { (node) -> Bool in
        //
        guard let name = node.name else …
Run Code Online (Sandbox Code Playgroud)

ios scenekit swift

12
推荐指数
1
解决办法
611
查看次数

在SceneKit中自定义可设置动画的属性

我知道可以在Core Animation中创建自定义的可动画属性,但在OS X 10.8的SceneKit框架中呢? SCNAnimatable似乎没有公开与CALayer使动画属性动画相同的API .

在我的应用程序中,我有一个SCNNode名为的子类Starfield,我通过使用一个从旧的OpenGL应用程序移植SCNNodeRendererDelegate.Starfields公开了一个GLfloat名为warpFactor:

@interface Starfield : SCNNode<SCNNodeRendererDelegate> {
    // other stuff that's not really important for this question
    GLfloat warpFactor;
}

@property(nonatomic) GLfloat warpFactor;
@end
Run Code Online (Sandbox Code Playgroud)

但是当我尝试添加动画时,就像这样:

CABasicAnimation *warp = [CABasicAnimation animationWithKeyPath:@"warpFactor"];
warp.toValue = @1.0;
warp.duration = 5.0;
[starfield addAnimation:warp forKey:@"warp"];
Run Code Online (Sandbox Code Playgroud)

我在控制台中得到以下内容:

[SCNKit ERROR] warpFactor is not an animatable path (from <unnamed SCNNode 0x1016473c0, no children>)
Run Code Online (Sandbox Code Playgroud)

我知道SceneKit是全新的,但有没有人碰巧知道如何使这项工作?

macos core-animation objective-c osx-mountain-lion scenekit

11
推荐指数
1
解决办法
1304
查看次数

如何使用Swift的UnsafeMutablePointer <UnsafeMutablePointer <Void >>引用?

我正在使用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.

帮我!

ios scenekit swift

11
推荐指数
1
解决办法
926
查看次数

自定义着色器SCNProgram iOS 9 Scenekit

我试图搞砸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)

opengl-es fragment-shader ios scenekit ios9

11
推荐指数
1
解决办法
2439
查看次数

如何让位置音频在SceneKit中工作?

我无法让位置音频在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开发者论坛.

audio ios scenekit

11
推荐指数
2
解决办法
1101
查看次数

将子项添加到场景ARKit/SceneKit时FPS会下降

我正在研究ARKit项目4个月了.我注意到在将一个子项添加到我的场景rootNode时,会有一个FPS丢弃.该设备冻结不到一秒钟.我做了很多研究和试验,注意到所有Apple的代码示例在放置对象时都会使这个FPS下降.无论是直接添加节点(scene.rootNode.addChild(child))还是在不同阶段(didUpdateAtTime,didApplyAnimations等等)的渲染器循环中添加节点都无关紧要.我发现一旦将一个对象添加到场景中,下一个添加的对象将立即呈现.我使用在SceneKit编辑器中创建的3D模型,克隆它以生成我的不同节点,然后将它们添加为子节点.我在放置物体之前做了这个装载工作.

仪器显示渲染器循环在冻结期间忙.

我找到的唯一解决方案是在开始整个体验之前将我的节点添加到加载屏幕后面的场景中.

这是游戏编程中使用它们之前渲染节点的正常行为吗?

多谢你们

augmented-reality ios scenekit swift arkit

11
推荐指数
1
解决办法
459
查看次数

ARKIT:使用PanGesture移动对象(正确的方法)

我一直在阅读大量关于如何通过在屏幕上拖动对象来移动对象的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

必须有一个更简单的方法来做到这一点.

xcode ios scenekit arkit

11
推荐指数
2
解决办法
3058
查看次数