简体   繁体   中英

How to restrict position of a node to the surface of a custom plane in Scenekit?

I'm new to Swift and SceneKit and I am trying to implement a solution where users can add a 3D object to a scene and it will be placed on the edge of a plane's surface.

I tried using the plane node's bounding box values to assume its edge and the object's potential position, but since the plane is a custom geometry, the object often ends up outside of the plane's surface.

On top of that, if the plane's specific edge is diagonal line, I also need the object to rotate so it always runs parallel to the plane's edge.

Here's a snippet of my code and an image illustrating the problem and the desired outcome :

//creating plane out of custom geometry values
let surfaceNode = SCNNode(geometry: surfaceGeometry)

//defining plane’s bounding box & center point
let minimum = SIMD3<Float>(surfaceNode.boundingBox.min)
let maximum = SIMD3<Float>(surfaceNode.boundingBox.max)
let translation = (maximum - minimum) * 0.5

//fixing pivot point
surfaceNode.pivot = SCNMatrix4MakeTranslation(surfaceNode.boundingBox.min.x + translation.x, 0, surfaceNode.boundingBox.min.z + translation.z)

//adding custom plane to the scene
surfaceNode.position = SCNVector3(0, 0 ,0)
sceneView.scene.rootNode.addChildNode(surfaceNode)

//creating object
let object = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
let objectNode = SCNNode(geometry: object)
objectNode.pivot = SCNMatrix4MakeTranslation(0, -0.1, 0)

//positioning object on top of the plane’s surface
objectNode.position = SCNVector3(surfaceNode.position.x, surfaceNode.position.y, surfaceNode.position.z - translation.z)

//adding object to scene
sceneView.scene.rootNode.addChildNode(objectNode)

I was hoping to see a cool math based solution for this because that would be a neat trick, but since I haven't...

  1. You didn't say how dynamic this has to be and 2) I'm guessing you have some kind of drag and drop in mind, so to avoid some of the math, this would be my approach.

What I would do is to take your Plane's Surface and calculate some snap-to positions that include the rotation you need to place your Object. I recommend this because some corners will just not fit and since you can't allow over lap. So, get your drop position and find the closest "acceptable" slot so to speak and "snap to" the nearest position.

If you want to allow a lot of flexibility, like move a basically 1 pixel at a time, then I'd create an array of acceptable position ranges and the rotation required for each. If someone drags outside of that range, then either don't allow that or move it to the closest acceptable "spot".

A bit painful to setup for multiple geometries, but depending on what you are trying to accomplish, it would be accurate albeit a bit "hard coded".

另一种更简单的可能性是,如果您为移动的盒子提供一个实体,并在平面的所有边缘放置带有实体的不可见“墙”,并使用碰撞遮罩让 Scenekit 为您完成工作。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM