Автор Тема: Звук-Анимация, Анимация-Звук  (Прочитано 1303 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн sungreen

  • ...
  • Житель
  • Kostroma mon amour
    • sungreen.github.io
Re: Звук-Анимация, Анимация-Звук
« Ответ #105 : 23 Ноября 2016, 18:49:47 »
... поясни, каким образом узнать какой тип анимации нужно создать по указанной ноте для конкретного объекта - клавиши3д? ...
Для Кота

Оффлайн LanuHum

  • Житель
Re: Звук-Анимация, Анимация-Звук
« Ответ #106 : 23 Ноября 2016, 18:56:09 »
>> Название клавиш должно начинаться с названия инструмента, а заканчиваться буквами, соответствующими ноте, например: "Piano_C2".
... это хорошая идея ...

>> Только, не создаём action для каждой ноты, а создаём анимацию каждого объекта - клавиши3д.
... каким образом узнать какой тип анимации нужно создать по указанной ноте для конкретного объекта - клавиши3д? ...
Я писал ранее и добавил крутилки, правда, ни все. В гуи мы выбираем, какой объект мы будем анимировать: музыканта или инструмент?
Если мы выбрали инструмент, мы должны выбрать тип инструмента в добавленном после этого поста enumprop: клавишный, духовой, струнный, ударный и так далее.
Твой код очень подходит для клавишных инструментов, и файл .blend , который ты предоставил, это хорошо демонстрирует.

Оффлайн sungreen

  • ...
  • Житель
  • Kostroma mon amour
    • sungreen.github.io
Re: Звук-Анимация, Анимация-Звук
« Ответ #107 : 23 Ноября 2016, 19:10:09 »
>> Твой код очень подходит для клавишных инструментов, и файл .blend , который ты предоставил, это хорошо демонстрирует.
... в том файле не было кода который создавал анимацию, там был код который создавал копии действия и расставлял эти действия в нужные места ...
... поэтому вопрос остаётся открытым - каким образом узнать какой тип анимации (или какую анимацию) нужно создать по указанной ноте для конкретного объекта - клавиши3д? ...
Для Кота

Оффлайн LanuHum

  • Житель
Re: Звук-Анимация, Анимация-Звук
« Ответ #108 : 23 Ноября 2016, 19:27:30 »
>> Твой код очень подходит для клавишных инструментов, и файл .blend , который ты предоставил, это хорошо демонстрирует.
... в том файле не было кода который создавал анимацию, там был код который создавал копии действия и расставлял эти действия в нужные места ...
... поэтому вопрос остаётся открытым - каким образом узнать какой тип анимации (или какую анимацию) нужно создать по указанной ноте для конкретного объекта - клавиши3д? ...
Ну, какой тип анимации для клавишей пианино? Location по Z. Я только не вникал, как по отдельным осям вставлять ключи, но по моему, знаю, как удалить ненужные fcurve. :)
Для других инструментов, скорей всего подойдёт анимация костей в режиме Pose с тем же типом Location

Оффлайн sungreen

  • ...
  • Житель
  • Kostroma mon amour
    • sungreen.github.io
Re: Звук-Анимация, Анимация-Звук
« Ответ #109 : 23 Ноября 2016, 19:33:48 »
>> Location по Z.
... на какую величину, какой формы? ...
Для Кота

Оффлайн LanuHum

  • Житель
Re: Звук-Анимация, Анимация-Звук
« Ответ #110 : 23 Ноября 2016, 19:45:29 »
>> Location по Z.
... на какую величину, какой формы? ...
Крутилку нужно добавить, и, для того мы указываем оператору bl_options = UNDO, чтобы можно было визуально подобрать. Двигаем крутилку - всё переписывается. Также, можно предварительно приблизительно вычислить величину из габаритов инструмента.
Форму также нужно определять крутилкой, но, как мне кажется, в большинстве случаев это будет линейная интерполяция. Какой ты знаешь инструмент, где нота извлекается путём синусоидального нажатия или по какой-то другой замысловатой тригонометрической формуле? :)

Оффлайн LanuHum

  • Житель
Re: Звук-Анимация, Анимация-Звук
« Ответ #111 : 25 Ноября 2016, 19:57:31 »
Николай! Запарился я искать как ты всё  это перепрыгиваешь:
        tree = ET.parse(self.filepath)
        node = tree.getroot()
        for head in node.findall('song'):
            for child_song in head.findall('trackcontainer'):
                for child_trackcontainer in child_song.findall('track'):
                    for child_track in child_trackcontainer.findall('pattern'):
                        for child_pattern in child_track.findall('note'):
                            print(child_pattern)
???
Как ты добираешься до паттерна от корня?

Вроде понял, рекурсию используешь...

Оффлайн sungreen

  • ...
  • Житель
  • Kostroma mon amour
    • sungreen.github.io
Re: Звук-Анимация, Анимация-Звук
« Ответ #112 : 25 Ноября 2016, 20:22:47 »
>> Вроде понял, рекурсию используешь...
... вроде логично для xml использовать рекурсию ...
Код: python [Выделить]
def mmp_parse(node):
    if node.tag=='pattern':
        notes={}
        for note in node:
            key = note.attrib['key'].zfill(3)
            if not (key in notes):
                notes[key] = []
            note=(int(note.attrib['pos']), int(note.attrib['len']), int(note.attrib['vol']))
            notes[key].append(note)
        if len(notes)>0:
            return [{'name':node.attrib['name'], 'pos':int(node.attrib['pos']), 'len':int(node.attrib['len']), 'notes':notes}]
        return []
    patterns = []
    for child in node:
        patterns.extend(mmp_parse(child))       
    return patterns 


>>Чтобы было понятней, вот словарь, написанный для одной октавы:
... кстати, ты сможешь сделать весь словарь ...
Для Кота

Оффлайн LanuHum

  • Житель
Re: Звук-Анимация, Анимация-Звук
« Ответ #113 : 25 Ноября 2016, 21:35:29 »
>>Чтобы было понятней, вот словарь, написанный для одной октавы:
... кстати, ты сможешь сделать весь словарь ...

notes_data = {
    0: ["До_4","c4","C4"],
    1: ["До_диез_4","Ре_бемоль_4","cis4","des4","C-sharp4","D-flat4"],
    2: ["Ре_4","d4","D4"],
    3: ["Ре_диез_4","Ми_бемоль_4","dis4","es4","D-sharp4","E-flat4"],
    4: ["Ми_4","e4","E4"],
    5: ["Фа_4","f4","F4"],
    6: ["Фа_диез_4","Соль_бемоль_4","fis4","ges4","F-sharp4","G-flat4"],
    7: ["Соль_4","g4","G4"],
    8: ["Соль_диез_4","Ля_бемоль_4","gis4","as4","G-sharp4","A-flat4"],
    9: ["Ля_4","a4","A4"],
    10: ["Ля_диез_4","Си_бемоль_4","ais4","b4","A-sharp4","B-flat4"],
    11: ["Си_4","h4","B4"]
}

notes = {}
for o in range(9):
    for i in range(12):
        key = i + (o*9)
        a=notes_data[i]
        n = []
        for s in a:
            s = s.replace("4","%s"%o)
            n.append(s)
        notes[key] = n
print(notes)

Кстати, вот здесь я дописал:
        bpm = None
        for head in node.findall('head'):
            if 'bpm' in head.attrib:
                bpm = int(head.attrib['bpm'])
            if not bpm:
                for child in head.findall('bpm'):
                    if 'value' in child.attrib:
                        bpm = int(child.attrib['value'])

Оффлайн sungreen

  • ...
  • Житель
  • Kostroma mon amour
    • sungreen.github.io
Re: Звук-Анимация, Анимация-Звук
« Ответ #114 : 26 Ноября 2016, 02:41:46 »
>> Кстати, вот здесь я дописал:
... в ранее выложенным .blend файле, который во вложении сообщения http://blender-3d.ru/forum/index.php/topic,1597.msg23008.html#msg23008 есть похожий код ...
... мне показалось более простым вместо findall использовать find, поскольку любая коллизия с множественным наличием head или bpm игнорируется ...
... и можно сразу задать bmp дефолтное значение, например 120 ...

Код: python [Выделить]
def data_from_mmp(path,name):
    filename=path+name+'.mmp'
    node = mmp_load(filename)

    bpm = 120
    elem = node.find('.//head')
    if elem:
        if 'bpm' in elem.attrib:
            bpm = int(elem.attrib['bpm'])
        else:                   
            elem = node.find('.//bpm')
            bpm = int(elem.attrib['value'])

    return {'tempo':bpm, 'patterns':mmp_parse(node)}
Для Кота

Оффлайн LanuHum

  • Житель
Re: Звук-Анимация, Анимация-Звук
« Ответ #115 : 26 Ноября 2016, 09:25:37 »
Я забыл просмотреть текст, но, не важно, если ты знаешь о том, что bpm может быть записан двумя вариантами...
Вот мой черновик, может, что-то увидишь в нём полезное:
# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

import os, subprocess
import bpy
from bpy.props import *
from bpy_extras.io_utils import ImportHelper
import xml.etree.ElementTree as ET

bl_info = {
    "name": "Import LMMP Pattern to Scene (.mmp)",
    "author": "blender-3d.ru/forum",
    "version": (0, 0, 1),
    "blender": (2, 78, 0),
    "location": "File > Import > LMMP Pattern to Scene(.mmp)",
    "description": "Imports LMMP files as a series of animation properties",
    "category": "Import-Export",
}

"""
This script imports LMMP files into 3D Scenes (.mmp)
"""

def fingers_item_callback(self, context):
    ob = context.object
    items = [("1", "1", ""),
            ("2", "2", ""),
            ("3", "3", ""),
            ("4", "4", ""),
            ("5", "5", "")]
    if ob.instrument_type == 'guitar':
        items = [("b", "B", ""),
                ("1", "1", ""),
                ("2", "2", ""),
                ("3", "3", ""),
                ("4", "4", "")]
    return items

class MusicPatternSettings(bpy.types.PropertyGroup):
    @classmethod
    def register(cls):
        bpy.types.TextCurve.music_pattern = PointerProperty(
                name="Music Pattern Settings",
                description="",
                type=cls,
                )
    autocreate = BoolProperty()
    midi_data_object = StringProperty()
    musician_instrument = bpy.props.EnumProperty(
        name="Musician or Instrument",
        items=( ("instrument", "Instrument", ""),
                ("musician", "Musician", "")),
        default="instrument")
    instrument_type = bpy.props.EnumProperty(
        name="Instrument Type",
        items=( ("bowed", "Bowed Strings", ""),
                ("brass", "Brass Instruments", ""),
                ("guitar", "Guitar family", ""),
                ("keyboard", "Keyboard instruments", ""),
                ("percussion", "Percussion instruments", ""),
                ("woodwind", "Woodwind", "")),
        default="keyboard")

    @classmethod
    def unregister(cls):
        del bpy.types.TextCurve.music_pattern

class NoteSettingItem(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty()
    index = bpy.props.IntProperty()
    volume = bpy.props.IntProperty()
    position = bpy.props.IntProperty()
    duration = bpy.props.IntProperty()
    hands = bpy.props.EnumProperty(
        name="Hands",
        items=( ("left", "Left", ""),
                ("right", "Right", ""),
                ("both", "Both", "")),
        default="right")

    left_hand = bpy.props.EnumProperty(
        name="motion_left_hand",
        items=( ("up", "Up", ""),
                ("down", "Down", ""),
                ("blow", "Blow", ""),
                ("fingers", "Fingers", "")),
        default="blow")

    fingers_left = bpy.props.EnumProperty(
        name="Fingers Left Hand",
        items=fingers_item_callback)

    finger_connect_left = bpy.props.BoolProperty()


    right_hand = bpy.props.EnumProperty(
        name="motion_right_hand",
        items=( ("up", "Up", ""),
                ("down", "Down", ""),
                ("blow", "Blow", ""),
                ("fingers", "Fingers", "")),
        default="blow")

    fingers_right = bpy.props.EnumProperty(
        name="Fingers Right Hand",
        items=fingers_item_callback)

    finger_connect_right = bpy.props.BoolProperty()

class View3DPanel():
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'

class VIEW3D_PT_lmms(View3DPanel, bpy.types.Panel):
    bl_category = "Animation"
    bl_context = "objectmode"
    bl_label = "Musicians Animation with LMMS"

    def draw(self, context):
        ob=context.object
        note = 0
        if ob and ob.type == 'FONT' and len(ob.data.notes) > 0:
            layout = self.layout
            layout.prop_search(ob,"midi_data_object",context.blend_data,'objects',text='Musician')
            layout.prop(ob,"auto")
            ctx = ob.data.notes[note]  #develop
            layout.prop(ctx,"name")
            layout.prop(ctx,"volume")
            layout.prop(ctx,"position")
            layout.prop(ctx,"duration")
            layout.label('Hands:')
            layout.prop(ctx,"hands",expand = True)
            if ctx.hands in {'left','both'}:
                layout.label('Left hand:')
                layout.prop(ctx,"left_hand",expand = True)
                if ctx.left_hand in {'fingers'}:
                    box = layout.box()
                    box.label('Fingers left hand')
                    box.prop(ctx,"fingers_left",text="1")
                    box.prop(ctx,"finger_connect_left",text="Leave Pressed")

            if ctx.hands in {'right','both'}:
                layout.label('Right hand:')
                layout.prop(ctx,"right_hand",expand = True)
                if ctx.right_hand in {'fingers'}:
                    box = layout.box()
                    box.label('Fingers right hand')
                    box.prop(ctx,"fingers_right",text="1")
                    box.prop(ctx,"finger_connect_right",text="Leave Pressed") 

scale = 1
offset = 0
scene = None
startframe = 0

class LMMPPatternToScene(bpy.types.Operator, ImportHelper):
   
    bl_idname = "import.lmmp_pattern_to_scene"
    bl_label = "LMMP Pattern to Scene"
    bl_description = "Imports notes from LMMP files into 3D Scenes"
    bl_options = {'REGISTER', 'UNDO'}
 
    filename_ext = {".mmp"}
    filter_glob = StringProperty(
            default="*.mmp",
            options={'HIDDEN'},
            )

    Offset = FloatProperty(name="Offset Frame", description="Offset frame", min=0, default=1)
    DefaultTicksPerTact = FloatProperty(name="Default Ticks Per Tact", description="Default ticks per tact", min=16, default=192)
   
    def draw(self, context):
        layout = self.layout
        box = layout.box()
        box.label('LMMP Pattern:', icon='SORTSIZE')
        box.prop(self, 'Offset')
        box.prop(self, 'DefaultTicksPerTact')
   
    def execute(self, context):
        scene = context.scene
        fps = scene.render.fps

        layers = 20*[False]
        layers[0]=True

        tree = ET.parse(self.filepath)
        node = tree.getroot()
        bpm = None
        for head in node.findall('head'):
            if 'bpm' in head.attrib:
                bpm = int(head.attrib['bpm'])
            if not bpm:
                for child in head.findall('bpm'):
                    if 'value' in child.attrib:
                        bpm = int(child.attrib['value'])
        scale = 60/bpm/(self.DefaultTicksPerTact/4)*fps
        location = 0
        for head in node.findall('song'):
            for child_song in head.findall('trackcontainer'):
                for child_trackcontainer in child_song.findall('track'):
                    for child_track in child_trackcontainer.findall('pattern'):
                        tname=child_track.attrib['name']
                        tpos=int(child_track.attrib['pos'])
                        tlen=int(child_track.attrib['len'])
                        bpy.ops.object.text_add(location=(0, 0, location), layers=layers)
                        ob = bpy.context.object
                        ob.data.body = tname
                        ob.name = tname
                        location += 0.1
                        for pnote in child_track.findall('note'):
                            note = ob.data.notes.add()
                            key=pnote.attrib['key']
                            pos=int(pnote.attrib['pos'])
                            len=int(pnote.attrib['len'])
                            vol=int(pnote.attrib['vol'])
                            note.name =
                            note.index =
                            note.volume =
                            note.position =
                            note.duration =
        return {'FINISHED'}

def menu_func(self, context):
    self.layout.operator(LMMPPatternToScene.bl_idname, text="LMMP Pattern to Scene (.mmp)", icon='PLUGIN')

def register():
    bpy.utils.register_module(__name__)
    bpy.types.INFO_MT_file_import.append(menu_func)
    bpy.types.TextCurve.notes = bpy.props.CollectionProperty(type=NoteSettingItem)

def unregister():
    bpy.utils.unregister_module(__name__)
    bpy.types.INFO_MT_file_import.remove(menu_func)
    del bpy.types.TextCurve.notes

if __name__ == "__main__":
    register()

 

* По форуму

* Последние вложения

Sizes.jpg
Скачано: 10
Автор: Dmi3ryd
paticles.jpg
Скачано: 5
Автор: Dmi3ryd
Снимок 1.PNG
Скачано: 3
Автор: atmk
Снимок.PNG
Скачано: 3
Автор: atmk
Screw.jpg
Скачано: 8
Автор: Dmi3ryd