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[0]
for everyPolygon in someObject.data.polygons:
distanceToAveragePoint = math.sqrt(
pow( polygonsAverage[0] - everyPolygon.center[0], 2) +
pow( polygonsAverage[1] - everyPolygon.center[1], 2) +
pow( polygonsAverage[2] - everyPolygon.center[2], 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! :)

meshinstead ofmeormand I supposeface or polyoverf or p. . If in doubt re a variable or what it does please ask. Also try and stick to pep8 egprint("foo")notprint ( "foo" )– batFINGER Jul 13 '20 at 17:19