Hi there Having some troubles trying to work out how to align faces of a polyhedra to a plane.
Code is intermingled with lots of other things but this is basically it:
/*
A Face of a Tetrahedron can be double clicked and each face is its own mesh with a single TransformNode as their parent:
* TransformNode / node
* Polygon Face / mesh
* Polygon Face / mesh
* Polygon Face / mesh
* Polygon Face / mesh
* etc
*/
function onDoublepick(e) {
const camera = context.getCamera()
const mesh = e.detail.mesh
const center = new BB.Vector3(0,0,0)
// MESH POSITION (center of the face)
const meshPosition = mesh.position.clone()
const meshPositionAbs = mesh.getAbsolutePosition()
// PARENT NODE POSITION (0,0,0)
const nodePosition = node.position.clone()
const nodePositionAbs = node.getAbsolutePosition()
// FLOOR
const floor = new BB.Vector3( 0, -9999, 0 )
// hard reset node rotations
node.rotationQuaternion = center.clone()
node.rotation = center.clone()
// individual points in the polygon face
const pointA = (mesh.data.points?.[0]).clone()
const pointB = (mesh.data.points?.[1]).clone()
const pointC = (mesh.data.points?.[2]).clone()
// attempt rotation to the floor (based on documentation example)
const axis1 = pointA.clone().subtract(pointB.clone())
const axis3 = BB.Vector3.Cross(floor, axis1)
const axis2 = BB.Vector3.Cross(axis3, axis1)
node.rotationQuaternion = BB.Quaternion.RotationQuaternionFromAxis(axis1, axis2, axis3)
// OR (same thing): node.rotation = BB.Vector3.RotationFromAxis(axis1, axis2, axis3)
}
Just trying to align the face to the floor for now - and this is without manipulating the camera or using lookAt methods. Thing I’m confused over is how to best create axis1 / axis2 / axis3. I’ve read as much as I can on the forum and in the documentation but no dice
It randomises polygons around a center origin, and when a polygon face is clicked, it tries to align the face to the ground (and creates an absolute position copy of the original sphere positions for reference).
In essence, just trying to align a point to a point around an origin!
NB, perhaps another way of approaching it is to change the meshes forward direction to point at an arbitrary point, and then use mesh.lookAt (for example mesh.lookAt(floor), mesh.lookAt(camera) etc).
My solution is convoluted but it allows me to freely rotate an object until a Vector3 is aligned to another Vector3:
bake world matrix into absolute position and rotation of each child node (this is different to bakeTransformIntoVertices, and is a custom function I saw here), edit: or just remove parent of child node
remove parent reference temporarily from each child node (they are now freely floating in space in the same position)
clone the transform node and make it look at one of the absolute positions of the former child nodes
re-add the child nodes to the original parent node
copy the rotation from the cloned transform node to the original transform node
In the sketch this basically just means click on a mesh → mesh centers in the viewport
And it could also be done with “lookAt” instead of creating a clone - but this way there is future possibility to interpolate or modify the rotation start and end point.
// BAKE TRANSFORM
function bakeWorldMatrix( mesh ) {
if (mesh.parent) mesh.parent.computeWorldMatrix(true)
mesh.computeWorldMatrix(true)
let rotation = BABYLON.Quaternion.Identity()
let position = BABYLON.Vector3.Zero()
mesh.getWorldMatrix().decompose(BABYLON.Vector3.Zero(), rotation, position)
if (mesh.rotationQuaternion) {
mesh.rotationQuaternion.copyFrom(rotation)
} else {
rotation.toEulerAnglesToRef(mesh.rotation)
}
// REMOVE PARENT
if (mesh.parent) mesh.parent = undefined
mesh.position.x = position.x
mesh.position.y = position.y
mesh.position.z = position.z
return mesh
}
// ============ ATTEMPT ============
function alignPolygonMeshToFloor( mesh ) {
const centerPoint = new BABYLON.Vector3(0,0,0)
const groundPoint = ground.getAbsolutePosition().clone()
const cameraPoint = camera.position.clone()
// BAKE TRANSFORMS INTO CHILDREN (AND REMOVE PARENT)
polygonMeshes.map( polyMesh => bakeWorldMatrix(polyMesh) )
// OR polygonMeshes.map( polyMesh => polyMesh.setParent(null) )
// NODE LOOKS AT MESH ABSOLUTE POSITION
mainTransformNode.lookAt( mesh.getAbsolutePosition() )
// CLONE NODE TO GET A NEW ROTATION (AND DELETE)
let clone = mainTransformNode.clone("clonedTransformNode")
clone.lookAt( cameraPoint )
bakeWorldMatrix( clone )
const rotationQuaternion = clone.rotationQuaternion ? clone.rotationQuaternion.clone() : null
const rotation = clone.rotation ? clone.rotation.clone() : null
clone.dispose()
// ADD CHILDREN BACK TO NODE + SET NODE ROTATION TO CLONES
polygonMeshes.map( polyMesh => polyMesh.setParent( mainTransformNode ) )
if (rotationQuaternion) mainTransformNode.rotationQuaternion = rotationQuaternion
if (rotation) mainTransformNode.rotation = rotation
}