[DEV] exporting blender

This commit is contained in:
Edouard DUPIN 2017-05-26 22:07:32 +02:00
parent afdcd183dc
commit 811f2fc2b1

View File

@ -6,6 +6,8 @@ import bpy
import mathutils import mathutils
import bpy_extras.io_utils import bpy_extras.io_utils
#blender myscene.blend --background --python myscript.py
def getChildren(obj): def getChildren(obj):
children = [] children = []
for ob in bpy.data.objects: for ob in bpy.data.objects:
@ -47,61 +49,57 @@ To create a compound physics collision shape for a mesh in blender:
default=True) default=True)
""" """
# Methods for writing point, scale, and quaternion types to a YAML file. def out_point3( v ):
# This particular implementation converts values to a Y-up coordinate system.
def out_point3_y_up( v ):
return "%g %g %g" % ( v.x, v.z, -v.y )
def out_scale3_y_up( s ):
return "%g %g %g" % ( s.x, s.z, s.y )
def out_quaternion_y_up( q ):
return "%g %g %g %g" % ( q.w, q.x, q.z, -q.y )
# This implementation maintains blender's Z-up coordinate system.
def out_point3_z_up( v ):
return "%g %g %g" % ( v.x, v.y, v.z ) return "%g %g %g" % ( v.x, v.y, v.z )
def out_scale3_z_up( s ): def out_scale3( s ):
return "%g %g %g" % ( s.x, s.y, s.z ) return "%g %g %g" % ( s.x, s.y, s.z )
def out_quaternion_z_up( q ): def out_quaternion( q ):
return "%g %g %g %g" % ( q.w, q.x, q.y, q.z ) return "%g %g %g %g" % ( q.x, q.y, q.z, q.w )
def get_physics_shape(obj, mainObjScale, use_y_up=False): def get_physics_shape(obj, mainObjScale, _matrix):
shape = "" shape = ""
props = { } props = { }
name = obj.name.lower() name = obj.name.lower()
scale = Vector(( abs(obj.scale.x), abs(obj.scale.y), abs(obj.scale.z) )) scale = Vector(( abs(obj.scale.x), abs(obj.scale.y), abs(obj.scale.z) ))
print("object * name : " + obj.name)
if use_y_up: print(" * scale : (" + str(obj.scale.x) + "," + str(obj.scale.y) + "," + str(obj.scale.z) + ")")
out_point3 = out_point3_y_up print(" * location : (" + str(obj.location.x) + "," + str(obj.location.y) + "," + str(obj.location.z) + ")")
out_scale3 = out_scale3_y_up if obj.rotation_mode == 'QUATERNION':
out_quaternion = out_quaternion_y_up qrot = obj.rotation_quaternion
qrot2 = _matrix.to_quaternion() * obj.rotation_quaternion
else: else:
out_point3 = out_point3_z_up qrot = obj.matrix_local.to_quaternion()
out_scale3 = out_scale3_z_up qrot2 = _matrix.to_quaternion() * obj.matrix_local.to_quaternion()
out_quaternion = out_quaternion_z_up if qrot == qrot2:
print(" * quaternion : (" + str(qrot.x) + "," + str(qrot.y) + "," + str(qrot.z) + "," + str(qrot.w) + ")")
else:
print(" * quaternion : (" + str(qrot.x) + "," + str(qrot.y) + "," + str(qrot.z) + "," + str(qrot.w) + ") ==> (" + str(qrot2.x) + "," + str(qrot2.y) + "," + str(qrot2.z) + "," + str(qrot2.w) + ")")
# BOX # BOX
if name.startswith('box') \ if name.startswith('box') \
or name.startswith('cube'): or name.startswith('cube'):
shape = "Box" shape = "Box"
props["half-extents"] = out_scale3( scale ) props["half-extents"] = out_scale3( Vector((scale.x * mainObjScale.x, scale.y * mainObjScale.y, scale.z * mainObjScale.z )) )
# SPHERE # SPHERE
elif name.startswith('sph'): elif name.startswith('sph'):
shape = "Sphere" shape = "Sphere"
props["radius"] = obj.scale.x * mainObjScale.x props["radius"] = (scale.x * mainObjScale.x + scale.y * mainObjScale.y + scale.z * mainObjScale.z ) / 3.0
# CONE # CONE
elif name.startswith('cone'): elif name.startswith('cone'):
shape = "Cone" shape = "Cone"
props["radius"] = obj.scale.x props["radius"] = (scale.x * mainObjScale.x + scale.y * mainObjScale.y ) / 2.0
props["height"] = obj.scale.z * 2.0 props["size"] = obj.scale.z * mainObjScale.z * 2.0
# CYLINDER # CYLINDER
elif name.startswith('cyl'): elif name.startswith('cyl'):
shape = "Cylinder" shape = "Cylinder"
props["half-extents"] = out_scale3( scale ) props["radius"] = (scale.x * mainObjScale.x + scale.y * mainObjScale.y ) / 2.0
props["size"] = obj.scale.z * mainObjScale.z
# CAPSULE # CAPSULE
elif name.startswith('cap'): elif name.startswith('cap'):
shape = "Capsule" shape = "Capsule"
props["radius"] = obj.scale.x props["radius"] = (scale.x * mainObjScale.x + scale.y * mainObjScale.y ) / 2.0
props["height"] = obj.scale.z props["size"] = obj.scale.z * mainObjScale.z
# CONVEX-HULL # CONVEX-HULL
elif name.startswith('convex'): elif name.startswith('convex'):
shape = "ConvexHull" shape = "ConvexHull"
@ -117,8 +115,14 @@ def get_physics_shape(obj, mainObjScale, use_y_up=False):
print(" shape type: '" + str(shape) + "' from element name:'" + str(obj.name) + "'") print(" shape type: '" + str(shape) + "' from element name:'" + str(obj.name) + "'")
if obj.location != Vector((0,0,0)): if obj.location != Vector((0,0,0)):
props["origin"] = out_point3(obj.location) location_tmp = _matrix * Vector((obj.location.x * mainObjScale.x, obj.location.y * mainObjScale.y, obj.location.z * mainObjScale.z ))
location_tmp = Vector((obj.location.x * mainObjScale.x, obj.location.y * mainObjScale.y, obj.location.z * mainObjScale.z ))
props["origin"] = out_point3(location_tmp)
if obj.rotation_mode == 'QUATERNION':
qrot = _matrix.to_quaternion() * obj.rotation_quaternion
else:
qrot = _matrix.to_quaternion() * obj.matrix_local.to_quaternion()
if obj.rotation_mode == 'QUATERNION': if obj.rotation_mode == 'QUATERNION':
qrot = obj.rotation_quaternion qrot = obj.rotation_quaternion
else: else:
@ -130,7 +134,7 @@ def get_physics_shape(obj, mainObjScale, use_y_up=False):
return (shape, props) return (shape, props)
def write_collision_shape(object, file, mainObjScale, offset): def write_collision_shape(object, file, mainObjScale, offset, EXPORT_GLOBAL_MATRIX):
if len(getChildren(object))==0: if len(getChildren(object))==0:
# no phisical shape ... # no phisical shape ...
return return
@ -143,7 +147,7 @@ def write_collision_shape(object, file, mainObjScale, offset):
if subObj.type != 'MESH' \ if subObj.type != 'MESH' \
and subObj.type != 'EMPTY': and subObj.type != 'EMPTY':
continue continue
(shape, props) = get_physics_shape(subObj, mainObjScale) (shape, props) = get_physics_shape(subObj, mainObjScale, EXPORT_GLOBAL_MATRIX)
if shape=="": if shape=="":
print("error of shape detection type ..."); print("error of shape detection type ...");
continue continue
@ -546,7 +550,7 @@ def write_mesh(scene, file, object, EXPORT_GLOBAL_MATRIX, mtl_dict):
print(" child:'%s'" % (subObj.name)) print(" child:'%s'" % (subObj.name))
if subObj.name.lower().startswith(EXPORT_COLLISION_NAME): if subObj.name.lower().startswith(EXPORT_COLLISION_NAME):
print(" find physics:'%s'" % (subObj.name)) print(" find physics:'%s'" % (subObj.name))
write_collision_shape(subObj, file, object.scale, 1) write_collision_shape(subObj, file, object.scale, 1, EXPORT_GLOBAL_MATRIX)
@ -619,7 +623,7 @@ def write_file(filepath,
##################################################################### #####################################################################
## Save collision shapes (for one all): ## Save collision shapes (for one all):
##################################################################### #####################################################################
write_collision_shape(sub_obj, file, sub_obj.scale, 0) write_collision_shape(sub_obj, file, sub_obj.scale, 0, EXPORT_GLOBAL_MATRIX)
else: else:
print(" child:'" + str(sub_obj.name) + "' type=" + sub_obj.type + " not parsed ...") print(" child:'" + str(sub_obj.name) + "' type=" + sub_obj.type + " not parsed ...")