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
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 = '%.6g %.6g %.6g' % (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 = '%.6g %.6g %.6g' % (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 = '%.6g %.6g %.6g' % ((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(['%.6g' % (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 = image.filepath
filepath_full = bpy.path.abspath(filepath)
filepath_ref = bpy_extras.io_utils.path_reference(filepath_full, base_src, base_dst, path_mode, "textures", copy_set)
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="%.3g %.3g %.3g"\n' % grd_triple)
fw(ident_step + 'skyColor="%.3g %.3g %.3g"\n' % grd_triple)
# Blend Gradient
elif blending == (True, False, False):
fw(ident_step + 'groundColor="%.3g %.3g %.3g, %.3g %.3g %.3g"\n' % (grd_triple + mix_triple))
fw(ident_step + 'groundAngle="1.57, 1.57"\n')
fw(ident_step + 'skyColor="%.3g %.3g %.3g, %.3g %.3g %.3g"\n' % (sky_triple + mix_triple))
fw(ident_step + 'skyAngle="1.57, 1.57"\n')
# Blend+Real Gradient Inverse
elif blending == (True, False, True):
fw(ident_step + 'groundColor="%.3g %.3g %.3g, %.3g %.3g %.3g"\n' % (sky_triple + grd_triple))
fw(ident_step + 'groundAngle="1.57"\n')
fw(ident_step + 'skyColor="%.3g %.3g %.3g, %.3g %.3g %.3g, %.3g %.3g %.3g"\n' % (sky_triple + grd_triple + sky_triple))
fw(ident_step + 'skyAngle="1.57, 3.14159"\n')
# Paper - just Zen Color
elif blending == (False, False, True):
fw(ident_step + 'groundColor="%.3g %.3g %.3g"\n' % sky_triple)
fw(ident_step + 'skyColor="%.3g %.3g %.3g"\n' % sky_triple)
# Blend+Real+Paper - komplex gradient
elif blending == (True, True, True):
fw(ident_step + 'groundColor="%.3g %.3g %.3g, %.3g %.3g %.3g"\n' % (sky_triple + grd_triple))
fw(ident_step + 'groundAngle="1.57, 1.57"\n')
fw(ident_step + 'skyColor="%.3g %.3g %.3g, %.3g %.3g %.3g"\n' % (sky_triple + grd_triple))
fw(ident_step + 'skyAngle="1.57, 1.57"\n')
# Any Other two colors
else:
fw(ident_step + 'groundColor="%.3g %.3g %.3g"\n' % grd_triple)
fw(ident_step + 'skyColor="%.3g %.3g %.3g"\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'
elif obj_type in {'MESH', 'CURVE', 'SURF', 'FONT'}:
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
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
else:
me = obj.data
if me is not None:
writeIndexedFaceSet(ident, obj, me, obj_matrix, world)
# free mesh created with create_mesh()
if me != obj.data:
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)
# copy all collected files.
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'}