Mannequin.js:铰接式人体模型库

2020-12-05 00:26:55

Mannequin.js是一个关节模型人物的简单库。图形的形状及其移动完全是用JavaScript完成的。图形在Three.js中实现。单击图像以打开实时演示。

这是人体模型的第四种化身。第一个是在Elica中实现的。第二个是在C / C ++和OpenGL中实现的。第三个是在JS / Three.js中实现的,是当前mannequin.js的直接前身。从第一个版本开始,mannequin.js就被用于数学和计算机系的计算机科学本科生课程中。索非亚大学信息学。

此存储库中包含Three.js,以防止与将来的版本不兼容。 Three.js不是mannequin.js的一部分。

mannequin.js库是作为JavaScript文件提供的,必须与three.js一起包含。

这是在浏览器中创建男性形象的最小程序(实时示例):

<!DOCTYPE html> < html> < head> < script src =" three.min.js" >< / script> < script src =" mannequin.min.js" >< / script> < / head> < body> < script> createScene(); var man = new Male(); < / script> < / body> < / html>

辅助函数createScene()提供场景及其元素(如照明,相机,地面等)的默认设置。另一个辅助函数animate(t)负责在t时刻定义人物的姿势。如果设置是使用自定义功能完成的,则它还应该自己管理动画循环。

var man = new Male();人 。职位。设置(20,3.5,0);人 。转(-120); :var woman = new Female();女人。职位。设置(-20,2,0);女人。转(-60); :var kid = new Child();小子。职位。 y =-8;小子。转(-90); :

这三个类别有一个共同的前身-人体模型(feminine,height),其中女性是布尔值,定义形状是女性还是男性,第二个参数是相对身高的数字(成人的身高为1)。

所有类型的图形都具有相同的关节结构。例如,图形的右臂由r_arm访问。左右身体部位与图形有关,而不与观察者有关(实况示例):

每个身体部位都有绕枢轴旋转的旋转方法。方法的第一个参数角度是旋转角度(以度为单位),因此180度是半圈,而360度是全圈。允许使用负角,它们表示沿相反方向旋转。一些方法具有用于运动方向的可选第二参数,可以是常数LEFT或RIGHT。

中央的身体部位只有一个实例-头部,颈部,躯干,骨盆和整个身体。使用整个身体的移动方法弯曲,旋转和倾斜图形(实时示例):

躯干具有与整个身体相同的方法:弯曲,旋转和倾斜(实时示例):

尽管脖子是身体的一个独立部分,但并不是单独控制它。相反,一部分头部运动分布在脖子上。同样,骨盆也不是单独控制的。而是通过弯曲,转动和倾斜来控制整个身体。

两种手臂支撑方法都可以举起,跨骑和转弯(现场示例)。以下列表是指右臂,但是右手可以使用相同的方法:

如果省略了方向参数,则跨骑和转弯的默认运动是对称的。例如,左臂跨在左侧,而右臂跨在右侧(实时示例)。

肘部的运动仅是弯曲的(实时示例)。角度的负值会导致肘部位置不自然。

手腕具有与躯干相同的方法:弯曲,旋转和倾斜(实时示例),但与手臂相似,如果未设置方向,则方向是对称的:

上肢的最后一个身体部位是手指。它们只能弯曲(实时示例),但是它们由两个部分组成,并且弯曲角度分布在两个部分上。

双腿支撑方法举起,跨骑和转弯(现场示例)。如果未设置折旧,则跨骑和转弯是对称的。

膝盖的动作只是弯曲(现场示例)。角度的负值会导致膝盖位置不自然。

脚腕的方法与手腕相同:弯曲,转弯和倾斜(实时示例),但是与腿相似,如果未设置方向,则方向是对称的:

通过设置身体部位的旋转来定义人物的姿势。旋转顺序是固定的,与用户程序中的旋转顺序无关(实时示例)。例如:

有时这可能会导致意外的结果,尤其是如果用户假设旋转顺序与mannequin.js使用的顺序不同。当身体部位绕3或2轴旋转时,可能会发生这种情况。

静态姿势定义了不变的身体部位的位置。默认情况下,创建图形时,其身体部位将设置为默认姿势。此版本的mannequin.js不提供姿势编辑器,因此必须以编程方式定义所有旋转。

有时最好逐步定义图形。太极拳的姿势(现场示例)可以从定义整个豆荚位置开始:

动态姿势(即随时间变化的姿势)的设置方法与静态姿势相同。 Mannequin.js定义了一个空函数animate(t),该动画函数在动画循环中为每个帧调用一次。姿势的所有更改都应在此函数内定义(实时示例)。参数t是时间,以十分之一秒为单位。此函数在createScene()中设置。如果不使用createScene和animate,则应手动管理动画循环。

函数animate(t){var time1 =(sin(2 * t)+ cos(3 * t)+ cos(5 * t))/ 3,time2 =(sin(2 * t-60)+ cos(3 * t-90)+ cos(5 * t-120))/ 3;球 。职位。 x =-3 * time1;孩子。职位。 x =-3 * time1;孩子。职位。 y = 4 + cos(90 * time1);孩子。转(-90-20 * time1 + 20 * time2);孩子。倾斜(10 * time1); :场景。回转 。 y = rad(30 * time1); }

为了使动画循环更快,应在动画外部定义所有恒定旋转。同样,如果循环中的旋转子发生变化,则无需在循环外进行设置。

除了移动身体部位,mannequin.js的当前版本还提供了用于其他修改或访问该图的基本功能。

默认情况下,所有图形都为身体部位使用一组预定义的全局颜色。全局颜色以六种Three.js颜色或小写HTML / CSS颜色名称的特定顺序存储在Mannequin.colors数组中-头部,鞋子,骨盆,关节,四肢和躯干:

模特儿。颜色= ['古董白,//头'灰色' ,//鞋子'古董白,//骨盆' burlywood' ,//关节'古董白,//四肢'浓汤//躯干];

关节和四肢的整体颜色是指所有关节和所有四肢。如果在创建图形实例之前完成对Mannequin.colors中的全局颜色的修改,则该更改生效。身体部位的颜色通过关节的重新着色方法设置(现场示例):

//全局颜色模特。颜色= ['浅绿色' ,'黑色' ,'黑色' ,'白色' ,' darkolivegreen' ,'暗裂]; var man = new Male(); ://各个颜色的人。 l_elbow。重新着色('黄色',黑色');人 。 l_wrist。重新着色('橙色');人 。 l_fingers。重新着色('珊瑚');人 。 l_fingers。提示 。重新着色('栗色');人 。 r_knee。重新着色(" antiquewhite','黑色');

重新着色的第一个参数是关节主要部分的颜色。第二个参数是身体部分的球形部分的颜色。

每个身体部位都可以隐藏。这不会从图中删除主体部分及其图形对象,而是只是未在框架中呈现。从图形隐藏关节的方法是:

其中joint是要隐藏的身体部位的名称。隐藏的身体部位仍然可以旋转,这会影响连接到它们的其他身体部位。以下示例隐藏了双臂和双腿,但是它们仍在内部保留,并由肘部和膝盖使用(实时示例):

主体部分是THREE.Object3D的后代,并支持其属性和方法。但是,由于骨骼的依赖性和关节的附着,身体部位的缩放应沿所有轴一致,否则需要调整位置(实时示例):

任何自定义THREE.Object3D都可以附加到身体部位。附着的对象包含在身体中,并且会受到身体所做的任何运动的影响:

可以将对象附加到隐藏的身体部位,但不会自动隐藏它们。此方法用于将主体部分替换为完全自定义的用户对象(实时示例):

man =新的Male(); //添加手镯镯子=新的三个。网格(新的3个.CylinderGeometry(3,3,1,16),新的3个。MeshPhongMaterial({color:' crimson',shininess:200}));手镯。 castShadow = true;手镯。职位。 y = 6;人 。 l_elbow。附上(手镯);手镯=手镯。克隆();人 。 r_elbow。附上(手镯); //用其他物体替换腿man。 r_leg。隐藏();材料=新三。 MeshPhongMaterial({color:'深红色',光泽度:200}); obj =新的三个。网格(新的三个。CylinderGeometry(3,2,3,32),材质); obj。 castShadow = true; obj。职位。 y = 2;人 。 r_leg。附加(obj);

并非所有的图形与其他对象之间的交互都可以通过附加实现。人体模型js为每个身体部位提供方法点(x,y,z)。此方法计算在身体部位的局部坐标系中定义的点(x,y,z)的全局坐标。

下面的示例创建一个相对于图形的身体部位贯穿5个点的线程(实时示例):

全球头寸可用于确定数字,这是将其置于实地的依据。但是,mannequin.js不包含任何碰撞功能,因此用户应选择碰撞点并测试其全局位置。

以下示例在每只鞋子上使用四个接触点(即man.r_ankle和man.l_ankle)。第八接触点的最小垂直位置用于调整图形的垂直位置(实时示例):

//获得最小的接触点垂直位置var bottom = Math。 min(man.l_ankle.point(-2,2,2)。y,man.l_ankle.point(-2,2,-2)。y,man.l_ankle。point(-2.5,-1,0)。 y,man。l_ankle。point(-2.1,6,0)。y,man。r_ankle。point(--2,2,2)。y,man。r_ankle。point(-2,2,-2)。y ,man。r_ankle。point(-2.5,-1,0)。y,man。r_ankle。point(-2.1,6,0)。y);人 。职位。 y + =(-29.5-bottom);

当前,mannequin.js用于支持“计算机图形学基础”课程中的一项家庭作业。显然,该库可用于其他活动。这为功能的进一步改进提供了思路。