Всем привет. Сегодня будет заключительная статья на тему программирования в мире 3D, как вводная во все возможные темы.
В 3D помимо статических обьектов и поверхностей, по которым можно ходить хотябы камерой. Нужны еще анимированные модели — такие как персонажи, еффекты, детали, которыми можно описывать какие-то наблюдаемые явления, частицы. Всё это можно создавать в программном инструменте Blender, Maya и тд.
Хочу продемонстрировать простенький подход минимального болванчика.
Для этого ничего не потребуется, только Blender (пользуюсь базовой настройкой версии 4.2.3 LTS), нужно правда для теста меша проверить его на любом скелете из миксамо.
Скрытый текст
#import bpy #from math import * #from mathutils import * #vs = [(0,0,0)] #t = 7 #es = [] #fs = [] #for i in range(t): # p=2.0*3.1415*-i/t; # for j in range(i): # p1=2.0*3.1415*-j/5; # vs.append((cos(p1),sin(p1),cos(p1))) #mesh = bpy.data.meshes.new('mesh') #mesh.from_pydata(vs,es,fs) #mesh.update() ##meshobj #meshobj= bpy.data.objects.new('mesh',mesh) ##collection #new_collection = bpy.data.collections.new('new_collection') #bpy.context.scene.collection.children.link(new_collection) #new_collection.objects.link(meshobj) import bpy from math import * from mathutils import * vs = [(0,0,0)] t = 2 es = [] fs = [] for i in range(t): vs.append(( i*2/3.5, i*2/3.5,i*7.4)) vs.append(( 0, i*2/3.5,i*7.4)) vs.append(( i*2/3.5,-i*2/3.5,i*7.4)) vs.append((0,-i*2/3.5, i*7.4)) vs.append((i*2/3.5,i*2/3.5,i*6.3)) vs.append((0,i*2/3.5,i*6.3)) vs.append((i*2/3.5,-i*2/3.5,i*6.3)) vs.append((0,-i*2/3.5,i*6.3)) vs.append((i*2/6.5,i*2/6.5,i*6.3)) vs.append((0,i*2/6.5,i*6.3)) vs.append((i*2/6.5,-i*2/6.5,i*6.3)) vs.append((0,-i*2/6.5,i*6.3)) vs.append((i*2/6.5,i*2/6.5,i*6.2)) vs.append((0,i*2/6.5,i*6.2)) vs.append((i*2/6.5,-i*2/6.5,i*6.2)) vs.append((0,-i*2/6.5,i*6.2)) vs.append((i*2/3,i*2/6.5,i*6.2)) vs.append((0,i*2/6.5,i*6.2)) vs.append((i*2/3,-i*2/6.5,i*6.2)) vs.append((0,-i*2/6.5,i*6.2)) vs.append((i*2/3,i*2/6.5,i*5.8)) vs.append((0,i*2/6.5,i*5.8)) vs.append((i*2/3,-i*2/6.5,i*5.8)) vs.append((0,-i*2/6.5,i*5.8)) vs.append((i*2/1.9,i*2/6.5,i*5.8)) vs.append((0,i*2/6.5,i*5.8)) vs.append((i*2/1.9,-i*2/6.5,i*5.8)) vs.append((0,-i*2/6.5,i*5.8)) vs.append((i*2/1.9,i*2/6.5,i*5.0)) vs.append((0,i*2/6.5,i*5.0)) vs.append((i*2/1.9,-i*2/6.5,i*5.0)) vs.append((0,-i*2/6.5,i*5.0)) vs.append((i*2/2.2,i*2/9,i*5.0)) vs.append((0,i*2/9,i*5.0)) vs.append((i*2/2.2,-i*2/9,i*5.0)) vs.append((0,-i*2/9,i*5.0)) vs.append((i*2/2.2,i*2/9,i*3.7)) vs.append((0,i*2/9,i*3.7)) vs.append((i*2/2.2,-i*2/9,i*3.7)) vs.append((0,-i*2/9,i*3.7)) vs.append((i*2/1.9,i*2/6.5,i*3.7)) vs.append((0,i*2/6.5,i*3.7)) vs.append((i*2/1.9,-i*2/6.5,i*3.7)) vs.append((0,-i*2/6.5,i*3.7)) vs.append((i*2/1.8 ,i*2/6.5,i*3.2)) vs.append((0 ,i*2/6.5,i*3.2)) vs.append((i*2/1.8 ,-i*2/6.5,i*3.2)) vs.append((0 ,-i*2/6.5,i*3.2)) #legs vs.append(( i*2/2.1, i*2/7.6, i*3.2)) vs.append(( 0.4,i*2/7.6, i*3.2)) vs.append(( i*2/2.1, -i*2/7.6, i*3.2)) vs.append(( 0.4,-i*2/7.6, i*3.2)) vs.append((i*2/2.1,i*2/7.6,i*2.35)) vs.append((0.4,i*2/7.6,i*2.35)) vs.append((i*2/2.1,-i*2/7.6,i*2.35)) vs.append((0.4,-i*2/7.6,i*2.35)) vs.append((i*2/1.95,i*2/6.6,i*2.35)) vs.append((0.35,i*2/6.6,i*2.35)) vs.append((i*2/1.95,-i*2/6.6,i*2.35)) vs.append((0.35,-i*2/6.6,i*2.35)) vs.append((i*2/1.95,i*2/6.6,i*1.8)) vs.append((0.35,i*2/6.6,i*1.8)) vs.append((i*2/1.95,-i*2/6.6,i*1.8)) vs.append((0.35,-i*2/6.6,i*1.8)) vs.append((i*2/2.1,i*2/7.6,i*1.8)) vs.append((0.4,i*2/7.6,i*1.8)) vs.append((i*2/2.1,-i*2/7.6,i*1.8)) vs.append((0.4,-i*2/7.6,i*1.8)) vs.append((i*2/2.1,i*2/7.6,i*.85)) vs.append((0.4,i*2/7.6,i*.85)) vs.append((i*2/2.1,-i*2/7.6,i*.85)) vs.append((0.4,-i*2/7.6,i*.85)) vs.append((i*2/1.8, i*2/4.6,i*.85)) vs.append((0.28, i*2/4.6,i*.85)) vs.append((i*2/1.8, -i*2/1.5,i*.85)) vs.append((0.28, -i*2/1.5,i*.85)) vs.append((i*2/1.8, i*2/4.6,i*.0)) vs.append((0.28, i*2/4.6,i*.0)) vs.append((i*2/1.8, -i*2/1.5,i*.0)) vs.append((0.28, -i*2/1.5,i*.0)) #hands vs.append((i*2/3,i*2/5.5,i*6.59)) vs.append((i*2/3,-i*2/5.5,i*6.59)) vs.append((i*2/3,-i*2/5.5,i*5.8)) vs.append((i*2/3,i*2/5.5,i*5.8)) vs.append((i*2/1.46,i*2/5.5,i*6.59)) vs.append((i*2/1.46,-i*2/5.5,i*6.59)) vs.append((i*2/1.46,-i*2/5.5,i*5.8)) vs.append((i*2/1.46,i*2/5.5,i*5.8)) vs.append((i*2/1.46,i*2/7.5,i*6.49)) vs.append((i*2/1.46,-i*2/7.5,i*6.49)) vs.append((i*2/1.46,-i*2/7.5,i*5.9)) vs.append((i*2/1.46,i*2/7.5,i*5.9)) vs.append((i*2.1,i*2/7.5,i*6.49)) vs.append((i*2.1,-i*2/7.5,i*6.49)) vs.append((i*2.1,-i*2/7.5,i*5.9)) vs.append((i*2.1,i*2/7.5,i*5.9)) vs.append((i*2.1,i*2/5.5,i*6.59)) vs.append((i*2.1,-i*2/5.5,i*6.59)) vs.append((i*2.1,-i*2/5.5,i*5.8)) vs.append((i*2.1,i*2/5.5,i*5.8)) vs.append((i*2.81,i*2/5.5,i*6.59)) vs.append((i*2.81,-i*2/5.5,i*6.59)) vs.append((i*2.81,-i*2/5.5,i*5.8)) vs.append((i*2.81,i*2/5.5,i*5.8)) vs.append((i*2.81,i*2/7.5,i*6.39)) vs.append((i*2.81,-i*2/7.5,i*6.39)) vs.append((i*2.81,-i*2/7.5,i*6)) vs.append((i*2.81,i*2/7.5,i*6)) vs.append((i*3.7,i*2/7.5,i*6.39)) vs.append((i*3.7,-i*2/7.5,i*6.39)) vs.append((i*3.7,-i*2/7.5,i*6)) vs.append((i*3.7,i*2/7.5,i*6)) vs.append((i*3.7,i*2/6.5,i*6.49)) vs.append((i*3.7,-i*2/6.5,i*6.49)) vs.append((i*3.7,-i*2/6.5,i*5.9)) vs.append((i*3.7,i*2/6.5,i*5.9)) vs.append((i*4.2,i*2/6.5,i*6.49)) vs.append((i*4.2,-i*2/6.5,i*6.49)) vs.append((i*4.2,-i*2/6.5,i*5.9)) vs.append((i*4.2,i*2/6.5,i*5.9)) vs.append((i*4.2,i*2/8.5,i*6.39)) vs.append((i*4.2,-i*2/6.5,i*6.39)) vs.append((i*4.2,-i*2/6.5,i*6.1)) vs.append((i*4.2,i*2/8.5,i*6.1)) vs.append((i*4.5,i*2/8.5,i*6.39)) vs.append((i*4.5,-i*2/4.5,i*6.39)) vs.append((i*4.5,-i*2/4.5,i*6.1)) vs.append((i*4.5,i*2/8.5,i*6.1)) vs.append((i*4.6,i*2/8.5,i*6.39)) vs.append((i*4.6,-i*2/4.5,i*6.39)) vs.append((i*4.6,-i*2/4.5,i*6.1)) vs.append((i*4.6,i*2/8.5,i*6.1)) vs.append((i*4.6,i*2/8.5,i*6.39)) vs.append((i*4.6,-i*2/8.5,i*6.39)) vs.append((i*4.6,-i*2/8.5,i*6.1)) vs.append((i*4.6,i*2/8.5,i*6.1)) vs.append((i*4.8,i*2/8.5,i*6.39)) vs.append((i*4.8,-i*2/8.5,i*6.39)) vs.append((i*4.8,-i*2/8.5,i*6.1)) vs.append((i*4.8,i*2/8.5,i*6.1)) mesh = bpy.data.meshes.new('mesh') mesh.from_pydata(vs,es,fs) mesh.update() #meshobj meshobj= bpy.data.objects.new('mesh',mesh) #collection new_collection = bpy.data.collections.new('new_collection') bpy.context.scene.collection.children.link(new_collection) new_collection.objects.link(meshobj)
Вот генерация такого меша, который состоит из точек
Когда скрипт отработает надо выбрать точки счелкнуть ПКМ и выбрать Convert To -> Mesh.
Ниже показаны некоторые артефакты данного подхода — пофиксил удалением этих точек, соответственно если кому-то будет интересно делать на этой базе процедурную генерацию по параметрам имейте ввиду.
Вот как это выглядит
Ниже представлен уже собранный в полигоны, и прокинутый через миксамо меш, с тестовой анимацией Run
визуализация стыков
скелет в миксамо выбирался по принципу варешка и большой палец.
ссылка на оригинал статьи https://habr.com/ru/articles/880248/
Добавить комментарий