Всем привет. Сегодня будет заключительная статья на тему программирования в мире 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))
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)Вот генерация такого меша, который состоит из точек

Вот как это выглядит
Ниже представлен уже собранный в полигоны, и прокинутый через миксамо меш, с тестовой анимацией Run

