主要问题:
我在此之后添加此部分以澄清问题. - 我可以暂停我的视频(我不希望它在循环播放).当我的节点出现时,我的节点播放我的视频,即使它处于暂停状态.如果我的视频播放完毕,它就会出现,它会重新启动.我想删除此行为.
在我的应用程序中,我使用对象和对象SKVideoNode从AVPlayer(:URL)内部3D空间创建.我用来确定何时找到特定图像,并从那里播放视频.一切都很好,花花公子,除了每次AVPlayer进入视线时玩家决定按照自己的时间进行游戏; 但是,它可能是只要在连接到进入视野.无论哪种方式,每次节点进入相机镜头时都会播放.我用SCNNodeSCNGeometryARKit .ImageTrackingARImageAnchorSCNNodeAVPlayer
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if(keyPath == "rate") {
print((object as! AVPlayer).rate)
}
}
Run Code Online (Sandbox Code Playgroud)
打印出速率,它是1,但它是0.
我print("Play")使用player.pause()或player.play()为我的所有函数打印出某种打印函数,并且无论何时更改速率,都不会调用它们.如何找到改变播放器速率的来源?
我检查了原始的rootnode,self.sceneview.scene.rootNode.childNodes以确保我没有创建额外的VideoNodes/SCNNodes/AVPlayers等,似乎只有1.
关于为什么SKVideoNode/AVPlayer正在作为SCNNode播放的任何想法都会使用ARKit看到相机?提前致谢!
EDIT1:
制定了一种解决方法,仅在用户单击此节点时确定
let tap = UITapGestureRecognizer(target: self, action: #selector(self!.tapGesture))
tap.delegate = self!
tap.name = "MyTap"
self!.sceneView.addGestureRecognizer(tap)
Run Code Online (Sandbox Code Playgroud)
然后在下一个函数里面,我放了
@objc func tapGesture(_ gesture:UITapGestureRecognizer) {
let tappedNodes = self.sceneView.hitTest(gesture.location(in: gesture.view), options: [SCNHitTestOption.searchMode: 1])
if …Run Code Online (Sandbox Code Playgroud) 我是iOS开发的新手,我自己也很难过.我正在尝试使用每个面具有不同颜色的SceneKit渲染立方体.
这是我到目前为止所得到的:
func sceneSetup() {
// 1
let scene = SCNScene()
// 2
let BoxGeometry = SCNBox(width: 0.9, height: 0.9, length: 0.9, chamferRadius: 0.0)
BoxGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
let cube = SCNNode(geometry: BoxGeometry)
cube.position = SCNVector3(x: 0, y: 0, z: -1)
scene.rootNode.addChildNode(cube)
// 3
sceneView.scene = scene
sceneView.autoenablesDefaultLighting = true
sceneView.allowsCameraControl = true
Run Code Online (Sandbox Code Playgroud)
但我希望每张脸都有不同的颜色.我怎么做?
这是360度视频播放器项目.
我添加了一个cameranode(SCNNode)到一个根节点,cameranode被放在了中心(0,0,0)SCNSphere,它现在可以播放视频了.
现在我必须使用devicemotion.设备移动时我需要旋转相机.不只是旋转一定的角度.(不只是设备移动,当我拿着设备时,我的移动方式就像设备移动一样.因为我发现如果我使用deviceMotion.attitude.roll,cameranode仅在设备自行移动时移动,而不是当我绕着设备移动时)
当设备位于(x1,y1,z1)位置时,cameranode将随设备移动而旋转,当设备再次位于(x1,y1,z1)位置时,视图应与我们离开的最后一个相同.
这就是我所做的:
if (self.motionManager.gyroAvailable) {
self.motionManager.gyroUpdateInterval = 1.0/60.0;
[self.motionManager startGyroUpdatesToQueue:self.queue withHandler:^(CMGyroData *gyroData, NSError *error){
if (error) {
[self.motionManager stopGyroUpdates];
NSLog(@"Gyroscope encountered error:%@",error);
}else {
CGFloat tempX = 0;
CGFloat tempY = 0;
CGFloat tempZ = 0;
if ((fabs(gyroData.rotationRate.y)/60) > 0.002) {
tempY = gyroData.rotationRate.y/60;
}
tempX = gyroData.rotationRate.x/60;
tempZ = gyroData.rotationRate.z/60;
[self.cameraNode runAction:[SCNAction rotateByX:-tempY y:tempX z:tempZ duration:0]];
}
}];
}else {
NSLog(@"This device has no gyroscope");
}
Run Code Online (Sandbox Code Playgroud)
数学可能是错误的,我不知道为什么我会划分60,但它似乎是我使用时所需的最接近的值 [self.cameraNode runAction:[SCNAction rotateByX:-tempY …
我正在使用3D模型开发ARKit应用程序。为此,我使用了3D模型并添加了用于移动,旋转和缩放3D模型的手势。
现在我只面临1个问题,但是我不确定这个问题与什么有关。3d模型是否存在问题,或者我的程序中是否缺少任何内容。
问题是我正在使用的3D模型显示得很大并且超出了屏幕。我正在尝试缩小尺寸,但尺寸很大。
这是我的代码:
@IBOutlet var mySceneView: ARSCNView!
var selectedNode = SCNNode()
var prevLoc = CGPoint()
var touchCount : Int = 0
override func viewDidLoad() {
super.viewDidLoad()
self.lblTitle.text = self.sceneTitle
let mySCN = SCNScene.init(named: "art.scnassets/\(self.sceneImagename).scn")!
self.mySceneView.scene = mySCN
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3Make(0, 0, 0)
self.mySceneView.scene.rootNode.addChildNode(cameraNode)
self.mySceneView.allowsCameraControl = true
self.mySceneView.autoenablesDefaultLighting = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(detailPage.doHandleTap(_:)))
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(detailPage.doHandlePan(_:)))
let gesturesArray = NSMutableArray()
gesturesArray.add(tapGesture)
gesturesArray.add(panGesture)
gesturesArray.addObjects(from: self.mySceneView.gestureRecognizers!)
self.mySceneView.gestureRecognizers …Run Code Online (Sandbox Code Playgroud) 我正在使用ARKit显示3D对象.我设法将节点放在用户面前的真实世界(也就是相机).但是当我放下相机时,我无法让它们面对镜头.
let tap_point=CGPoint(x: x, y: y)
let results=arscn_view.hitTest(tap_point, types: .estimatedHorizontalPlane)
guard results.count>0 else{
return
}
guard let r=results.first else{
return
}
let hit_tf=SCNMatrix4(r.worldTransform)
let new_pos=SCNVector3Make(hit_tf.m41, hit_tf.m42+Float(0.2), hit_tf.m43)
guard let scene=SCNScene(named: file_name) else{
return
}
guard let node=scene.rootNode.childNode(withName: "Mesh", recursively: true) else{
return
}
node.position=new_pos
arscn_view.scene.rootNode.addChildNode(node)
Run Code Online (Sandbox Code Playgroud)
节点位于相机前面的平面上.但他们都朝着同一个方向前进.我想我应该轮换,SCNNode但我没有设法做到这一点.
我正在为我的应用程序使用ARKit,我尝试从我的web服务器(URL)动态加载.scn文件
这是我的代码的一部分
let urlString = "https://da5645f1.ngrok.io/mug.scn"
let url = URL.init(string: urlString)
let request = URLRequest(url: url!)
let session = URLSession.shared
let downloadTask = session.downloadTask(with: request,
completionHandler: { (location:URL?, response:URLResponse?, error:Error?)
-> Void in
print("location:\(String(describing: location))")
let locationPath = location!.path
let documents:String = NSHomeDirectory() + "/Documents/mug.scn"
ls = NSHomeDirectory() + "/Documents"
let fileManager = FileManager.default
if (fileManager.fileExists(atPath: documents)){
try! fileManager.removeItem(atPath: documents)
}
try! fileManager.moveItem(atPath: locationPath, toPath: documents)
print("new location:\(documents)")
let node = SCNNode()
let scene = SCNScene(named:"mug.scn", inDirectory: ls)
let nodess …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用场景工具包复制此立方体图像形状(获得原始创建者的许可).

到目前为止,我有线条和顶点的绘图代码.我无法使用图像,因为背景必须是透明的.
我正在尝试解决的具体问题是如何编辑SCNGeometryPrimitiveType.Line元素的笔触宽度.
我创建行的基本方法是这样的:
private func squareVertices(length: Float) -> [SCNVector3] {
let m = length/Float(2)
let topLeft = SCNVector3Make(-m-q, m+q, m+q)
let topRight = SCNVector3Make( m+q, m+q, m+q)
let bottomLeft = SCNVector3Make(-m-q, -m-q, m+q)
let bottomRight = SCNVector3Make( m+q, -m-q, m+q)
return [topLeft, topRight, bottomLeft, bottomRight]
}
private func cubeFace() -> SCNGeometry {
let vertices : [SCNVector3] = squareVertices(l)
let geoSrc = SCNGeometrySource(vertices: UnsafePointer<SCNVector3>(vertices), count: vertices.count)
// index buffer
let idx1 : [Int32] = [0, 3] …Run Code Online (Sandbox Code Playgroud) 我在XCode中导入了一个DAE文件并将其转换为SCN文件.此文件包含一些带动画的3D对象.
我正在尝试使用动画导入所有节点并在场景中播放它们.节点已导入但我无法播放动画.
NSURL *idleURL = [[NSBundle mainBundle] URLForResource:model.model3D
withExtension:@"scn" subdirectory:@"3d.scnassets"];
SCNScene *idleScene = [SCNScene sceneWithURL:idleURL
options:@{
SCNSceneSourceAnimationImportPolicyKey:SCNSceneSourceAnimationImportPolicyPlayRepeatedly}
error:nil];
// Merge the loaded scene into our main scene in order to
// place the object in our own scene
for (SCNNode *child in idleScene.rootNode.childNodes){
[_sceneView.scene.rootNode addChildNode:child];
if (child.animationKeys.count > 0) {
CAAnimation *animation = [child animationForKey:child.animationKeys[0]];
animation.repeatCount = INFINITY;
child.paused = NO;
[_sceneView.scene.rootNode addAnimation:animation forKey:child.animationKeys[0]];
}
}
[_sceneView setPlaying:YES];
Run Code Online (Sandbox Code Playgroud) 目标是子类化SCNNode.根据类docs,init(geometry geometry: SCNGeometry?)是一个指定的初始化器(没有convenience列出关键字),所以这个代码是不是调用了它的超类的指定初始化器?
为什么Xcode显示以下错误?
必须调用超类SCNNode的指定初始值设定项
class PreviewNode: SCNNode {
// Constants
let PreviewNodeColor = gRedColor
let Size = CGFloat(1.0)
let ChamferRadius = CGFloat(0.0)
override init() {
let previewBox = SCNBox(width: Size, height: Size, length: Size, chamferRadius: ChamferRadius)
previewBox.firstMaterial!.diffuse.contents = PreviewNodeColor
previewBox.firstMaterial!.transparency = 0.2
previewBox.firstMaterial!.specular.contents = UIColor.whiteColor()
super.init(geometry: previewBox)
}
}
Run Code Online (Sandbox Code Playgroud) 我创建了一个子类SCNNode.它由很少的子节点组成.我已经宣布了一种方法,即.soundCasual()这会SCNAudioPlayer为此类的实例添加一个.当调用此方法时,一切都按预期工作并播放音频.无论何时轻敲该节点(手势),都会在该节点上调用此方法.
码:
class MyNode: SCNNode {
let wrapperNode = SCNNode()
let audioSource5 = SCNAudioSource(fileNamed: "audiofile.mp3")
override init() {
super.init()
if let virtualScene = SCNScene(named: "MyNode.scn", inDirectory: "Assets.scnassets/Shapes/MyNode") {
for child in virtualScene.rootNode.childNodes {
wrapperNode.addChildNode(child)
}
}
}
func soundCasual() {
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
if let audioSource = self?.audioSource5 {
let audioPlayer = SCNAudioPlayer(source: audioSource)
self?.wrapperNode.removeAllAudioPlayers()
self?.wrapperNode.addAudioPlayer(audioPlayer)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
仪器内的问题(分配)
当我分析我的整个代码库(这是其他几件事)时,我看到每当我点击该节点时,SCNAudioPlayer的分配计数在Instruments内进行分析时增加1.但所有的增长都是持久的.根据定义SCNAudioPlayer,我假设玩家在播放后被移除,这就是为什么增量应该在瞬态分配中,但它不是这样工作的.这就是为什么我removeAllAudioPlayers()在向节点添加SCNAudioPlayer之前尝试过,正如您在代码中看到的那样soundCasual() …