我想在用户点击屏幕时创建一个新的SceneKit节点,并让它以预定距离直接出现在摄像机前面.对于测试,这将是一个SCNText读取"你在这里点击"的读数.它也应该与视线成直角 - 也就是说,"面向相机".
那么,鉴于self.camera.orientation
SCNVector4(或类似),我该如何:
我怀疑(2)的答案是它与`self.camera.orientation相同?但是(1)让我有点失落.
我看到了许多类似的问题,比如这个,但没有答案.
我正在尝试在照片上构建静态增强现实场景,在平面和图像上的共面点之间有4个定义的对应关系.
这是一步一步的流程:
我还测量了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,我需要:
H - 单应性; K - 内在矩阵; [R | t] - 外在矩阵
我尝试了两种方法来找到相机的变换矩阵:使用OpenCV中的solvePnP和基于4个共面点的单应性手动计算.
1.找出单应性
此步骤已成功完成,因为世界原点的UV坐标似乎是正确的.
2.内在矩阵
为了获得iPhone 6的内在矩阵,我使用了这个应用程序,它给出了100个640*480分辨率图像中的以下结果:
假设输入图像具有4:3的宽高比,我可以根据分辨率缩放上述矩阵
我不确定,但感觉这是一个潜在的问题.我用cv :: calibrationMatrixValues来检查fovx的计算内在矩阵,结果是~50°,而它应该接近60°. …
我正在使用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控件在方向更改时旋转?
我试图从我的场景中删除表示路径的节点集.它们是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) 我知道可以在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是全新的,但有没有人碰巧知道如何使这项工作?
我正在使用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) 我无法让位置音频在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项目4个月了.我注意到在将一个子项添加到我的场景rootNode时,会有一个FPS丢弃.该设备冻结不到一秒钟.我做了很多研究和试验,注意到所有Apple的代码示例在放置对象时都会使这个FPS下降.无论是直接添加节点(scene.rootNode.addChild(child))还是在不同阶段(didUpdateAtTime,didApplyAnimations等等)的渲染器循环中添加节点都无关紧要.我发现一旦将一个对象添加到场景中,下一个添加的对象将立即呈现.我使用在SceneKit编辑器中创建的3D模型,克隆它以生成我的不同节点,然后将它们添加为子节点.我在放置物体之前做了这个装载工作.
仪器显示渲染器循环在冻结期间忙.
我找到的唯一解决方案是在开始整个体验之前将我的节点添加到加载屏幕后面的场景中.
这是游戏编程中使用它们之前渲染节点的正常行为吗?
多谢你们
我一直在阅读大量关于如何通过在屏幕上拖动对象来移动对象的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
必须有一个更简单的方法来做到这一点.