我一辈子都想不出如何从objective-c中的转换创建SCNMatrix4。
我尝试在objective-c中使用的swift代码:
let affineTransform = frame.displayTransform(for: .portrait, viewportSize: sceneView.bounds.size)
let transform = SCNMatrix4(affineTransform)
faceGeometry.setValue(SCNMatrix4Invert(transform), forKey: "displayTransform")
我得到了第一行和第三行,但我找不到从CGAffineTransform创建此SCNMatrix4的方法。
CGAffineTransform affine = [self.sceneView.session.currentFrame displayTransformForOrientation:UIInterfaceOrientationPortrait viewportSize:self.sceneView.bounds.size];
SCNMatrix4 trans = ??
[f setValue:SCNMatrix4Invert(trans) forKey:@"displayTransform"];
没有SCNMatrix4Make,我尝试了simd_matrix4x4,但似乎也不起作用。
谢谢
编辑:
swift的代码来自苹果的Example项目"ARKitFaceExample",以下是完整的代码:
/*
See LICENSE folder for this sample’s licensing information.
Abstract:
Demonstrates using video imagery to texture and modify the face mesh.
*/
import ARKit
import SceneKit
/// - Tag: VideoTexturedFace
class VideoTexturedFace: TexturedFace {
override func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
guard let sceneView = renderer as? ARSCNView,
let frame = sceneView.session.currentFrame,
anchor is ARFaceAnchor
else { return nil }
#if targetEnvironment(simulator)
#error("ARKit is not supported in iOS Simulator. Connect a physical iOS device and select it as your Xcode run destination, or select Generic iOS Device as a build-only destination.")
#else
// Show video texture as the diffuse material and disable lighting.
let faceGeometry = ARSCNFaceGeometry(device: sceneView.device!, fillMesh: true)!
let material = faceGeometry.firstMaterial!
material.diffuse.contents = sceneView.scene.background.contents
material.lightingModel = .constant
guard let shaderURL = Bundle.main.url(forResource: "VideoTexturedFace", withExtension: "shader"),
let modifier = try? String(contentsOf: shaderURL)
else { fatalError("Can't load shader modifier from bundle.") }
faceGeometry.shaderModifiers = [ .geometry: modifier]
// Pass view-appropriate image transform to the shader modifier so
// that the mapped video lines up correctly with the background video.
let affineTransform = frame.displayTransform(for: .portrait, viewportSize: sceneView.bounds.size)
let transform = SCNMatrix4(affineTransform)
faceGeometry.setValue(SCNMatrix4Invert(transform), forKey: "displayTransform")
contentNode = SCNNode(geometry: faceGeometry)
#endif
return contentNode
}
}
如果有人需要这个,这是我丢失的分机号
extension SCNMatrix4 {
/**
Create a 4x4 matrix from CGAffineTransform, which represents a 3x3 matrix
but stores only the 6 elements needed for 2D affine transformations.
[ a b 0 ] [ a b 0 0 ]
[ c d 0 ] -> [ c d 0 0 ]
[ tx ty 1 ] [ 0 0 1 0 ]
. [ tx ty 0 1 ]
Used for transforming texture coordinates in the shader modifier.
(Needs to be SCNMatrix4, not SIMD float4x4, for passing to shader modifier via KVC.)
*/
init(_ affineTransform: CGAffineTransform) {
self.init()
m11 = Float(affineTransform.a)
m12 = Float(affineTransform.b)
m21 = Float(affineTransform.c)
m22 = Float(affineTransform.d)
m41 = Float(affineTransform.tx)
m42 = Float(affineTransform.ty)
m33 = 1
m44 = 1
}
}
1条答案
按热度按时间lbsnaicq1#
要复制Swift扩展以从
CGAffineTransform
创建SCNMatrix4
,您可以实现以下函数:一些.h文件:
一些.m文件:
然后你的代码变成:
注意
NSValue valueWithSCNMatrix4:
的用法,这是将结构体转换为对象所必需的,并且应该满足使用KVC设置displayTransform
属性的要求。