Jelajahi Sumber

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

# Conflicts:
#	dist/preview release/babylon.core.js
#	dist/preview release/babylon.d.ts
#	dist/preview release/babylon.js
#	dist/preview release/babylon.max.js
#	dist/preview release/babylon.noworker.js
#	src/Canvas2d/babylon.renderablePrim2d.js
#	src/Canvas2d/babylon.renderablePrim2d.ts
David Catuhe 9 tahun lalu
induk
melakukan
73aa395f1c

+ 57 - 42
Exporters/Blender/io_export_babylon.py

@@ -1,7 +1,7 @@
 bl_info = {
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (4, 4, 4),
+    'version': (4, 5, 0),
     'blender': (2, 75, 0),
     'location': 'File > Export > Babylon.js (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',
@@ -601,7 +601,7 @@ class FCurveAnimatable:
                 scaleAnimation = VectorAnimation(object, 'scaling', 'scale')
 
             self.ranges = []
-            frameOffset = bpy.context.scene.frame_start - 1
+            frameOffset = 0
 
             for action in bpy.data.actions:
                 # get the range / assigning the action to the object
@@ -610,18 +610,18 @@ class FCurveAnimatable:
                     continue
 
                 if supportsRotation:
-                    hasData = rotAnimation.append_range(object, frameOffset)
+                    hasData = rotAnimation.append_range(object, animationRange)
 
                 if supportsPosition:
-                    hasData |= posAnimation.append_range(object, frameOffset)
+                    hasData |= posAnimation.append_range(object, animationRange)
 
                 if supportsScaling:
-                    hasData |= scaleAnimation.append_range(object, frameOffset)
+                    hasData |= scaleAnimation.append_range(object, animationRange)
 
                 if hasData:
-                    Main.log('processing action ' + action.name, 3)
+                    Main.log('processing action ' + animationRange.to_string(), 3)
                     self.ranges.append(animationRange)
-                    frameOffset = animationRange.frame_end + 1
+                    frameOffset = animationRange.frame_end
 
             #Set Animations
             self.animations = []
@@ -1330,7 +1330,7 @@ class Bone:
         self.parentBone = bone.parent
 
         self.matrix_world = skeleton.matrix_world
-        self.matrix = self.get_bone_matrix()
+        self.matrix = self.get_bone_matrix(True)
 
         parentId = -1
         if (bone.parent):
@@ -1347,24 +1347,24 @@ class Bone:
             self.previousBoneMatrix = None
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def append_animation_pose(self, frame, force = False):
-        currentBoneMatrix = self.get_bone_matrix()
+        currentBoneMatrix = self.get_bone_matrix(True)
 
         if (force or not same_matrix4(currentBoneMatrix, self.previousBoneMatrix)):
             self.animation.frames.append(frame)
             self.animation.values.append(currentBoneMatrix)
             self.previousBoneMatrix = currentBoneMatrix
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    def set_rest_pose(self, editBone, matrix_world):
-        self.rest = Bone.get_matrix(editBone, self.matrix_world)
+    def set_rest_pose(self, editBone):
+        self.rest = Bone.get_matrix(editBone, self.matrix_world, True)
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    def get_bone_matrix(self):
-        return Bone.get_matrix(self.posedBone, self.matrix_world)
+    def get_bone_matrix(self, doParentMult):
+        return Bone.get_matrix(self.posedBone, self.matrix_world, doParentMult)
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     @staticmethod
-    def get_matrix(bone, matrix_world):
+    def get_matrix(bone, matrix_world, doParentMult):
         SystemMatrix = mathutils.Matrix.Scale(-1, 4, mathutils.Vector((0, 0, 1))) * mathutils.Matrix.Rotation(math.radians(-90), 4, 'X')
 
-        if (bone.parent):
+        if (bone.parent and doParentMult):
             return (SystemMatrix * matrix_world * bone.parent.matrix).inverted() * (SystemMatrix * matrix_world * bone.matrix)
         else:
             return SystemMatrix * matrix_world * bone.matrix
@@ -1401,34 +1401,35 @@ class Skeleton:
 
         if (skeleton.animation_data):
             self.ranges = []
-            frameOffset = scene.frame_start - 1
+            frameOffset = 0
             for action in bpy.data.actions:
                 # get the range / assigning the action to the object
                 animationRange = AnimationRange.actionPrep(skeleton, action, FRAME_BASED_ANIMATION, frameOffset)
                 if animationRange is None:
                     continue
 
-                Main.log('processing action ' + action.name, 2)
+                Main.log('processing action ' + animationRange.to_string(), 2)
                 self.ranges.append(animationRange)
 
-                for frame in animationRange.frames:
-                    bpy.context.scene.frame_set(frame)
+                nFrames = len(animationRange.frames_in)
+                for idx in range(nFrames):
+                    bpy.context.scene.frame_set(animationRange.frames_in[idx])
+                    firstOrLast = idx == 0 or idx == nFrames - 1
 
                     for bone in self.bones:
-                        bone.append_animation_pose(frame + frameOffset, frame == animationRange.highest_frame)
+                        bone.append_animation_pose(animationRange.frames_out[idx], firstOrLast)
 
-                frameOffset = animationRange.frame_end + 1
+                frameOffset = animationRange.frame_end
 
         # mode_set's only work when there is an active object, switch bones to edit mode to rest position
         scene.objects.active = skeleton
         bpy.ops.object.mode_set(mode='EDIT')
-        matrix_world = skeleton.matrix_world
 
         # you need to access edit_bones from skeleton.data not skeleton.pose when in edit mode
         for editBone in skeleton.data.edit_bones:
             for myBoneObj in self.bones:
                 if editBone.name == myBoneObj.name:
-                    myBoneObj.set_rest_pose(editBone, matrix_world)
+                    myBoneObj.set_rest_pose(editBone)
                     break
 
         bpy.ops.object.mode_set(mode='OBJECT')
@@ -2230,11 +2231,21 @@ class BakedMaterial(Material):
 class AnimationRange:
     # constructor called by the static actionPrep method
     def __init__(self, name, frames, frameOffset):
+        # process input args to members
         self.name = name
-        self.highest_frame = frames[len(frames) - 1]
-        self.frame_start = frameOffset + 1
-        self.frame_end   = frameOffset + self.highest_frame
-        self.frames = frames
+        self.frames_in = frames        
+        self.frame_start = AnimationRange.nextStartingFrame(frameOffset)
+        
+        self.frames_out = []
+        for frame in self.frames_in:
+            self.frames_out.append(self.frame_start + frame)
+            
+        highest_idx = len(self.frames_in) - 1
+        self.highest_frame_in = self.frames_in [highest_idx]
+        self.frame_end        = self.frames_out[highest_idx]
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    def to_string(self):
+        return self.name + ': ' + ' in[' + format_int(self.frames_in[0]) + ' - ' + format_int(self.highest_frame_in) + '], out[' + format_int(self.frame_start) + ' - ' + format_int(self.frame_end) + ']'
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def to_scene_file(self, file_handler):
         file_handler.write('{')
@@ -2246,14 +2257,14 @@ class AnimationRange:
     @staticmethod
     def actionPrep(object, action, includeAllFrames, frameOffset):
         # assign the action & test if there is any data for that action for this object
-#        bpy.context.scene.objects.active = object
         object.animation_data.action = action
         if len(object.animation_data.action.fcurves) == 0:
             return None
 
         if includeAllFrames:
-            frame_start, frame_end = [int(x) for x in action.frame_range]
-            frames = range(frame_start, frame_end)
+            frame_start = int(action.frame_range[0])
+            frame_end   = int(action.frame_range[1])
+            frames = range(frame_start, frame_end + 1) # range is not inclusive with 2nd arg
 
         else:
             # capture built up from fcurves
@@ -2266,6 +2277,16 @@ class AnimationRange:
             frames = sorted(frames)
 
         return AnimationRange(action.name, frames, frameOffset)
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    @staticmethod
+    def nextStartingFrame(frameOffset):
+        if frameOffset == 0: return 0
+        
+        # ensure a gap of at least 5 frames, starting on an even multiple of 10
+        frameOffset += 4
+        remainder = frameOffset % 10
+        return frameOffset + 10 - remainder
+        
 #===============================================================================
 class Animation:
     def __init__(self, dataType, loopBehavior, name, propertyInBabylon, attrInBlender = None, mult = 1, xOffset = 0):
@@ -2285,21 +2306,15 @@ class Animation:
         self.values = [] # vector3 for ANIMATIONTYPE_VECTOR3 & matrices for ANIMATIONTYPE_MATRIX
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # a separate method outside of constructor, so can be called once for each Blender Action object participates in
-    def append_range(self, object, frameOffset):
+    def append_range(self, object, animationRange):
         # action already assigned, always using poses, not every frame, build up again filtering by attrInBlender
-        frames = dict()
-        for fcurve in object.animation_data.action.fcurves:
-            if fcurve.data_path == self.attrInBlender:
-                for key in fcurve.keyframe_points:
-                    frame = key.co.x
-                    frames[frame] = 1
+        for idx in range(len(animationRange.frames_in)):
+            bpy.context.scene.frame_set(animationRange.frames_in[idx])
 
-        for Frame in sorted(frames):
-            self.frames.append(Frame + frameOffset)
-            bpy.context.scene.frame_set(int(Frame))
+            self.frames.append(animationRange.frames_out[idx])
             self.values.append(self.get_attr(object))
 
-        return len(frames) > 0
+        return len(animationRange.frames_in) > 0
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # for auto animate
     def get_first_frame(self):
@@ -2389,7 +2404,7 @@ def format_f(num):
     s = s.rstrip('0') # ignore trailing zeroes
     s = s.rstrip('.') # ignore trailing .
     return '0' if s == '-0' else s
-
+    
 def format_matrix4(matrix):
     tempMatrix = matrix.copy()
     tempMatrix.transpose()

File diff ditekan karena terlalu besar
+ 3 - 3
dist/preview release/babylon.core.js


File diff ditekan karena terlalu besar
+ 1618 - 1618
dist/preview release/babylon.d.ts


File diff ditekan karena terlalu besar
+ 4 - 4
dist/preview release/babylon.js


File diff ditekan karena terlalu besar
+ 4 - 5
dist/preview release/babylon.max.js


File diff ditekan karena terlalu besar
+ 4 - 4
dist/preview release/babylon.noworker.js


+ 3 - 4
src/Canvas2d/babylon.renderablePrim2d.js

@@ -346,8 +346,7 @@ var BABYLON;
                         this.refreshInstanceDataPart(dataPart);
                         this.isVisible = curVisible;
                         var size = 0;
-                        for (var index = 0; index < cti.fullContent.count; index++) {
-                            var v = cti.fullContent[index];
+                        cti.fullContent.forEach(function (k, v) {
                             if (!v.category || cat.indexOf(v.category) !== -1) {
                                 if (!v.size) {
                                     console.log("ERROR: Couldn't detect the size of the Property " + v.attributeName + " from type " + BABYLON.Tools.getClassName(cti.type) + ". Property is ignored.");
@@ -356,7 +355,7 @@ var BABYLON;
                                     size += v.size;
                                 }
                             }
-                        }
+                        });
                         dataStrides.push(size);
                         usedCatList.push(cat);
                         ctiArray.push(cti);
@@ -397,7 +396,7 @@ var BABYLON;
                 }
                 for (var _c = 0, _d = this._instanceDataParts; _c < _d.length; _c++) {
                     var part = _d[_c];
-                    var cat = this.getUsedShaderCategories(part);
+                    var cat_1 = this.getUsedShaderCategories(part);
                     InstanceClassInfo._CurCategories = gii._instancesPartsUsedShaderCategories[gii._partIndexFromId.get(part.id.toString())];
                     // Will return false if the instance should not be rendered (not visible or other any reasons)
                     if (!this.refreshInstanceDataPart(part)) {

+ 9 - 12
src/Canvas2d/babylon.renderablePrim2d.ts

@@ -342,8 +342,8 @@
                     let joinedUsedCatList = new Array<string>();
 
                     for (let dataPart of parts) {
-                        let cat = this.getUsedShaderCategories(dataPart);
-                        let cti = dataPart.getClassTreeInfo();
+                        var cat = this.getUsedShaderCategories(dataPart);
+                        var cti = dataPart.getClassTreeInfo();
                         // Make sure the instance is visible other the properties won't be set and their size/offset wont be computed
                         let curVisible = this.isVisible;
                         this.isVisible = true;
@@ -355,10 +355,8 @@
                         this.refreshInstanceDataPart(dataPart);
                         this.isVisible = curVisible;
 
-                        let size = 0;
-
-                        for (var index = 0; index < cti.fullContent.count; index++) {
-                            var v = cti.fullContent[index];
+                        var size = 0;
+                        cti.fullContent.forEach((k, v) => {
                             if (!v.category || cat.indexOf(v.category) !== -1) {
                                 if (!v.size) {
                                     console.log(`ERROR: Couldn't detect the size of the Property ${v.attributeName} from type ${Tools.getClassName(cti.type)}. Property is ignored.`);
@@ -366,8 +364,7 @@
                                     size += v.size;
                                 }
                             }
-                        }
-
+                        });
                         dataStrides.push(size);
                         usedCatList.push(cat);
                         ctiArray.push(cti);
@@ -431,7 +428,7 @@
             }
         }
 
-        protected getDataPartEffectInfo(dataPartId: number, vertexBufferAttributes: string[]): { attributes: string[], uniforms: string[], defines: string} {
+        protected getDataPartEffectInfo(dataPartId: number, vertexBufferAttributes: string[]): { attributes: string[], uniforms: string[], defines: string } {
             let dataPart = Tools.first(this._instanceDataParts, i => i.id === dataPartId);
             if (!dataPart) {
                 return null;
@@ -443,7 +440,7 @@
             let categories = this.getUsedShaderCategories(dataPart);
             let att = cti.classContent.getShaderAttributes(categories);
             let defines = "";
-            categories.forEach(c => { defines += `#define ${c}\n`});
+            categories.forEach(c => { defines += `#define ${c}\n` });
             if (instancedArray) {
                 defines += "#define Instanced\n";
             }
@@ -505,8 +502,8 @@
             let w = size.width * zBias;
             let h = size.height * zBias;
             let invZBias = 1 / zBias;
-            let tx = new Vector4(t.m[0] * 2 / w, t.m[4] * 2 / w, 0/*t.m[8]*/, ((t.m[12]+offX) * 2 / w) - (invZBias));
-            let ty = new Vector4(t.m[1] * 2 / h, t.m[5] * 2 / h, 0/*t.m[9]*/, ((t.m[13]+offY) * 2 / h) - (invZBias));
+            let tx = new Vector4(t.m[0] * 2 / w, t.m[4] * 2 / w, 0/*t.m[8]*/, ((t.m[12] + offX) * 2 / w) - (invZBias));
+            let ty = new Vector4(t.m[1] * 2 / h, t.m[5] * 2 / h, 0/*t.m[9]*/, ((t.m[13] + offY) * 2 / h) - (invZBias));
             part.transformX = tx;
             part.transformY = ty;
             part.origin = this.origin;