Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
case SFFLOAT: return "SFFloat";
case MFFLOAT: return "MFFloat";
case SFDOUBLE: return "SFDouble";
case MFDOUBLE: return "MFDouble";
case SFTIME: return "SFTime";
case MFTIME: return "MFTime";
case SFINT32: return "SFInt32";
case MFINT32: return "MFInt32";
case SFVEC2F: return "SFVec2f";
case MFVEC2F: return "MFVec2f";
case SFVEC2D: return "SFVec2d";
case MFVEC2D: return "MFVec2d";
case SFVEC3F: return "SFVec3f";
case MFVEC3F: return "MFVec3f";
case SFVEC3D: return "SFVec3d";
case MFVEC3D: return "MFVec3d";
case SFVEC4F: return "SFVec4f";
case MFVEC4F: return "MFVec4f";
case SFVEC4D: return "SFVec4d";
case MFVEC4D: return "MFVec4d";
case SFBOOL: return "SFBool";
case MFBOOL: return "MFBool";
case SFSTRING: return "SFString";
case MFSTRING: return "MFString";
case SFNODE: return "SFNode";
case MFNODE: return "MFNode";
case SFCOLOR: return "SFColor";
case MFCOLOR: return "MFColor";
case SFCOLORRGBA: return "SFColorRGBA";
case MFCOLORRGBA: return "MFColorRGBA";
case SFROTATION: return "SFRotation";
case MFROTATION: return "MFRotation";
case SFQUATERNION: return "SFQuaternion";
case MFQUATERNION: return "MFQuaternion";
case SFMATRIX3F: return "SFMatrix3f";
case MFMATRIX3F: return "MFMatrix3f";
case SFMATRIX4F: return "SFMatrix4f";
case MFMATRIX4F: return "MFMatrix4f";
case SFMATRIX3D: return "SFMatrix3d";
case MFMATRIX3D: return "MFMatrix3d";
case SFMATRIX4D: return "SFMatrix4d";
case MFMATRIX4D: return "MFMatrix4d";
default:return "UNKNOWN_X3D_TYPE";
'''
import gpu
Campbell Barton
committed
fw('%s<ComposedShader DEF=%s language="GLSL" >\n' % (ident, material_id))
shader_url_frag = 'shaders/%s_%s.frag' % (filename_strip, material_id[1:-1])
shader_url_vert = 'shaders/%s_%s.vert' % (filename_strip, material_id[1:-1])
shader_dir = os.path.join(base_dst, 'shaders')
if not os.path.isdir(shader_dir):
os.mkdir(shader_dir)
# ------------------------------------------------------
# shader-patch
field_descr = " <!--- H3D View Matrix Patch -->"
fw('%s<field name="%s" type="SFMatrix4f" accessType="inputOutput" />%s\n' % (ident, H3D_VIEW_MATRIX, field_descr))
frag_vars = ["uniform mat4 %s;" % H3D_VIEW_MATRIX]
# annoying!, we need to track if some of the directional lamp
# vars are children of the camera or not, since this adjusts how
# they are patched.
frag_uniform_var_map = {}
h3d_material_route.append(
'<ROUTE fromNode="%s" fromField="glModelViewMatrix" toNode=%s toField="%s" />%s' %
(H3D_TOP_LEVEL, material_id, H3D_VIEW_MATRIX, field_descr))
# ------------------------------------------------------
for uniform in gpu_shader['uniforms']:
if uniform['type'] == gpu.GPU_DYNAMIC_SAMPLER_2DIMAGE:
field_descr = " <!--- Dynamic Sampler 2d Image -->"
fw('%s<field name="%s" type="SFNode" accessType="inputOutput">%s\n' % (ident, uniform['varname'], field_descr))
writeImageTexture(ident + '\t', uniform['image'])
elif uniform['type'] == gpu.GPU_DYNAMIC_LAMP_DYNCO:
lamp_obj = uniform['lamp']
frag_uniform_var_map[uniform['varname']] = lamp_obj
if uniform['datatype'] == gpu.GPU_DATA_3F: # should always be true!
Campbell Barton
committed
lamp_obj_id = quoteattr(unique_name(lamp_obj, 'LA_' + lamp_obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_"))
lamp_obj_transform_id = quoteattr(unique_name(lamp_obj, lamp_obj.name, uuid_cache_object, clean_func=clean_def, sep="_"))
value = '%.6f %.6f %.6f' % (global_matrix * lamp_obj.matrix_world).to_translation()[:]
field_descr = " <!--- Lamp DynCo '%s' -->" % lamp_obj.name
fw('%s<field name="%s" type="SFVec3f" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
# ------------------------------------------------------
# shader-patch
field_descr = " <!--- Lamp DynCo '%s' (shader patch) -->" % lamp_obj.name
fw('%s<field name="%s_transform" type="SFMatrix4f" accessType="inputOutput" />%s\n' % (ident, uniform['varname'], field_descr))
# transform
frag_vars.append("uniform mat4 %s_transform;" % uniform['varname'])
h3d_material_route.append(
'<ROUTE fromNode=%s fromField="accumulatedForward" toNode=%s toField="%s_transform" />%s' %
(suffix_quoted_str(lamp_obj_transform_id, "_TRANSFORM"), material_id, uniform['varname'], field_descr))
h3d_material_route.append(
'<ROUTE fromNode=%s fromField="location" toNode=%s toField="%s" /> %s' %
(lamp_obj_id, material_id, uniform['varname'], field_descr))
# ------------------------------------------------------
else:
assert(0)
elif uniform['type'] == gpu.GPU_DYNAMIC_LAMP_DYNCOL:
# odd we have both 3, 4 types.
lamp_obj = uniform['lamp']
frag_uniform_var_map[uniform['varname']] = lamp_obj
value = '%.6f %.6f %.6f' % (lamp.color * lamp.energy)[:]
field_descr = " <!--- Lamp DynColor '%s' -->" % lamp_obj.name
fw('%s<field name="%s" type="SFVec3f" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
fw('%s<field name="%s" type="SFVec4f" accessType="inputOutput" value="%s 1.0" />%s\n' % (ident, uniform['varname'], value, field_descr))
elif uniform['type'] == gpu.GPU_DYNAMIC_LAMP_DYNENERGY:
# not used ?
assert(0)
elif uniform['type'] == gpu.GPU_DYNAMIC_LAMP_DYNVEC:
lamp_obj = uniform['lamp']
frag_uniform_var_map[uniform['varname']] = lamp_obj
lamp_obj = uniform['lamp']
value = '%.6f %.6f %.6f' % ((global_matrix * lamp_obj.matrix_world).to_quaternion() * mathutils.Vector((0.0, 0.0, 1.0))).normalized()[:]
field_descr = " <!--- Lamp DynDirection '%s' -->" % lamp_obj.name
fw('%s<field name="%s" type="SFVec3f" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
# route so we can have the lamp update the view
if h3d_is_object_view(scene, lamp_obj):
lamp_id = quoteattr(unique_name(lamp_obj, 'LA_' + lamp_obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_"))
h3d_material_route.append(
'<ROUTE fromNode=%s fromField="direction" toNode=%s toField="%s" />%s' %
(lamp_id, material_id, uniform['varname'], field_descr))
else:
assert(0)
elif uniform['type'] == gpu.GPU_DYNAMIC_OBJECT_VIEWIMAT:
frag_uniform_var_map[uniform['varname']] = None
if uniform['datatype'] == gpu.GPU_DATA_16F:
# must be updated dynamically
# TODO, write out 'viewpointMatrices.py'
value = ' '.join(['%.6f' % f for v in mathutils.Matrix() for f in v])
field_descr = " <!--- Object View Matrix '%s' -->" % obj.name
fw('%s<field name="%s" type="SFMatrix4f" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
else:
assert(0)
elif uniform['type'] == gpu.GPU_DYNAMIC_OBJECT_IMAT:
frag_uniform_var_map[uniform['varname']] = None
value = ' '.join(['%.6f' % f for v in (global_matrix * obj.matrix_world).inverted() for f in v])
field_descr = " <!--- Object Invertex Matrix '%s' -->" % obj.name
fw('%s<field name="%s" type="SFMatrix4f" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
else:
assert(0)
elif uniform['type'] == gpu.GPU_DYNAMIC_SAMPLER_2DSHADOW:
pass # XXX, shadow buffers not supported.
elif uniform['type'] == gpu.GPU_DYNAMIC_SAMPLER_2DBUFFER:
frag_uniform_var_map[uniform['varname']] = None
if uniform['datatype'] == gpu.GPU_DATA_1I:
if 1:
tex = uniform['texpixels']
value = []
for i in range(0, len(tex) - 1, 4):
col = tex[i:i + 4]
value.append('0x%.2x%.2x%.2x%.2x' % (col[0], col[1], col[2], col[3]))
field_descr = " <!--- Material Buffer -->"
fw('%s<field name="%s" type="SFNode" accessType="inputOutput">%s\n' % (ident, uniform['varname'], field_descr))
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<PixelTexture \n' % ident)))
fw(ident_step + 'repeatS="false"\n')
fw(ident_step + 'repeatT="false"\n')
fw(ident_step + 'image="%s 1 4 %s"\n' % (len(value), " ".join(value)))
fw(ident_step + '/>\n')
ident = ident[:-1]
fw('%s</field>\n' % ident)
#for i in range(0, 10, 4)
#value = ' '.join(['%d' % f for f in uniform['texpixels']])
# value = ' '.join(['%.6f' % (f / 256) for f in uniform['texpixels']])
#fw('%s<field name="%s" type="SFInt32" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
#print('test', len(uniform['texpixels']))
else:
print("SKIPPING", uniform['type'])
file_frag = open(os.path.join(base_dst, shader_url_frag), 'w')
file_frag.write(gpu_shader['fragment'])
file_frag.close()
h3d_shader_glsl_frag_patch(os.path.join(base_dst, shader_url_frag),
scene,
frag_vars,
frag_uniform_var_map,
)
file_vert = open(os.path.join(base_dst, shader_url_vert), 'w')
file_vert.write(gpu_shader['vertex'])
file_vert.close()
fw('%s<ShaderPart type="FRAGMENT" url="%s" />\n' % (ident, shader_url_frag))
fw('%s<ShaderPart type="VERTEX" url="%s" />\n' % (ident, shader_url_vert))
ident = ident[:-1]
fw('%s</ComposedShader>\n' % ident)
def writeImageTexture(ident, image):
Campbell Barton
committed
image_id = quoteattr(unique_name(image, 'IM_' + image.name, uuid_cache_image, clean_func=clean_def, sep="_"))
if image.tag:
Campbell Barton
committed
fw('%s<ImageTexture USE=%s />\n' % (ident, image_id))
else:
image.tag = True
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<ImageTexture ' % ident)))
Campbell Barton
committed
fw('DEF=%s\n' % image_id)
# collect image paths, can load multiple
Campbell Barton
committed
# [relative, name-only, absolute]
filepath_full = bpy.path.abspath(filepath, library=image.library)
filepath_ref = bpy_extras.io_utils.path_reference(filepath_full, base_src, base_dst, path_mode, "textures", copy_set, image.library)
filepath_base = os.path.basename(filepath_full)
filepath_base,
images = [f.replace('\\', '/') for f in images]
images = [f for i, f in enumerate(images) if f not in images[:i]]
fw(ident_step + "url='%s' " % ' '.join(['"%s"' % f for f in images]))
Campbell Barton
committed
def writeBackground(ident, world):
Campbell Barton
committed
if world is None:
return
Campbell Barton
committed
# note, not re-used
Campbell Barton
committed
world_id = quoteattr(unique_name(world, 'WO_' + world.name, uuid_cache_world, clean_func=clean_def, sep="_"))
Campbell Barton
committed
blending = world.use_sky_blend, world.use_sky_paper, world.use_sky_real
grd_triple = clamp_color(world.horizon_color)
sky_triple = clamp_color(world.zenith_color)
mix_triple = clamp_color((grd_triple[i] + sky_triple[i]) / 2.0 for i in range(3))
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<Background ' % ident)))
Campbell Barton
committed
fw('DEF=%s\n' % world_id)
# No Skytype - just Hor color
if blending == (False, False, False):
fw(ident_step + 'groundColor="%.3f %.3f %.3f"\n' % grd_triple)
fw(ident_step + 'skyColor="%.3f %.3f %.3f"\n' % grd_triple)
# Blend Gradient
elif blending == (True, False, False):
fw(ident_step + 'groundColor="%.3f %.3f %.3f, %.3f %.3f %.3f"\n' % (grd_triple + mix_triple))
fw(ident_step + 'skyColor="%.3f %.3f %.3f, %.3f %.3f %.3f"\n' % (sky_triple + mix_triple))
# Blend+Real Gradient Inverse
elif blending == (True, False, True):
fw(ident_step + 'groundColor="%.3f %.3f %.3f, %.3f %.3f %.3f"\n' % (sky_triple + grd_triple))
fw(ident_step + 'skyColor="%.3f %.3f %.3f, %.3f %.3f %.3f, %.3f %.3f %.3f"\n' % (sky_triple + grd_triple + sky_triple))
# Paper - just Zen Color
elif blending == (False, False, True):
fw(ident_step + 'groundColor="%.3f %.3f %.3f"\n' % sky_triple)
fw(ident_step + 'skyColor="%.3f %.3f %.3f"\n' % sky_triple)
# Blend+Real+Paper - komplex gradient
elif blending == (True, True, True):
fw(ident_step + 'groundColor="%.3f %.3f %.3f, %.3f %.3f %.3f"\n' % (sky_triple + grd_triple))
fw(ident_step + 'skyColor="%.3f %.3f %.3f, %.3f %.3f %.3f"\n' % (sky_triple + grd_triple))
# Any Other two colors
else:
fw(ident_step + 'groundColor="%.3f %.3f %.3f"\n' % grd_triple)
fw(ident_step + 'skyColor="%.3f %.3f %.3f"\n' % sky_triple)
if tex.type == 'IMAGE' and tex.image:
namemat = tex.name
pic = tex.image
basename = bpy.path.basename(pic.filepath)
fw(ident_step + 'bottomUrl="%s"\n' % basename)
# -------------------------------------------------------------------------
# Export Object Hierarchy (recursively called)
# -------------------------------------------------------------------------
def export_object(ident, obj_main_parent, obj_main, obj_children):
world = scene.world
free, derived = create_derived_objects(scene, obj_main)
if use_hierarchy:
obj_main_matrix_world = obj_main.matrix_world
if obj_main_parent:
obj_main_matrix = obj_main_parent.matrix_world.inverted() * obj_main_matrix_world
else:
obj_main_matrix = obj_main_matrix_world
obj_main_matrix_world_invert = obj_main_matrix_world.inverted()
Campbell Barton
committed
obj_main_id = quoteattr(unique_name(obj_main, obj_main.name, uuid_cache_object, clean_func=clean_def, sep="_"))
ident = writeTransform_begin(ident, obj_main_matrix if obj_main_parent else global_matrix * obj_main_matrix, suffix_quoted_str(obj_main_id, "_TRANSFORM"))
for obj, obj_matrix in (() if derived is None else derived):
obj_type = obj.type
if use_hierarchy:
# make transform node relative
obj_matrix = obj_main_matrix_world_invert * obj_matrix
# H3D - use for writing a dummy transform parent
is_dummy_tx = False
if obj_type == 'CAMERA':
writeViewpoint(ident, obj, obj_matrix, scene)
if use_h3d and scene.camera == obj:
view_id = uuid_cache_view[obj]
fw('%s<Transform DEF="%s">\n' % (ident, H3D_CAMERA_FOLLOW))
h3d_material_route.extend([
'<ROUTE fromNode="%s" fromField="totalPosition" toNode="%s" toField="translation" />' % (view_id, H3D_CAMERA_FOLLOW),
'<ROUTE fromNode="%s" fromField="totalOrientation" toNode="%s" toField="rotation" />' % (view_id, H3D_CAMERA_FOLLOW),
])
is_dummy_tx = True
ident += '\t'
Campbell Barton
committed
elif obj_type in {'MESH', 'CURVE', 'SURFACE', 'FONT'}:
if (obj_type != 'MESH') or (use_apply_modifiers and obj.is_modified(scene, 'PREVIEW')):
try:
me = obj.to_mesh(scene, use_apply_modifiers, 'PREVIEW')
except:
me = None
do_remove = True
else:
me = obj.data
do_remove = False
if me is not None:
# ensure unique name, we could also do this by
# postponing mesh removal, but clearing data - TODO
if do_remove:
me.name = obj.name.rstrip("1234567890").rstrip(".")
me_name_new = me_name_org = me.name
count = 0
while me_name_new in mesh_name_set:
me.name = "%.17s.%03d" % (me_name_org, count)
me_name_new = me.name
count += 1
mesh_name_set.add(me_name_new)
del me_name_new, me_name_org, count
# done
writeIndexedFaceSet(ident, obj, me, obj_matrix, world)
# free mesh created with create_mesh()
if do_remove:
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
bpy.data.meshes.remove(me)
elif obj_type == 'LAMP':
data = obj.data
datatype = data.type
if datatype == 'POINT':
writePointLight(ident, obj, obj_matrix, data, world)
elif datatype == 'SPOT':
writeSpotLight(ident, obj, obj_matrix, data, world)
elif datatype == 'SUN':
writeDirectionalLight(ident, obj, obj_matrix, data, world)
else:
writeDirectionalLight(ident, obj, obj_matrix, data, world)
else:
#print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
pass
if free:
free_derived_objects(obj_main)
# ---------------------------------------------------------------------
# write out children recursively
# ---------------------------------------------------------------------
for obj_child, obj_child_children in obj_children:
export_object(ident, obj_main, obj_child, obj_child_children)
if is_dummy_tx:
ident = ident[:-1]
fw('%s</Transform>\n' % ident)
is_dummy_tx = False
if use_hierarchy:
ident = writeTransform_end(ident)
# -------------------------------------------------------------------------
# Main Export Function
# -------------------------------------------------------------------------
# tag un-exported IDs
bpy.data.meshes.tag(False)
bpy.data.materials.tag(False)
bpy.data.images.tag(False)
print('Info: starting X3D export to %r...' % file.name)
ident = ''
ident = writeHeader(ident)
Campbell Barton
committed
writeNavigationInfo(ident, scene)
writeBackground(ident, world)
writeFog(ident, world)
Campbell Barton
committed
Campbell Barton
committed
if use_selection:
objects = [obj for obj in scene.objects if obj.is_visible(scene) and obj.select]
Campbell Barton
committed
else:
objects = [obj for obj in scene.objects if obj.is_visible(scene)]
Campbell Barton
committed
if use_hierarchy:
objects_hierarchy = build_hierarchy(objects)
else:
objects_hierarchy = ((obj, []) for obj in objects)
for obj_main, obj_main_children in objects_hierarchy:
export_object(ident, None, obj_main, obj_main_children)
ident = writeFooter(ident)
# -------------------------------------------------------------------------
# global cleanup
# -------------------------------------------------------------------------
if use_h3d:
bpy.data.materials.remove(gpu_shader_dummy_mat)
# print(copy_set)
bpy_extras.io_utils.path_reference_copy(copy_set)
print('Info: finished X3D export to %r' % file.name)
##########################################################
# Callbacks, needed before Main
##########################################################
def save(operator, context, filepath="",
use_selection=True,
use_apply_modifiers=False,
use_triangulate=False,
use_hierarchy=True,
Campbell Barton
committed
bpy.path.ensure_ext(filepath, '.x3dz' if use_compress else '.x3d')
if bpy.ops.object.mode_set.poll():
bpy.ops.object.mode_set(mode='OBJECT')
Campbell Barton
committed
file = gzip.open(filepath, 'w')
else:
if global_matrix is None:
global_matrix = mathutils.Matrix()
export(file,
global_matrix,
context.scene,
use_apply_modifiers=use_apply_modifiers,
use_selection=use_selection,
use_triangulate=use_triangulate,
use_normals=use_normals,
use_hierarchy=use_hierarchy,
return {'FINISHED'}