Esempio n. 1
0
    def test_reset_complement_03(self):
        # モーションの宣言
        motion = VmdMotion()
        motion.frames["左手首"] = []

        bf = VmdBoneFrame()
        bf.format_name = "左手首"
        bf.frame = 0
        bf.read = True
        bf.key = True
        bf.complement = [
            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10
        ]
        motion.frames["左手首"].append(bf)

        bf = VmdBoneFrame()
        bf.format_name = "左手首"
        bf.frame = 5
        bf.read = True
        # 間に有効キーなし
        bf.key = False
        bf.complement = [
            30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30
        ]
        motion.frames["左手首"].append(bf)

        bf = VmdBoneFrame()
        bf.format_name = "左手首"
        bf.frame = 30
        bf.read = True
        bf.key = True
        bf.complement = [
            20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
            20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
            20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
            20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
        ]
        motion.frames["左手首"].append(bf)

        # 腕リストの宣言
        arm_links = self.create_arm_links()

        # 処理実施
        sub_arm_ik.reset_complement(motion, arm_links)

        for c in motion.frames["左手首"][0].complement:
            self.assertEqual(10, c)

        for c in motion.frames["左手首"][1].complement:
            self.assertEqual(30, c)

        for c in motion.frames["左手首"][2].complement:
            self.assertEqual(20, c)
Esempio n. 2
0
    def read_vmd_file(self, filepath):
        # VMDファイルをバイナリ読み込み
        self.buffer = open(filepath, "rb").read()
        
        # vmdバージョン
        signature = self.unpack(30, "30s")
        logger.debug("signature %s", signature)

        motion = VmdMotion()
        
        # モーションパス
        motion.path = filepath

        # モデル名
        model_bname, model_name = self.read_text(20)
        logger.debug("model_bname %s, model_name: %s", model_bname, model_name)
        motion.model_name = model_name

        # モーション数
        motion.motion_cnt = self.read_uint(4)
        logger.debug("motion.motion_cnt %s", motion.motion_cnt)
        
        # モーションのあるキーのINDEX
        motion_indexes = {}
        
        # 1F分のモーション情報
        for n in range(motion.motion_cnt):
            frame = VmdBoneFrame()
            frame.key = True
            frame.read = True
            
            # ボーン ----------------------
            # ボーン名
            bone_bname, bone_name = self.read_text(15)

            frame.name = bone_bname
            frame.format_name = bone_name
            logger.debug("name: %s, format_name %s", bone_bname, bone_name)
            
            # フレームIDX
            frame.frame = self.read_uint(4)
            logger.debug("frame.frame %s", frame.frame)            
            
            # 位置X,Y,Z
            frame.position = self.read_Vector3D()
            logger.debug("frame.position %s", frame.position)   
            # オリジナルを保持
            frame.org_position = copy.deepcopy(frame.position)         
            
            # 回転X,Y,Z,scalar
            frame.rotation = self.read_Quaternion()
            logger.debug("frame.rotation %s", frame.rotation)            
            logger.debug("frame.rotation.euler %s", frame.rotation.toEulerAngles())            
            # オリジナルを保持
            frame.org_rotation = copy.deepcopy(frame.rotation)         
            
            # 補間曲線
            frame.complement = list(self.unpack(64, "64B", True))
            logger.debug("complement %s", frame.complement)
            # オリジナルの補間曲線を保持しておく
            frame.org_complement = copy.deepcopy(frame.complement)
            logger.debug("org_complement %s", frame.org_complement)
            
            if bone_name not in motion.frames:
                # まだ辞書にない場合、配列追加
                motion.frames[bone_name] = []
                motion_indexes[bone_name] = {}

            is_not_existed = True
            if frame.frame in motion_indexes[bone_name]:
                is_not_existed = False

            # 辞書の該当部分にボーンフレームを追加
            if is_not_existed == True:
                motion.frames[bone_name].append(frame)
                motion_indexes[bone_name][frame.frame] = frame.frame

            if frame.frame > motion.last_motion_frame:
                # 最終フレームを記録
                motion.last_motion_frame = frame.frame
            
            if n % 10000 == 0:
                print("VMDモーション読み込み キー: %s" % n)
                
        # ソート
        for k, v in motion.frames.items():
            motion.frames[k] = sorted(v, key=lambda u: u.frame)

        # モーフ数
        motion.morph_cnt = self.read_uint(4)
        logger.debug("motion.morph_cnt %s", motion.morph_cnt)
                
        # モーションのあるキーのINDEX
        morph_indexes = {}

        # 1F分のモーフ情報
        for n in range(motion.morph_cnt):
            morph = VmdMorphFrame()
            
            # ボーン ----------------------
            # ボーン名
            morph_bname, morph_name = self.read_text(15)

            morph.name = morph_bname
            morph.format_name = morph_name
            logger.debug("name: %s, format_name %s", morph_bname, morph_name)
            
            # フレームIDX
            morph.frame = self.read_uint(4)
            logger.debug("morph.frame %s", morph.frame)            
            
            # 度数
            morph.ratio = self.read_float(4)
            logger.debug("morph.ratio %s", morph.ratio)

            if morph_name not in motion.morphs:
                # まだ辞書にない場合、配列追加
                motion.morphs[morph_name] = []
                morph_indexes[morph_name] = {}

            is_not_existed = True
            if morph.frame in morph_indexes[morph_name]:
                is_not_existed = False

            if is_not_existed == True:
                # まだなければ辞書の該当部分にモーフフレームを追加
                motion.morphs[morph_name].append(morph)
                morph_indexes[morph_name][morph.frame] = morph.frame
        
            if n % 1000 == 0:
                print("VMDモーション読み込み モーフ: %s" % n)
                
        # ソート
        for k, v in motion.morphs.items():
            motion.morphs[k] = sorted(v, key=lambda u: u.frame)

        # カメラ数
        motion.camera_cnt = self.read_uint(4)
        logger.debug("motion.camera_cnt %s", motion.camera_cnt)
        
        # 1F分のカメラ情報
        for _ in range(motion.camera_cnt):
            camera = VmdCameraFrame()
                        
            # フレームIDX
            camera.frame = self.read_uint(4)
            logger.debug("camera.frame %s", camera.frame)            
            
            # 距離
            camera.length = self.read_float(4)
            logger.debug("camera.length %s", camera.length)            
            
            # 位置X,Y,Z
            camera.position = self.read_Vector3D()
            logger.debug("camera.position %s", camera.position)
            
            # 角度(オイラー角)
            camera.euler = self.read_Vector3D()
            logger.debug("camera.euler %s", camera.euler)
            
            # 補間曲線
            camera.complement = self.unpack(24, "24B", True)
            logger.debug("camera.complement %s", camera.complement)
            
            # 視野角
            camera.angle = self.read_uint(4)
            logger.debug("camera.angle %s", camera.angle)
            
            # パース有無
            camera.perspective = self.unpack(1, "B")
            logger.debug("camera.perspective %s", camera.perspective)

            # カメラを追加
            motion.cameras.append(camera)
        
        # ソート
        motion.cameras = sorted(motion.cameras, key=lambda u: u.frame)

        # 照明数
        try:
            motion.light_cnt = self.read_uint(4)
            logger.debug("motion.light_cnt %s", motion.light_cnt)
        except Exception as e:
            # 情報がない場合、catchして握りつぶす
            motion.light_cnt = 0
        
        # 1F分の照明情報
        for _ in range(motion.light_cnt):
            light = VmdLightFrame()
                        
            # フレームIDX
            light.frame = self.read_uint(4)
            logger.debug("light.frame %s", light.frame)     

            # 照明色(RGBだが、下手に数値が変わるのも怖いのでV3D)
            light.color = self.read_Vector3D()
            logger.debug("light.color %s", light.color)            

            # 照明位置
            light.position = self.read_Vector3D()
            logger.debug("light.position %s", light.position) 

            # 追加
            motion.lights.append(light)           
            
        # セルフシャドウ数
        try:
            motion.shadow_cnt = self.read_uint(4)
            logger.debug("motion.shadow_cnt %s", motion.shadow_cnt)

            # 1F分のシャドウ情報
            for _ in range(motion.shadow_cnt):
                shadow = VmdShadowFrame()
                            
                # フレームIDX
                shadow.frame = self.read_uint(4)
                logger.debug("shadow.frame %s", shadow.frame)     

                # シャドウ種別
                shadow.type = self.read_uint(1)
                logger.debug("shadow.type %s", shadow.type)            

                # 距離
                shadow.distance = self.read_float()
                logger.debug("shadow.distance %s", shadow.distance)            
                
                # 追加
                motion.shadows.append(shadow)

        except Exception as e:
            # 情報がない場合、catchして握りつぶす
            motion.shadow_cnt = 0
        
        # IK数
        try:
            motion.ik_cnt = self.read_uint(4)
            logger.debug("motion.ik_cnt %s", motion.ik_cnt)

            # 1F分のIK情報
            for _ in range(motion.ik_cnt):
                ik = VmdShowIkFrame()
                            
                # フレームIDX
                ik.frame = self.read_uint(4)
                logger.debug("ik.frame %s", ik.frame)     

                # モデル表示, 0:OFF, 1:ON
                ik.show = self.read_uint(1)
                logger.debug("ik.show %s", ik.show)            

                # 記録するIKの数
                ik.ik_count = self.read_uint(4)
                logger.debug("ik.ik_count %s", ik.ik_count)     

                for _ in range(ik.ik_count):
                    ik_info = VmdInfoIk()

                    # IK名
                    ik_bname, ik_name = self.read_text(20)
                    ik_info.name = ik_bname
                    logger.debug("ik_info.name %s", ik_name)            

                    # モデル表示, 0:OFF, 1:ON
                    ik_info.onoff = self.read_uint(1)
                    logger.debug("ik_info.onoff %s", ik_info.onoff)            

                    ik.ik.append(ik_info)  

                # 追加
                motion.showiks.append(ik)       
                            
        except Exception as e:
            # 昔のMMD(MMDv7.39.x64以前)はIK情報がないため、catchして握りつぶす
            motion.ik_cnt = 0
        
        # ハッシュを設定
        motion.digest = self.hexdigest(filepath)
        logger.debug("motion: %s, hash: %s", motion.path, motion.digest)

        return motion            
Esempio n. 3
0
    def test_reset_complement_06(self):
        # モーションの宣言
        motion = VmdMotion()
        motion.frames["左手首"] = []

        bf = VmdBoneFrame()
        bf.format_name = "左手首"
        bf.frame = 0
        bf.read = True
        bf.key = True
        for r in utils.R_x1_idxs:
            bf.complement[r] = 10
        for r in utils.R_y1_idxs:
            bf.complement[r] = 10
        for r in utils.R_x2_idxs:
            bf.complement[r] = 10
        for r in utils.R_y2_idxs:
            bf.complement[r] = 10
        motion.frames["左手首"].append(bf)

        bf = VmdBoneFrame()
        bf.format_name = "左手首"
        bf.frame = 5
        bf.read = True
        # 間に有効キーあり
        bf.key = True
        for r in utils.R_x1_idxs:
            bf.complement[r] = 30
        for r in utils.R_y1_idxs:
            bf.complement[r] = 30
        for r in utils.R_x2_idxs:
            bf.complement[r] = 30
        for r in utils.R_y2_idxs:
            bf.complement[r] = 30
        motion.frames["左手首"].append(bf)

        bf = VmdBoneFrame()
        bf.format_name = "左手首"
        bf.frame = 10
        bf.read = False
        # 有効キーの次に無効キー
        bf.key = False
        for r in utils.R_x1_idxs:
            bf.complement[r] = 30
        for r in utils.R_y1_idxs:
            bf.complement[r] = 30
        for r in utils.R_x2_idxs:
            bf.complement[r] = 30
        for r in utils.R_y2_idxs:
            bf.complement[r] = 30
        motion.frames["左手首"].append(bf)

        bf = VmdBoneFrame()
        bf.format_name = "左手首"
        bf.frame = 15
        bf.read = False
        # 2つ目の有効キー
        bf.key = True
        for r in utils.R_x1_idxs:
            bf.complement[r] = 30
        for r in utils.R_y1_idxs:
            bf.complement[r] = 30
        for r in utils.R_x2_idxs:
            bf.complement[r] = 30
        for r in utils.R_y2_idxs:
            bf.complement[r] = 30
        motion.frames["左手首"].append(bf)

        bf = VmdBoneFrame()
        bf.format_name = "左手首"
        bf.frame = 30
        bf.read = True
        bf.key = True
        for r in utils.R_x1_idxs:
            bf.complement[r] = 10
        for r in utils.R_y1_idxs:
            bf.complement[r] = 10
        for r in utils.R_x2_idxs:
            bf.complement[r] = 20
        for r in utils.R_y2_idxs:
            bf.complement[r] = 20
        motion.frames["左手首"].append(bf)

        # 腕リストの宣言
        arm_links = self.create_arm_links()

        # 処理実施
        sub_arm_ik.reset_complement(motion, arm_links)

        # ---------------------------------
        # 前回の開始X
        for r in utils.R_x1_idxs:
            self.assertEqual(10, motion.frames["左手首"][0].complement[r])

        # 前回の開始Y
        for r in utils.R_y1_idxs:
            self.assertEqual(10, motion.frames["左手首"][0].complement[r])

        # 前回の終了X
        for r in utils.R_x2_idxs:
            self.assertEqual(10, motion.frames["左手首"][0].complement[r])

        # 前回の終了Y
        for r in utils.R_y2_idxs:
            self.assertEqual(10, motion.frames["左手首"][0].complement[r])

        # ---------------------------------
        # 今回の開始X
        for r in utils.R_x1_idxs:
            self.assertEqual(30, motion.frames["左手首"][1].complement[r])

        # 今回の開始Y
        for r in utils.R_y1_idxs:
            self.assertEqual(30, motion.frames["左手首"][1].complement[r])

        # 今回の終了X
        for r in utils.R_x2_idxs:
            self.assertEqual(30, motion.frames["左手首"][1].complement[r])

        # 今回の終了Y
        for r in utils.R_y2_idxs:
            self.assertEqual(30, motion.frames["左手首"][1].complement[r])

        # ---------------------------------
        # 無効次回の開始X
        for r in utils.R_x1_idxs:
            self.assertEqual(30, motion.frames["左手首"][2].complement[r])

        # 無効次回の開始Y
        for r in utils.R_y1_idxs:
            self.assertEqual(30, motion.frames["左手首"][2].complement[r])

        # 無効次回の終了X
        for r in utils.R_x2_idxs:
            self.assertEqual(30, motion.frames["左手首"][2].complement[r])

        # 無効次回の終了Y
        for r in utils.R_y2_idxs:
            self.assertEqual(30, motion.frames["左手首"][2].complement[r])

        # ---------------------------------
        # 有効次回の開始X
        for r in utils.R_x1_idxs:
            self.assertEqual(17, motion.frames["左手首"][3].complement[r])

        # 有効次回の開始Y
        for r in utils.R_y1_idxs:
            self.assertEqual(17, motion.frames["左手首"][3].complement[r])

        # 有効次回の終了X
        for r in utils.R_x2_idxs:
            self.assertEqual(34, motion.frames["左手首"][3].complement[r])

        # 有効次回の終了Y
        for r in utils.R_y2_idxs:
            self.assertEqual(34, motion.frames["左手首"][3].complement[r])

        # ---------------------------------
        # 次回の開始X
        for r in utils.R_x1_idxs:
            self.assertEqual(29, motion.frames["左手首"][4].complement[r])

        # 次回の開始Y
        for r in utils.R_y1_idxs:
            self.assertEqual(29, motion.frames["左手首"][4].complement[r])

        # 次回の終了X
        for r in utils.R_x2_idxs:
            self.assertEqual(70, motion.frames["左手首"][4].complement[r])

        # 次回の終了Y
        for r in utils.R_y2_idxs:
            self.assertEqual(70, motion.frames["左手首"][4].complement[r])