Chapter 17: Working with Blend Shapes
前言
這章主要就是對豬頭進行表情的操作。
大綱
Right eye
Left eye
Animojis and blend shapes
是ARFaceAnchor中的一個屬性。
是一個字典。
目前53個key, 分別對應臉部的不同特徵,value是0~1,依據不同的特徵變化。
Animating the brow
根據blend shapes來更動眉毛的位置。
class Pig: SCNNode {
let occlusionNode: SCNNode
// set up brow
private var neutralBrowY: Float = 0
// 從scene graph中取出brow的位置
private lazy var browNode = childNode(withName: "brow", recursively: true)!
// - Tag: BlendShapeAnimation
var blendShapes: [ARFaceAnchor.BlendShapeLocation: Any] = [:] {
didSet {
// 從blendShapes中取出browInnerUp的數值
guard let browInnerUp = blendShapes[.browInnerUp] as? Float else { return }
// 設定browNode的位置
let browHeight = (browNode.boundingBox.max.y - browNode.boundingBox.min.y)
browNode.position.y = neutralBrowY + browHeight * browInnerUp
}
}
// - Tag: ARFaceAnchor Update
func update(withFaceAnchor anchor: ARFaceAnchor) {
// 不段從外面取得最新的blendShapes
blendShapes = anchor.blendShapes
}
Animating the eyes
一樣的類似動作,現在分別針對左右兩眼處理
// Set up right eye
private var neutralRightEyeX: Float = 0
private var neutralRightEyeY: Float = 0
private lazy var eyeRightNode = childNode(withName: "eyeRight", recursively: true)!
private lazy var pupilRightNode = childNode(withName: "pupilRight", recursively: true)!
// Get size of pupils(瞳孔)
private lazy var pupilWidth: Float = {
let (min, max) = pupilRightNode.boundingBox
return max.x - min.x
}()
private lazy var pupilHeight: Float = {
let (min, max) = pupilRightNode.boundingBox
return max.y - min.y
}()
/////////////////////////////
// Right eye look
let rightPupilPos = SCNVector3(
x: (neutralRightEyeX - pupilWidth) * (eyeLookInRight - eyeLookOutRight),
y: (neutralRightEyeY - pupilHeight) * (eyeLookUpRight - eyeLookDownRight),
z: pupilRightNode.position.z
)
pupilRightNode.position = rightPupilPos
// Right eye blink
eyeRightNode.scale.y = 1 - eyeBlinkRight
Animating the mouth
嘴巴
// Set up mouth
private var neutralMouthY: Float = 0
private lazy var mouthNode = childNode(withName: "mouth",
recursively: true)!
// Get size of mouth
private lazy var mouthHeight: Float = {
let (min, max) = mouthNode.boundingBox
return max.y - min.y
}()
////////////////////////
// Mouth
mouthNode.position.y = neutralMouthY - mouthHeight * mouthOpen
PreviousChapter 16: Creating Assets for Face-Based ARNextChapter 18: Recording Your ARKit Experience with ReplayKit
Last updated
Was this helpful?