提交 d047a711 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #10621 from phfatmonkey/Blender_Exporter_Object_Export_with_Skinned_Mesh

Blender exporter object export with skinned mesh
......@@ -41,6 +41,7 @@ NUMERIC = {
'SphericalReflectionMapping': 305,
'RepeatWrapping': 1000,
'repeat': 1000,
'ClampToEdgeWrapping': 1001,
'MirroredRepeatWrapping': 1002,
......
......@@ -12,6 +12,33 @@ from . import object as object_
from .. import constants, utilities, logger, exceptions
# flips vectors
#TODO: add these strings into constants.py
XZ_Y = "XZ_Y"
X_ZY = "X_ZY"
XYZ = "XYZ"
_XY_Z = "_XY_Z"
def flip_axes (a, dir=XYZ):
"""
:function to swap vectors:
"""
if dir == XZ_Y:
a = (a[0], a[2], -a[1])
elif dir == X_ZY:
a = (a[0], -a[2], a[1])
elif dir == _XY_Z:
a = (-a[0], -a[1], a[2])
return (a[0], a[1], a[2])
def _mesh(func):
"""
......@@ -107,7 +134,7 @@ def bones(mesh, options):
@_mesh
def buffer_normal(mesh):
def buffer_normal(mesh, options):
"""
:param mesh:
......@@ -122,16 +149,43 @@ def buffer_normal(mesh):
msg = "Non-triangulated face detected"
raise exceptions.BufferGeometryError(msg)
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = (normal.x, normal.y, normal.z) if face.use_smooth else (face.normal.x, face.normal.y, face.normal.z)
normals_.extend(vector)
# using Object Loader with skinned mesh
if options.get(constants.SCENE, True) and _armature(mesh):
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = flip_axes(normal, XZ_Y) if face.use_smooth else flip_axes(face.normal, XZ_Y)
normals_.extend(vector)
# using Object Loader with static mesh
elif options.get(constants.SCENE, True) and not _armature(mesh):
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = flip_axes(normal, _XY_Z) if face.use_smooth else flip_axes(face.normal, _XY_Z)
normals_.extend(vector)
# using JSON Loader with skinned mesh
elif not options.get(constants.SCENE, True) and _armature(mesh):
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = flip_axes(normal) if face.use_smooth else flip_axes(face.normal)
normals_.extend(vector)
# using JSON Loader with static mesh
else:
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = flip_axes(normal) if face.use_smooth else flip_axes(face.normal)
normals_.extend(vector)
return normals_
@_mesh
def buffer_position(mesh):
def buffer_position(mesh, options):
"""
:param mesh:
......@@ -146,10 +200,37 @@ def buffer_position(mesh):
msg = "Non-triangulated face detected"
raise exceptions.BufferGeometryError(msg)
for vertex_index in face.vertices:
vertex = mesh.vertices[vertex_index]
vector = (vertex.co.x, vertex.co.y, vertex.co.z)
position.extend(vector)
# using Object Loader with skinned mesh
if options.get(constants.SCENE, True) and _armature(mesh):
for vertex_index in face.vertices:
vertex = mesh.vertices[vertex_index]
vector = flip_axes(vertex.co, XZ_Y)
position.extend(vector)
# using Object Loader with static mesh
elif options.get(constants.SCENE, True) and not _armature(mesh):
for vertex_index in face.vertices:
vertex = mesh.vertices[vertex_index]
vector = flip_axes(vertex.co, _XY_Z)
position.extend(vector)
# using JSON Loader with skinned mesh
elif not options.get(constants.SCENE, True) and _armature(mesh):
for vertex_index in face.vertices:
vertex = mesh.vertices[vertex_index]
vector = flip_axes(vertex.co)
position.extend(vector)
# using JSON Loader with static mesh
else:
for vertex_index in face.vertices:
vertex = mesh.vertices[vertex_index]
vector = flip_axes(vertex.co)
position.extend(vector)
return position
......@@ -293,7 +374,7 @@ def faces(mesh, options, material_list=None):
logger.debug("Normals enabled = %s", opt_normals)
uv_indices = _uvs(mesh)[1] if opt_uvs else None
vertex_normals = _normals(mesh) if opt_normals else None
vertex_normals = _normals(mesh, options) if opt_normals else None
vertex_colours = vertex_colors(mesh) if opt_colours else None
faces_data = []
......@@ -305,11 +386,37 @@ def faces(mesh, options, material_list=None):
colour_indices[str(colour)] = index
normal_indices = {}
if vertex_normals:
logger.debug("Indexing normals")
for index, normal in enumerate(vertex_normals):
normal = (normal[0], normal[2], -normal[1])
normal_indices[str(normal)] = index
# using Object Loader with skinned mesh
if options.get(constants.SCENE, True) and _armature(mesh):
for index, normal in enumerate(vertex_normals):
normal = flip_axes(normal, XYZ)
normal_indices[str(normal)] = index
# using Object Loader with static mesh
elif options.get(constants.SCENE, True) and not _armature(mesh):
for index, normal in enumerate(vertex_normals):
normal = flip_axes(normal, XYZ)
normal_indices[str(normal)] = index
# using JSON Loader with skinned mesh
elif not options.get(constants.SCENE, True) and _armature(mesh):
for index, normal in enumerate(vertex_normals):
normal = flip_axes(normal)
normal_indices[str(normal)] = index
# using JSON Loader with static mesh
else:
for index, normal in enumerate(vertex_normals):
normal = flip_axes(normal)
normal_indices[str(normal)] = index
logger.info("Parsing %d faces", len(mesh.tessfaces))
for face in mesh.tessfaces:
......@@ -355,11 +462,43 @@ def faces(mesh, options, material_list=None):
mask[constants.UVS] = True
if vertex_normals:
for vertex in face.vertices:
normal = mesh.vertices[vertex].normal
normal = (normal.x, normal.z, -normal.y) if face.use_smooth else (face.normal.x, face.normal.z, -face.normal.y)
face_data.append(normal_indices[str(normal)])
mask[constants.NORMALS] = True
# using Object Loader with skinned mesh
if options.get(constants.SCENE, True) and _armature(mesh):
for vertex in face.vertices:
normal = mesh.vertices[vertex].normal
normal = flip_axes(normal, XZ_Y) if face.use_smooth else flip_axes(face.normal, XZ_Y)
face_data.append(normal_indices[str(normal)])
mask[constants.NORMALS] = True
# using Object Loader with static mesh
elif options.get(constants.SCENE, True) and not _armature(mesh):
for vertex in face.vertices:
normal = mesh.vertices[vertex].normal
normal = flip_axes(normal, _XY_Z) if face.use_smooth else flip_axes(face.normal, _XY_Z)
face_data.append(normal_indices[str(normal)])
mask[constants.NORMALS] = True
# using JSON Loader with skinned mesh
elif not options.get(constants.SCENE, True) and _armature(mesh):
for vertex in face.vertices:
normal = mesh.vertices[vertex].normal
normal = flip_axes(normal) if face.use_smooth else flip_axes(face.normal)
face_data.append(normal_indices[str(normal)])
mask[constants.NORMALS] = True
# using JSON Loader with static mesh
else:
for vertex in face.vertices:
normal = mesh.vertices[vertex].normal
normal = flip_axes(normal) if face.use_smooth else flip_axes(face.normal)
face_data.append(normal_indices[str(normal)])
mask[constants.NORMALS] = True
if vertex_colours:
colours = mesh.tessface_vertex_colors.active.data[face.index]
......@@ -403,8 +542,29 @@ def morph_targets(mesh, options):
morphs.append([])
vertices_ = object_.extract_mesh(obj, options).vertices[:]
for vertex in vertices_:
morphs[-1].extend([vertex.co.x, vertex.co.y, vertex.co.z])
# using Object Loader with skinned mesh
if options.get(constants.SCENE, True) and _armature(mesh):
for vertex in vertices_:
morphs[-1].extend(flip_axes(vertex.co, XZ_Y))
# using Object Loader with static mesh
elif options.get(constants.SCENE, True) and not _armature(mesh):
for vertex in vertices_:
morphs[-1].extend(flip_axes(vertex.co, _XY_Z))
# using JSON Loader with skinned mesh
elif not options.get(constants.SCENE, True) and _armature(mesh):
for vertex in vertices_:
morphs[-1].extend(flip_axes(vertex.co))
# using JSON Loader with static mesh
else:
for vertex in vertices_:
morphs[-1].extend(flip_axes(vertex.co))
context.scene.frame_set(original_frame, 0.0)
morphs_detected = False
......@@ -605,7 +765,7 @@ def materials(mesh, options):
@_mesh
def normals(mesh):
def normals(mesh, options):
"""
:param mesh:
......@@ -615,7 +775,7 @@ def normals(mesh):
logger.debug("mesh.normals(%s)", mesh)
normal_vectors = []
for vector in _normals(mesh):
for vector in _normals(mesh, options):
normal_vectors.extend(vector)
return normal_vectors
......@@ -752,7 +912,7 @@ def vertex_colors(mesh):
@_mesh
def vertices(mesh):
def vertices(mesh, options):
"""
:param mesh:
......@@ -762,8 +922,29 @@ def vertices(mesh):
logger.debug("mesh.vertices(%s)", mesh)
vertices_ = []
for vertex in mesh.vertices:
vertices_.extend((vertex.co.x, vertex.co.y, vertex.co.z))
# using Object Loader with skinned mesh
if options.get(constants.SCENE, True) and _armature(mesh):
for vertex in mesh.vertices:
vertices_.extend(flip_axes(vertex.co, XZ_Y))
# using Object Loader with static mesh
elif options.get(constants.SCENE, True) and not _armature(mesh):
for vertex in mesh.vertices:
vertices_.extend(flip_axes(vertex.co, _XY_Z))
# using JSON Loader with skinned mesh
elif not options.get(constants.SCENE, True) and _armature(mesh):
for vertex in mesh.vertices:
vertices_.extend(flip_axes(vertex.co))
# using JSON Loader with static mesh
else:
for vertex in mesh.vertices:
vertices_.extend(flip_axes(vertex.co))
return vertices_
......@@ -892,7 +1073,7 @@ def _diffuse_map(mat):
return diffuse
def _normals(mesh):
def _normals(mesh, options):
"""
:param mesh:
......@@ -904,16 +1085,57 @@ def _normals(mesh):
vectors_ = {}
for face in mesh.tessfaces:
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = (normal.x, normal.y, normal.z) if face.use_smooth else (face.normal.x, face.normal.y, face.normal.z)
if options.get(constants.SCENE, True) and _armature(mesh):
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = flip_axes(normal, XZ_Y) if face.use_smooth else flip_axes(face.normal, XZ_Y)
str_vec = str(vector)
try:
vectors_[str_vec]
except KeyError:
vectors.append(vector)
vectors_[str_vec] = True
elif options.get(constants.SCENE, True) and not _armature(mesh):
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = flip_axes(normal,_XY_Z) if face.use_smooth else flip_axes(face.normal,_XY_Z)
str_vec = str(vector)
try:
vectors_[str_vec]
except KeyError:
vectors.append(vector)
vectors_[str_vec] = True
elif not options.get(constants.SCENE, True) and _armature(mesh):
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = flip_axes(normal) if face.use_smooth else flip_axes(face.normal)
str_vec = str(vector)
try:
vectors_[str_vec]
except KeyError:
vectors.append(vector)
vectors_[str_vec] = True
str_vec = str(vector)
try:
vectors_[str_vec]
except KeyError:
vectors.append(vector)
vectors_[str_vec] = True
else:
for vertex_index in face.vertices:
normal = mesh.vertices[vertex_index].normal
vector = flip_axes(normal) if face.use_smooth else flip_axes(face.normal)
str_vec = str(vector)
try:
vectors_[str_vec]
except KeyError:
vectors.append(vector)
vectors_[str_vec] = True
return vectors
......
......@@ -373,13 +373,13 @@ class Geometry(base_classes.BaseNode):
option_index_type = self.options.get(constants.INDEX_TYPE)
pos_tuple = (constants.POSITION, options_vertices,
api.mesh.buffer_position, 3)
lambda m: api.mesh.buffer_position(m, self.options), 3)
uvs_tuple = (constants.UV, option_uvs,
api.mesh.buffer_uv, 2)
uvs2_tuple = (constants.UV2, option_uvs,
lambda m: api.mesh.buffer_uv(m, layer=1), 2)
normals_tuple = (constants.NORMAL, option_normals,
api.mesh.buffer_normal, 3)
lambda m: api.mesh.buffer_normal(m, self.options), 3)
dispatch = (pos_tuple, uvs_tuple, uvs2_tuple, normals_tuple)
for key, option, func, size in dispatch:
......@@ -500,11 +500,11 @@ class Geometry(base_classes.BaseNode):
"""Parse the geometry to Three.Geometry specs"""
if self.options.get(constants.VERTICES):
logger.info("Parsing %s", constants.VERTICES)
self[constants.VERTICES] = api.mesh.vertices(self.node) or []
self[constants.VERTICES] = api.mesh.vertices(self.node, self.options) or []
if self.options.get(constants.NORMALS):
logger.info("Parsing %s", constants.NORMALS)
self[constants.NORMALS] = api.mesh.normals(self.node) or []
self[constants.NORMALS] = api.mesh.normals(self.node, self.options) or []
if self.options.get(constants.COLORS):
logger.info("Parsing %s", constants.COLORS)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册