[DEV] change mesh exporter (add stupid collision model

This commit is contained in:
Edouard DUPIN 2013-08-08 22:39:30 +02:00
parent 6e718229b8
commit 9b5d1fa4f2
3 changed files with 82 additions and 193 deletions

View File

@ -210,7 +210,7 @@ class ExportEMF(bpy.types.Operator, ExportHelper):
collision_object_name = StringProperty(
name="Collision root name",
description="The top-level name that will contain the physics shapes",
default="StaticMesh/object"
default="physic"
)
axis_forward = EnumProperty(

View File

@ -6,34 +6,13 @@ import bpy
import mathutils
import bpy_extras.io_utils
"""
bl_info = {
"name": "Export Physics Shapes (.yaml)",
"author": "Stuart Denman",
"version": (1, 0),
"blender": (2, 5, 7),
# "api": 35622,
"location": "File > Export",
"description": "Export physics shapes under the selected empty named 'physics'.",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Import-Export"}
def getChildren(obj):
children = []
for ob in bpy.data.objects:
if ob.parent == obj:
children.append(ob)
return children
'''
Usage Notes:
To create a compound physics collision shape for a mesh in blender:
1. place the 3D cursor at the origin of the mesh object.
2. Add > Empty, name it "physics"
3. Create a physics shape with Add > Mesh > Cube, UV Sphere, Cylinder, Cone or create an arbitrary mesh for a ConvexHull shape.
4. Parent the new shape to the "physics" Empty.
5. The mesh name must start with: Box, Sphere, Cylinder, Cone, Capsule, or ConvexHull, depending on the shape you want.
6. Position and scale the shape object, but do not modify the internal vertices, unless it is a ConvexHull type.
7. Repeat step 3-6 until your shape is complete. Shapes can only be a 1-level deep hierarchy.
8. IMPORTANT: Select the empty object you named "physics"
9. Click File > Export > Physics Shapes (.yaml)
'''
import bpy
from bpy.props import *
@ -47,31 +26,50 @@ from bpy_extras.io_utils import ExportHelper
import time
import shutil
"""
Usage Notes:
To create a compound physics collision shape for a mesh in blender:
1. place the 3D cursor at the origin of the mesh object.
2. Add > Empty, name it "physics"
3. Create a physics shape with Add > Mesh > Cube, UV Sphere, Cylinder, Cone or create an arbitrary mesh for a ConvexHull shape.
4. Parent the new shape to the "physics" Empty.
5. The mesh name must start with: Box, Sphere, Cylinder, Cone, Capsule, or ConvexHull, depending on the shape you want.
6. Position and scale the shape object, but do not modify the internal vertices, unless it is a ConvexHull type.
7. Repeat step 3-6 until your shape is complete. Shapes can only be a 1-level deep hierarchy.
8. IMPORTANT: Select the empty object you named "physics"
9. Click File > Export > Physics Shapes (.yaml)
"""
"""
use_y_up = BoolProperty(name="Convert To Y-Up",
description="Converts the values to a Y-Axis Up coordinate system",
default=True)
"""
# Methods for writing point, scale, and quaternion types to a YAML file.
# 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 )
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 )
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 )
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 ):
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 ):
return "[%g,%g,%g,%g]" % ( q.w, q.x, q.y, q.z )
return "%g %g %g %g" % ( q.w, q.x, q.y, q.z )
def getPhysicsShape( obj, use_y_up ):
def getPhysicsShape(obj, use_y_up=True):
shape = ""
props = { }
name = obj.name.lower()
scale = Vector(( abs(obj.scale.x), abs(obj.scale.y), abs(obj.scale.z) ))
if use_y_up:
out_point3 = out_point3_y_up
out_scale3 = out_scale3_y_up
@ -79,10 +77,11 @@ def getPhysicsShape( obj, use_y_up ):
else:
out_point3 = out_point3_z_up
out_scale3 = out_scale3_z_up
out_quaternion = out_quaternion_z_up
out_quaternion = out_quaternion_z_up
# BOX
if name.startswith('box'):
if name.startswith('box') \
or name.startswith('cube'):
shape = "Box"
props["half-extents"] = out_scale3( scale )
# SPHERE
@ -107,132 +106,47 @@ def getPhysicsShape( obj, use_y_up ):
elif name.startswith('convex'):
shape = "ConvexHull"
mesh = obj.to_mesh( bpy.context.scene, True, 'PREVIEW' )
props["points"] = "\n"
props["points"] = ""
for v in mesh.vertices:
props["points"] += " - " + out_point3( v.co ) + "\n"
props["points"] = props["points"].rstrip("\n")
props["points"] += "" + out_point3( v.co ) + "|"
props["points"] = props["points"].rstrip("|")
if scale != Vector((1,1,1)):
props["scale"] = out_scale3( scale )
# remove mesh
print(" shape type : '%s' from element name : '%s'" % (shape, obj.name))
if obj.location != Vector((0,0,0)):
props["origin"] = out_point3( obj.location )
if obj.rotation_mode == 'QUATERNION':
qrot = obj.rotation_quaternion
else:
qrot = obj.matrix_local.to_quaternion()
if qrot != Quaternion((1,0,0,0)):
props["rotate"] = out_quaternion( qrot )
return (shape, props)
###### EXPORT OPERATOR #######
class ExportPhysicsShape(bpy.types.Operator, ExportHelper):
'''Export physics shapes under the selected empty named "physics".'''
bl_idname = "object.export_physics"
bl_label = "Export Physics Shapes"
filename_file = ""
filename_ext = ".yaml"
filter_glob = StringProperty(default="*.yaml", options={'HIDDEN'})
append_to_existing = BoolProperty(name="Append To Existing File",
description="Appends the physics shapes to an existing file",
default=True)
use_y_up = BoolProperty(name="Convert To Y-Up",
description="Converts the values to a Y-Axis Up coordinate system",
default=True)
object_name = StringProperty(name="Root Name",
description="The top-level name that will contain the physics shapes",
default="StaticMesh/object" )
@classmethod
def poll(cls, context):
return context.active_object.type in ['EMPTY'] and context.active_object.name == 'physics'
def execute(self, context):
filepath = self.filepath
filepath = bpy.path.ensure_ext(filepath, self.filename_ext)
ob_base = context.active_object
out = open( filepath, ["w","a"][self.append_to_existing] )
out.write( self.object_name + ":\n" )
out.write( " physics:\n" )
for c in ob_base.children:
if c.type != 'MESH':
continue
(shape, props) = getPhysicsShape( c, self.use_y_up )
out.write( " - shape: " + shape + "\n" )
for (k,v) in props.items():
out.write( " %s: %s\n" % (k, v) )
out.close();
self.report( {'INFO'}, "Export succeeded!" )
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
# change the default object name to use the current .blend filename
name = bpy.path.display_name_from_filepath(bpy.data.filepath)
self.object_name = "StaticMesh/" + name
self.filepath = name
if True:
# File selector
wm.fileselect_add(self) # will run self.execute()
return {'RUNNING_MODAL'}
elif True:
# search the enum
wm.invoke_search_popup(self)
return {'RUNNING_MODAL'}
elif False:
# Redo popup
return wm.invoke_props_popup(self, event) #
elif False:
return self.execute(context)
"""
def getPhysicsShape(obj):
name = obj.name.lower()
# BOX
if name.startswith('box'):
shape = "Box"
# SPHERE
elif name.startswith('sph'):
shape = "Sphere"
# CONE
elif name.startswith('cone'):
shape = "Cone"
# CYLINDER
elif name.startswith('cyl'):
shape = "Cylinder"
# CAPSULE
elif name.startswith('cap'):
shape = "Capsule"
# CONVEX-HULL
elif name.startswith('convex'):
shape = "ConvexHull"
print("find a '%s'" % shape)
def writeCollisionShape(object, file, collisionName):
print("need write collision Shape ... \n")
def writeCollisionShape(object, file):
if len(getChildren(object))==0:
# no phisical shape ...
return
fw = file.write
fw('\nCollisions shapes :\n')
fw('\t\n')
for c in object.children:
if c.type != 'MESH':
fw('\t\tPhysique : \n')
for subObj in getChildren(object):
print(" element='%s' type '%s'" % (subObj.name,str(subObj.type)))
if subObj.type != 'MESH':
continue
getPhysicsShape( c )
(shape, props) = getPhysicsShape(subObj)
if shape=="":
print("error of shape detection type ...");
continue
fw("\t\t\t" + shape + "\n" )
for (k,v) in props.items():
fw("\t\t\t\t%s : %s\n" % (k, v) )
@ -372,7 +286,7 @@ def write_file(filepath,
EXPORT_GLOBAL_MATRIX=None,
EXPORT_PATH_MODE='AUTO',
EXPORT_BINARY_MODE=False,
EXPORT_COLLISION_NAME="",
EXPORT_COLLISION_NAME=""
):
if EXPORT_GLOBAL_MATRIX is None:
EXPORT_GLOBAL_MATRIX = mathutils.Matrix()
@ -415,7 +329,11 @@ def write_file(filepath,
# Get all meshes
for ob_main in objects:
print("object : '%s'" % str(ob_main))
print("**************** '%s' *******************" % str(ob_main.name))
if ob_main.type != 'MESH':
print(ob_main.name, 'is not a mesh type - ignoring')
fw('# can not export : "%s" : type="%s"\n' % (ob_main.name, str(ob_main.type)))
continue
#print("name : '%s'" % ob_main.name)
#for plop in ob_main.child:
# print(" child : '%s'" % plop.name)
@ -491,18 +409,18 @@ def write_file(filepath,
obnamestring = name_compat(name1)
else:
obnamestring = '%s_%s' % (name_compat(name1), name_compat(name2))
fw('\tName : %s\n' % obnamestring) # Write Object name
fw('\t%s\n' % obnamestring) # Write Object name
###########################################################
## Vert
###########################################################
fw('\tVertex : %d\n\t\t' % len(me_verts))
fw('\t\tVertex : %d\n\t\t\t' % len(me_verts))
for v in me_verts:
fw('%.6f %.6f %.6f|' % v.co[:])
fw('\n')
###########################################################
## UV
###########################################################
fw('\tUV-mapping :\n\t\t')
fw('\t\tUV-mapping :\n\t\t\t')
if faceuv:
# in case removing some of these dont get defined.
uv = uvkey = uv_dict = f_index = uv_index = None
@ -530,7 +448,7 @@ def write_file(filepath,
localIsSmooth = 'vertex'
else:
localIsSmooth = 'face'
fw('\tNormal(%s) : %d\n\t\t' % (localIsSmooth, len(face_index_pairs)) )
fw('\t\tNormal(%s) : %d\n\t\t\t' % (localIsSmooth, len(face_index_pairs)) )
for f, f_index in face_index_pairs:
if f.use_smooth:
for v_idx in f.vertices:
@ -554,7 +472,7 @@ def write_file(filepath,
###########################################################
## faces
###########################################################
fw('\tFace : %d' % len(face_index_pairs))
fw('\t\tFace : %d' % len(face_index_pairs))
for f, f_index in face_index_pairs:
f_smooth = f.use_smooth
f_mat = min(f.material_index, len(materials) - 1)
@ -572,7 +490,7 @@ def write_file(filepath,
else:
if key[0] is None and key[1] is None:
# inform the use of a material :
fw("\n\t\t---:") # mat, image
fw("\n\t\t\t---:") # mat, image
else:
mat_data = mtl_dict.get(key)
if not mat_data:
@ -597,7 +515,7 @@ def write_file(filepath,
mat_data = mtl_dict[key] = mtl_name, materials[f_mat], f_image
mtl_rev_dict[mtl_name] = key
# set the use of a material :
fw("\n\t\t%s:" % mat_data[0]) # can be mat_image or (null)
fw("\n\t\t\t%s\n\t\t\t\t" % mat_data[0]) # can be mat_image or (null)
contextMat = key
f_v = [(vi, me_verts[v_idx]) for vi, v_idx in enumerate(f.vertices)]
if faceuv:
@ -646,16 +564,19 @@ def write_file(filepath,
bpy.data.meshes.remove(me)
if ob_main.dupli_type != 'NONE':
ob_main.dupli_list_clear()
#####################################################################
## Save collision shapes (for one object :
#####################################################################
for subObj in getChildren(ob_main):
print(" child : '%s'" % (subObj.name))
if subObj.name.lower() == EXPORT_COLLISION_NAME:
print(" find physic : '%s'" % (subObj.name))
writeCollisionShape(subObj, file)
#####################################################################
## Now we have all our materials, save them in the material section
#####################################################################
write_mtl(scene, file, mtlfilepath, EXPORT_PATH_MODE, copy_set, mtl_dict)
#####################################################################
## Save collision shapes :
#####################################################################
# writeCollisionShape(ob_main, file, EXPORT_COLLISION_NAME)
writeCollisionShape(objects, file, EXPORT_COLLISION_NAME)
#####################################################################
## End of the file generation:
@ -667,15 +588,6 @@ def write_file(filepath,
print("EMF Export time: %.2f" % (time.time() - time1))
def getChildren(obj, allObj):
children = []
for ob in allObj:
if ob.parent == obj:
children.append(ob)
if len(children) != 0:
return children
else:
return None
"""
" @brief generate the requested object file ... with his material inside and ...
@ -710,23 +622,6 @@ def _write(context,
full_path = ''.join(context_name)
for objj in objects:
print("Object : '%s'" % (objj.name))
for subObj in getChildren(objj, scene.objects):
print(" find subObject : '%s'" % (subObj.name))
#print("-----------------------------------------------------------------------")
#print("Display object game property : ")
#for objj in objects:
# print(" Object : '%s' : %s" % (objj.name, str(objj.game)))
# for element
# print(" actor : '%s'" % str(objj.game.use_actor))
# print(" type : '%s'" % str(objj.game.collision_bounds_type))
# print(" physique : '%s'" % str(objj.game.physics_type))
#print("-----------------------------------------------------------------------")
#print("plop:%s" % (str(dir(bpy.data.objects["Cube"].game)))
#result : plop:['__doc__', '__module__', '__slots__', 'actuators', 'bl_rna', 'collision_bounds_type', 'collision_group', 'collision_margin', 'collision_mask', 'controllers', 'damping', 'fall_speed', 'form_factor', 'friction_coefficients', 'jump_speed', 'lock_location_x', 'lock_location_y', 'lock_location_z', 'lock_rotation_x', 'lock_rotation_y', 'lock_rotation_z', 'mass', 'obstacle_radius', 'physics_type', 'properties', 'radius', 'rna_type', 'rotation_damping', 'sensors', 'show_actuators', 'show_controllers', 'show_debug_state', 'show_sensors', 'show_state_panel', 'soft_body', 'states_initial', 'states_visible', 'step_height', 'use_activity_culling', 'use_actor', 'use_all_states', 'use_anisotropic_friction', 'use_collision_bounds', 'use_collision_compound', 'use_ghost', 'use_material_physics_fh', 'use_obstacle_create', 'use_rotate_from_normal', 'use_sleep', 'used_states', 'velocity_max', 'velocity_min']
write_file(full_path,
objects,
scene,

View File

@ -70,12 +70,6 @@ ewol::Mesh::Mesh(const etk::UString& _fileName, const etk::UString& _shaderName)
// get the shader resource :
m_GLPosition = 0;
// set the element material properties :
//m_material.SetAmbientFactor(vec4(0.100000,0.100000,0.100000, 1.0));
//m_material.SetDiffuseFactor(vec4(0.640000, 0.640000, 0.640000, 1.0));
//m_material.SetSpecularFactor(vec4(0.500000, 0.500000, 0.500000, 1.0));
//m_material.SetShininess(0.96078431);
m_light.SetDirection(vec3(0,cos(M_PI/4),sin(M_PI/4)));
m_light.SetHalfPlane(vec3(1,0,0));
m_light.SetAmbientColor(vec4(1,1,1,1));