|
@@ -1,7 +1,7 @@
|
|
bl_info = {
|
|
bl_info = {
|
|
'name': 'Babylon.js',
|
|
'name': 'Babylon.js',
|
|
'author': 'David Catuhe, Jeff Palmer',
|
|
'author': 'David Catuhe, Jeff Palmer',
|
|
- 'version': (4, 0, 1),
|
|
|
|
|
|
+ 'version': (4, 1, 0),
|
|
'blender': (2, 75, 0),
|
|
'blender': (2, 75, 0),
|
|
'location': 'File > Export > Babylon.js (.babylon)',
|
|
'location': 'File > Export > Babylon.js (.babylon)',
|
|
'description': 'Export Babylon.js scenes (.babylon)',
|
|
'description': 'Export Babylon.js scenes (.babylon)',
|
|
@@ -39,7 +39,8 @@ if __name__ == '__main__':
|
|
MAX_VERTEX_ELEMENTS = 65535
|
|
MAX_VERTEX_ELEMENTS = 65535
|
|
MAX_VERTEX_ELEMENTS_32Bit = 16777216
|
|
MAX_VERTEX_ELEMENTS_32Bit = 16777216
|
|
VERTEX_OUTPUT_PER_LINE = 100
|
|
VERTEX_OUTPUT_PER_LINE = 100
|
|
-MAX_FLOAT_PRECISION = '%.4f'
|
|
|
|
|
|
+MAX_FLOAT_PRECISION_INT = 4
|
|
|
|
+MAX_FLOAT_PRECISION = '%.' + str(MAX_FLOAT_PRECISION_INT) + 'f'
|
|
COMPRESS_MATRIX_INDICES = True # this is True for .babylon exporter & False for TOB
|
|
COMPRESS_MATRIX_INDICES = True # this is True for .babylon exporter & False for TOB
|
|
|
|
|
|
# used in World constructor, defined in BABYLON.Scene
|
|
# used in World constructor, defined in BABYLON.Scene
|
|
@@ -756,7 +757,8 @@ class Mesh(FCurveAnimatable):
|
|
if hasSkeleton:
|
|
if hasSkeleton:
|
|
weightsPerVertex = []
|
|
weightsPerVertex = []
|
|
indicesPerVertex = []
|
|
indicesPerVertex = []
|
|
- influenceCounts = [0, 0, 0, 0, 0, 0, 0, 0, 0] # 9, so accessed orign 1
|
|
|
|
|
|
+ influenceCounts = [0, 0, 0, 0, 0, 0, 0, 0, 0] # 9, so accessed orign 1; 0 used for all those greater than 8
|
|
|
|
+ totalInfluencers = 0
|
|
highestInfluenceObserved = 0
|
|
highestInfluenceObserved = 0
|
|
|
|
|
|
# used tracking of vertices as they are received
|
|
# used tracking of vertices as they are received
|
|
@@ -908,7 +910,11 @@ class Mesh(FCurveAnimatable):
|
|
vertices_sk_weights[vertex_index].append(matricesWeights)
|
|
vertices_sk_weights[vertex_index].append(matricesWeights)
|
|
vertices_sk_indices[vertex_index].append(matricesIndices)
|
|
vertices_sk_indices[vertex_index].append(matricesIndices)
|
|
nInfluencers = len(matricesWeights)
|
|
nInfluencers = len(matricesWeights)
|
|
- influenceCounts[nInfluencers] += 1
|
|
|
|
|
|
+ totalInfluencers += nInfluencers
|
|
|
|
+ if nInfluencers <= 8:
|
|
|
|
+ influenceCounts[nInfluencers] += 1
|
|
|
|
+ else:
|
|
|
|
+ influenceCounts[0] += 1
|
|
highestInfluenceObserved = nInfluencers if nInfluencers > highestInfluenceObserved else highestInfluenceObserved
|
|
highestInfluenceObserved = nInfluencers if nInfluencers > highestInfluenceObserved else highestInfluenceObserved
|
|
weightsPerVertex.append(matricesWeights)
|
|
weightsPerVertex.append(matricesWeights)
|
|
indicesPerVertex.append(matricesIndices)
|
|
indicesPerVertex.append(matricesIndices)
|
|
@@ -943,17 +949,9 @@ class Mesh(FCurveAnimatable):
|
|
if (self.numBoneInfluencers > 4):
|
|
if (self.numBoneInfluencers > 4):
|
|
self.skeletonIndicesExtra = Mesh.packSkeletonIndices(self.skeletonIndicesExtra)
|
|
self.skeletonIndicesExtra = Mesh.packSkeletonIndices(self.skeletonIndicesExtra)
|
|
|
|
|
|
- totalInfluencers = influenceCounts[1]
|
|
|
|
- totalInfluencers += influenceCounts[2] * 2
|
|
|
|
- totalInfluencers += influenceCounts[3] * 3
|
|
|
|
- totalInfluencers += influenceCounts[4] * 4
|
|
|
|
- totalInfluencers += influenceCounts[5] * 5
|
|
|
|
- totalInfluencers += influenceCounts[6] * 6
|
|
|
|
- totalInfluencers += influenceCounts[7] * 7
|
|
|
|
- totalInfluencers += influenceCounts[8] * 8
|
|
|
|
Main.log('Total Influencers: ' + format_f(totalInfluencers), 3)
|
|
Main.log('Total Influencers: ' + format_f(totalInfluencers), 3)
|
|
Main.log('Avg # of influencers per vertex: ' + format_f(totalInfluencers / len(self.positions)), 3)
|
|
Main.log('Avg # of influencers per vertex: ' + format_f(totalInfluencers / len(self.positions)), 3)
|
|
- Main.log('Highest # of influencers observed: ' + str(highestInfluenceObserved) + ', num vertices with this: ' + format_int(influenceCounts[highestInfluenceObserved]), 3)
|
|
|
|
|
|
+ Main.log('Highest # of influencers observed: ' + str(highestInfluenceObserved) + ', num vertices with this: ' + format_int(influenceCounts[highestInfluenceObserved if highestInfluenceObserved < 9 else 0]), 3)
|
|
Main.log('exported as ' + str(self.numBoneInfluencers) + ' influencers', 3)
|
|
Main.log('exported as ' + str(self.numBoneInfluencers) + ' influencers', 3)
|
|
nWeights = len(self.skeletonWeights) + len(self.skeletonWeightsExtra) if hasattr(self, 'skeletonWeightsExtra') else 0
|
|
nWeights = len(self.skeletonWeights) + len(self.skeletonWeightsExtra) if hasattr(self, 'skeletonWeightsExtra') else 0
|
|
Main.log('num skeletonWeights and skeletonIndices: ' + str(nWeights), 3)
|
|
Main.log('num skeletonWeights and skeletonIndices: ' + str(nWeights), 3)
|
|
@@ -1241,6 +1239,7 @@ class Bone:
|
|
def __init__(self, bone, skeleton, scene, index):
|
|
def __init__(self, bone, skeleton, scene, index):
|
|
Main.log('processing begun of bone: ' + bone.name + ', index: '+ str(index), 2)
|
|
Main.log('processing begun of bone: ' + bone.name + ', index: '+ str(index), 2)
|
|
self.name = bone.name
|
|
self.name = bone.name
|
|
|
|
+ self.length = bone.length
|
|
self.index = index
|
|
self.index = index
|
|
|
|
|
|
matrix_world = skeleton.matrix_world
|
|
matrix_world = skeleton.matrix_world
|
|
@@ -1267,7 +1266,7 @@ class Bone:
|
|
bpy.context.scene.frame_set(frame)
|
|
bpy.context.scene.frame_set(frame)
|
|
currentBoneMatrix = Bone.get_matrix(bone, matrix_world)
|
|
currentBoneMatrix = Bone.get_matrix(bone, matrix_world)
|
|
|
|
|
|
- if (frame != end_frame and currentBoneMatrix == previousBoneMatrix):
|
|
|
|
|
|
+ if (frame != end_frame and same_matrix4(currentBoneMatrix, previousBoneMatrix)):
|
|
continue
|
|
continue
|
|
|
|
|
|
self.animation.frames.append(frame)
|
|
self.animation.frames.append(frame)
|
|
@@ -1291,6 +1290,7 @@ class Bone:
|
|
write_int(file_handler, 'index', self.index)
|
|
write_int(file_handler, 'index', self.index)
|
|
write_matrix4(file_handler, 'matrix', self.matrix)
|
|
write_matrix4(file_handler, 'matrix', self.matrix)
|
|
write_int(file_handler, 'parentBoneIndex', self.parentBoneIndex)
|
|
write_int(file_handler, 'parentBoneIndex', self.parentBoneIndex)
|
|
|
|
+ write_float(file_handler, 'length', self.length)
|
|
|
|
|
|
#animation
|
|
#animation
|
|
if hasattr(self, 'animation'):
|
|
if hasattr(self, 'animation'):
|
|
@@ -2306,10 +2306,24 @@ def scale_vector(vector, mult, xOffset = 0):
|
|
ret.y *= mult
|
|
ret.y *= mult
|
|
return ret
|
|
return ret
|
|
|
|
|
|
|
|
+def same_matrix4(matA, matB):
|
|
|
|
+ if(matA is None or matB is None): return False
|
|
|
|
+ if (len(matA) != len(matB)): return False
|
|
|
|
+ for i in range(len(matA)):
|
|
|
|
+ if (round(matA[i][0], MAX_FLOAT_PRECISION_INT) != round(matB[i][0], MAX_FLOAT_PRECISION_INT) or
|
|
|
|
+ round(matA[i][1], MAX_FLOAT_PRECISION_INT) != round(matB[i][1], MAX_FLOAT_PRECISION_INT) or
|
|
|
|
+ round(matA[i][2], MAX_FLOAT_PRECISION_INT) != round(matB[i][2], MAX_FLOAT_PRECISION_INT) or
|
|
|
|
+ round(matA[i][3], MAX_FLOAT_PRECISION_INT) != round(matB[i][3], MAX_FLOAT_PRECISION_INT)):
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ return True
|
|
|
|
+
|
|
def same_vertex(vertA, vertB):
|
|
def same_vertex(vertA, vertB):
|
|
|
|
+ if(vertA is None or vertB is None): return False
|
|
return vertA.x == vertB.x and vertA.y == vertB.y and vertA.z == vertB.z
|
|
return vertA.x == vertB.x and vertA.y == vertB.y and vertA.z == vertB.z
|
|
|
|
|
|
def same_array(arrayA, arrayB):
|
|
def same_array(arrayA, arrayB):
|
|
|
|
+ if(arrayA is None or arrayB is None): return False
|
|
if len(arrayA) != len(arrayB): return False
|
|
if len(arrayA) != len(arrayB): return False
|
|
for i in range(len(arrayA)):
|
|
for i in range(len(arrayA)):
|
|
if arrayA[i] != arrayB[i] : return False
|
|
if arrayA[i] != arrayB[i] : return False
|