添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I don't understand how node scaling on nodes work.

I'm trying to understand how the code on Apple's Creating Face Based AR Experiences sample project works. Specifically, I'm trying to understand the TransformVisualization.swift file and the transformations applied to its nodes.

The method addEyeTransformNodes() is called and left and right eye nodes are both scaled using the simdScale properties. That's the part I'm confused about.

I tried scaling the same node using .scale and .simdScale properties, but both of them did nothing.

Moreover, what's more confusing is the fact that even though the values for .simdPivot are greater than 1 the node is scaled down. I expected nodes to scale up.

Why would we need to set .simdPivot to scale the nodes but not .scale and .simdScale properties?

Here's the function I'm talking about.

func addEyeTransformNodes() {
  guard #available(iOS 12.0, *), let anchorNode = contentNode else { return }
  // Scale down the coordinate axis visualizations for eyes.
  rightEyeNode.simdPivot = float4x4(diagonal: float4(3, 3, 3, 1))
  leftEyeNode.simdPivot = float4x4(diagonal: float4(3, 3, 3, 1))
  anchorNode.addChildNode(rightEyeNode)
  anchorNode.addChildNode(leftEyeNode)

Here's what I tried:

func addEyeTransformNodes() {
  guard #available(iOS 12.0, *), let anchorNode = contentNode else { return }
  // Does nothing
  rightEyeNode.simdScale = float3(3, 3, 3)
  // Does nothing
  leftEyeNode.scale = SCNVector3(x: 3, y: 3, z: 3)
  anchorNode.addChildNode(rightEyeNode)
  anchorNode.addChildNode(leftEyeNode)

I expected to scale the node with the way I did it, but nothing happened.

Looking forward to your answers and help.

If you need to offset a pivot (before applying rotate and/or scale) point use simdPivot instance property.

Use my testing code to find out how it works:

let sphereNode1 = SCNNode(geometry: SCNSphere(radius: 1))
sphereNode1.geometry?.firstMaterial?.diffuse.contents = UIColor.red
sphereNode1.position = SCNVector3(-5, 0, 0)
scene.rootNode.addChildNode(sphereNode1)
let sphereNode2 = SCNNode(geometry: SCNSphere(radius: 1))
sphereNode2.geometry?.firstMaterial?.diffuse.contents = UIColor.green
sphereNode2.simdPivot.columns.3.x = -1
sphereNode2.scale = SCNVector3(2, 2, 2)           // WORKS FINE
//sphereNode2.simdScale = float3(2, 2, 2)         // WORKS FINE
scene.rootNode.addChildNode(sphereNode2)
let sphereNode3 = SCNNode(geometry: SCNSphere(radius: 1))
sphereNode3.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
sphereNode3.position = SCNVector3(5, 0, 0)
scene.rootNode.addChildNode(sphereNode3)

Pivot offset is x: -1:

Pivot offset is x: 0:

Using init(diagonal:) initializer helps you creating a new 4x4 Matrix with the specified vector on the main diagonal. This method has an issue: it scales down objects when you're assigning diagonal values greater than 1, and vice versa. So, if you want to scale up character's eyes use the following approach as a workaround:

rightEyeNode.simdPivot = float4x4(diagonal: float4(1/3, 1/3, 1/3, 1))
leftEyeNode.simdPivot = float4x4(diagonal: float4(1/3, 1/3, 1/3, 1))

I think Apple engineers will fix this issue in the future.

Hope this helps.

Hi ARGeo, thanks for the answer. Unfortunately, I think it doesn't answer my question. As shown above Apple used .simdPivot to scale down the node. I'm trying to understand 1) why setting either .scale or .simdScale doesn't scale the nodes given situation above, 2) why setting float4(3,3,3,1) on .simdPivot scales down the node, I expected nodes to scale up. Hopefully, you can shed light on these. My understanding of working with matrices and .simd is based on this: developer.apple.com/documentation/accelerate/simd/… – ddeger May 8, 2019 at 6:35 Thanks for the update. You are certainly correct about the issue with the init(diagonal:). I was able to scale up the node based on your suggestion. The only question that remains is why setting either node.scale or node.simdScale doesn't scale the nodes. Can you explain that please? – ddeger May 8, 2019 at 7:05 .simdScale = float3(3, 3, 3) and .scale = SCNVector3(x: 3, y: 3, z: 3) are working fine. Test them outside a function. You'll see it's OK. I suppose the problem is an anchorNode. – Andy Jazz May 8, 2019 at 7:18 I've supplied my code with sphereNode2.scale = SCNVector3(2, 2, 2). It works. I've just tested .simdScale = float3(3, 3, 3). It works too. – Andy Jazz May 8, 2019 at 7:20

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.