I've been working on a script to assign transforms to child objects, such that the transforms will be transferred to Unity ( relative to the origin set in Blender, along with their rotation ) when using the experimental .fbx options. After another user kindly shared a very helpful script with me, I refactored it to match my requirements. Below is the script.
import bpy import math from mathutils import Quaternion context = bpy.context bpy.ops.object.mode_set() baseRotation = Quaternion() for someObject in context.selected_objects: polygonsLength = len( someObject.data.polygons ) if polygonsLength < 1: continue print(someObject) objectData = someObject.data objectWorldMatrix = someObject.matrix_world objectWorldMatrixInverted = objectWorldMatrix.inverted() polygonsAverage = [0.0, 0.0, 0.0] for everyPolygon in someObject.data.polygons: for i in range(3): polygonsAverage[i] += everyPolygon.center[i] for i in range(3): polygonsAverage[i] /= polygonsLength smallestDistanceBetweenCenters = 1000000000 closestPolygonToCenter = someObject.data.polygons for everyPolygon in someObject.data.polygons: distanceToAveragePoint = math.sqrt( pow( polygonsAverage - everyPolygon.center, 2) + pow( polygonsAverage - everyPolygon.center, 2) + pow( polygonsAverage - everyPolygon.center, 2) ) if distanceToAveragePoint < smallestDistanceBetweenCenters: smallestDistanceBetweenCenters = distanceToAveragePoint closestPolygonToCenter = everyPolygon print(closestPolygonToCenter.center) somePolygonInObject = closestPolygonToCenter somePolygonCenter = objectWorldMatrix @ somePolygonInObject.center somePolygonNormal = objectWorldMatrix @ somePolygonInObject.normal rotationDifference = baseRotation.rotation_difference(somePolygonNormal.to_track_quat()) rotationDifferenceMatrix = rotationDifference.to_matrix().to_4x4() rotationDifferenceMatrix.translation = somePolygonCenter objectData.transform(objectWorldMatrixInverted @ rotationDifferenceMatrix.inverted()) someObject.matrix_world = rotationDifferenceMatrix
The script finds the mean of the object's constituent polygons' centers, and then picks the center of the closest polygon as the overall object's center. This worked reasonably well, however when checking the resultant transform center, it at times was not within the object or not close to the object's center, as the chosen polygon's center was not inside the object. Image below.
I would like to adjust this script to be able to assign purely the mean center of the polygons as the object center, provided that this mean center is within a constituent polygon, relative to the origin. In thinking about this, it seems to me that the most reliable approach to checking for this would be some kind of raycasting from the origin to the mean center, and ensuring that one of the polygons collides with this ray, though I'm not sure if there may be a better / simpler approach to this.
How could I perform such a check, and how would I then assign the actual mean transform (which is currently being stored as a simple 3-element array) to the object's transform?
Any help would be greatly appreciated! :)