Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
a5642d0f
T
three.js
项目概览
车家大少爷
/
three.js
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
three.js
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a5642d0f
编写于
11月 25, 2015
作者:
M
Mr.doob
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #7585 from takahirox/MMDLoader
Physics support for THREE.MMDLoader.
上级
264773c1
5c6651f3
变更
5
展开全部
隐藏空白更改
内联
并排
Showing
5 changed file
with
1587 addition
and
77 deletion
+1587
-77
examples/js/animation/CCDIKSolver.js
examples/js/animation/CCDIKSolver.js
+0
-33
examples/js/animation/MMDPhysics.js
examples/js/animation/MMDPhysics.js
+938
-0
examples/js/libs/ammo.js
examples/js/libs/ammo.js
+38
-0
examples/js/loaders/MMDLoader.js
examples/js/loaders/MMDLoader.js
+532
-30
examples/webgl_loader_mmd.html
examples/webgl_loader_mmd.html
+79
-14
未找到文件。
examples/js/animation/CCDIKSolver.js
浏览文件 @
a5642d0f
...
...
@@ -22,14 +22,6 @@ THREE.CCDIKSolver = function ( mesh ) {
this
.
mesh
=
mesh
;
var
bones
=
mesh
.
skeleton
.
bones
;
this
.
orgBones
=
[];
for
(
var
i
=
0
;
i
<
bones
.
length
;
i
++
)
{
this
.
orgBones
.
push
(
bones
[
i
].
clone
()
);
}
};
THREE
.
CCDIKSolver
.
prototype
=
{
...
...
@@ -139,31 +131,6 @@ THREE.CCDIKSolver.prototype = {
}
},
resetLinks
:
function
()
{
var
bones
=
this
.
mesh
.
skeleton
.
bones
;
var
iks
=
this
.
mesh
.
geometry
.
iks
;
for
(
var
i
=
0
,
il
=
iks
.
length
;
i
<
il
;
i
++
)
{
var
ik
=
iks
[
i
];
var
links
=
ik
.
links
;
for
(
var
j
=
0
;
j
<
links
.
length
;
j
++
)
{
var
link
=
links
[
j
];
var
index
=
link
.
index
;
var
b
=
bones
[
index
];
var
b2
=
this
.
orgBones
[
index
];
//b.position.copy( b2.position );
b
.
quaternion
.
copy
(
b2
.
quaternion
);
}
}
}
};
...
...
examples/js/animation/MMDPhysics.js
0 → 100644
浏览文件 @
a5642d0f
/**
* @author takahiro / https://github.com/takahirox
*
* Dependencies
* - Ammo.js https://github.com/kripken/ammo.js
*
*
* MMD specific Physics class.
*
* See THREE.MMDLoader for the passed parameter list of RigidBody/Constraint.
*
*
* TODO
* - use Physijs http://chandlerprall.github.io/Physijs/
* and improve the performance by making use of Web worker.
* - if possible, make this class being non-MMD specific.
*/
THREE
.
MMDPhysics
=
function
(
mesh
)
{
this
.
mesh
=
mesh
;
this
.
helper
=
new
THREE
.
MMDPhysics
.
PhysicsHelper
();
this
.
world
=
null
;
this
.
bodies
=
[];
this
.
constraints
=
[];
this
.
init
();
};
THREE
.
MMDPhysics
.
prototype
=
{
constructor
:
THREE
.
MMDPhysics
,
init
:
function
()
{
this
.
initWorld
();
this
.
initRigidBodies
();
this
.
initConstraints
();
this
.
reset
();
},
initWorld
:
function
()
{
var
config
=
new
Ammo
.
btDefaultCollisionConfiguration
();
var
dispatcher
=
new
Ammo
.
btCollisionDispatcher
(
config
);
var
cache
=
new
Ammo
.
btDbvtBroadphase
();
var
solver
=
new
Ammo
.
btSequentialImpulseConstraintSolver
();
var
world
=
new
Ammo
.
btDiscreteDynamicsWorld
(
dispatcher
,
cache
,
solver
,
config
);
world
.
setGravity
(
new
Ammo
.
btVector3
(
0
,
-
10
*
10
,
0
)
);
this
.
world
=
world
;
},
initRigidBodies
:
function
()
{
var
bodies
=
this
.
mesh
.
geometry
.
rigidBodies
;
for
(
var
i
=
0
;
i
<
bodies
.
length
;
i
++
)
{
var
b
=
new
THREE
.
MMDPhysics
.
RigidBody
(
this
.
mesh
,
this
.
world
,
bodies
[
i
],
this
.
helper
);
this
.
bodies
.
push
(
b
);
}
},
initConstraints
:
function
()
{
var
constraints
=
this
.
mesh
.
geometry
.
constraints
;
for
(
var
i
=
0
;
i
<
constraints
.
length
;
i
++
)
{
var
params
=
constraints
[
i
];
var
bodyA
=
this
.
bodies
[
params
.
rigidBodyIndex1
];
var
bodyB
=
this
.
bodies
[
params
.
rigidBodyIndex2
];
var
c
=
new
THREE
.
MMDPhysics
.
Constraint
(
this
.
mesh
,
this
.
world
,
bodyA
,
bodyB
,
params
,
this
.
helper
);
this
.
constraints
.
push
(
c
);
}
},
update
:
function
(
delta
)
{
var
unitStep
=
1
/
60
;
var
stepTime
=
delta
;
var
maxStepNum
=
(
(
delta
/
unitStep
)
|
0
)
+
1
;
if
(
maxStepNum
>
3
)
{
maxStepNum
=
3
;
}
this
.
updateRigidBodies
();
this
.
world
.
stepSimulation
(
stepTime
,
maxStepNum
,
unitStep
);
this
.
updateBones
();
},
updateRigidBodies
:
function
()
{
for
(
var
i
=
0
;
i
<
this
.
bodies
.
length
;
i
++
)
{
this
.
bodies
[
i
].
updateFromBone
();
}
},
updateBones
:
function
()
{
for
(
var
i
=
0
;
i
<
this
.
bodies
.
length
;
i
++
)
{
this
.
bodies
[
i
].
updateBone
();
}
},
reset
:
function
()
{
for
(
var
i
=
0
;
i
<
this
.
bodies
.
length
;
i
++
)
{
this
.
bodies
[
i
].
reset
();
}
},
warmup
:
function
(
cycles
)
{
for
(
var
i
=
0
;
i
<
cycles
;
i
++
)
{
this
.
update
(
1
);
}
}
};
/**
* This helper class responsibilies are
*
* 1. manage Ammo.js and Three.js object resources and
* improve the performance and the memory consumption by
* reusing objects.
*
* 2. provide simple Ammo object operations.
*/
THREE
.
MMDPhysics
.
PhysicsHelper
=
function
()
{
// for Three.js
this
.
threeVector3s
=
[];
this
.
threeMatrix4s
=
[];
this
.
threeQuaternions
=
[];
// for Ammo.js
this
.
transforms
=
[];
this
.
quaternions
=
[];
this
.
vector3s
=
[];
};
THREE
.
MMDPhysics
.
PhysicsHelper
.
prototype
=
{
allocThreeVector3
:
function
()
{
return
(
this
.
threeVector3s
.
length
>
0
)
?
this
.
threeVector3s
.
pop
()
:
new
THREE
.
Vector3
();
},
freeThreeVector3
:
function
(
v
)
{
this
.
threeVector3s
.
push
(
v
);
},
allocThreeMatrix4
:
function
()
{
return
(
this
.
threeMatrix4s
.
length
>
0
)
?
this
.
threeMatrix4s
.
pop
()
:
new
THREE
.
Matrix4
();
},
freeThreeMatrix4
:
function
(
m
)
{
this
.
threeMatrix4s
.
push
(
m
);
},
allocThreeQuaternion
:
function
()
{
return
(
this
.
threeQuaternions
.
length
>
0
)
?
this
.
threeQuaternions
.
pop
()
:
new
THREE
.
Quaternion
();
},
freeThreeQuaternion
:
function
(
q
)
{
this
.
threeQuaternions
.
push
(
q
);
},
allocTransform
:
function
()
{
return
(
this
.
transforms
.
length
>
0
)
?
this
.
transforms
.
pop
()
:
new
Ammo
.
btTransform
();
},
freeTransform
:
function
(
t
)
{
this
.
transforms
.
push
(
t
);
},
allocQuaternion
:
function
()
{
return
(
this
.
quaternions
.
length
>
0
)
?
this
.
quaternions
.
pop
()
:
new
Ammo
.
btQuaternion
();
},
freeQuaternion
:
function
(
q
)
{
this
.
quaternions
.
push
(
q
);
},
allocVector3
:
function
()
{
return
(
this
.
vector3s
.
length
>
0
)
?
this
.
vector3s
.
pop
()
:
new
Ammo
.
btVector3
();
},
freeVector3
:
function
(
v
)
{
this
.
vector3s
.
push
(
v
);
},
setIdentity
:
function
(
t
)
{
t
.
setIdentity
();
},
getBasis
:
function
(
t
)
{
var
q
=
this
.
allocQuaternion
();
t
.
getBasis
().
getRotation
(
q
);
return
q
;
},
getBasisAsMatrix3
:
function
(
t
)
{
var
q
=
this
.
getBasis
(
t
);
var
m
=
this
.
quaternionToMatrix3
(
q
);
this
.
freeQuaternion
(
q
);
return
m
;
},
getOrigin
:
function
(
t
)
{
return
t
.
getOrigin
();
},
setOrigin
:
function
(
t
,
v
)
{
t
.
getOrigin
().
setValue
(
v
.
x
(),
v
.
y
(),
v
.
z
()
);
},
copyOrigin
:
function
(
t1
,
t2
)
{
var
o
=
t2
.
getOrigin
();
this
.
setOrigin
(
t1
,
o
);
},
setBasis
:
function
(
t
,
q
)
{
t
.
setRotation
(
q
);
},
setBasisFromMatrix3
:
function
(
t
,
m
)
{
var
q
=
this
.
matrix3ToQuaternion
(
m
);
this
.
setBasis
(
t
,
q
);
this
.
freeQuaternion
(
q
);
},
setOriginFromArray3
:
function
(
t
,
a
)
{
t
.
getOrigin
().
setValue
(
a
[
0
],
a
[
1
],
a
[
2
]
);
},
setBasisFromArray3
:
function
(
t
,
a
)
{
t
.
getBasis
().
setEulerZYX
(
a
[
0
],
a
[
1
],
a
[
2
]
);
},
setBasisFromArray4
:
function
(
t
,
a
)
{
var
q
=
this
.
array4ToQuaternion
(
a
);
this
.
setBasis
(
t
,
q
);
this
.
freeQuaternion
(
q
);
},
array4ToQuaternion
:
function
(
a
)
{
var
q
=
this
.
allocQuaternion
();
q
.
setX
(
a
[
0
]
);
q
.
setY
(
a
[
1
]
);
q
.
setZ
(
a
[
2
]
);
q
.
setW
(
a
[
3
]
);
return
q
;
},
multiplyTransforms
:
function
(
t1
,
t2
)
{
var
t
=
this
.
allocTransform
();
this
.
setIdentity
(
t
);
var
m1
=
this
.
getBasisAsMatrix3
(
t1
);
var
m2
=
this
.
getBasisAsMatrix3
(
t2
);
var
o1
=
this
.
getOrigin
(
t1
);
var
o2
=
this
.
getOrigin
(
t2
);
var
v1
=
this
.
multiplyMatrix3ByVector3
(
m1
,
o2
);
var
v2
=
this
.
addVector3
(
v1
,
o1
);
this
.
setOrigin
(
t
,
v2
);
var
m3
=
this
.
multiplyMatrices3
(
m1
,
m2
);
this
.
setBasisFromMatrix3
(
t
,
m3
);
this
.
freeVector3
(
v1
);
this
.
freeVector3
(
v2
);
return
t
;
},
inverseTransform
:
function
(
t
)
{
var
t2
=
this
.
allocTransform
();
var
m1
=
this
.
getBasisAsMatrix3
(
t
);
var
o
=
this
.
getOrigin
(
t
);
var
m2
=
this
.
transposeMatrix3
(
m1
);
var
v1
=
this
.
negativeVector3
(
o
);
var
v2
=
this
.
multiplyMatrix3ByVector3
(
m2
,
v1
);
this
.
setOrigin
(
t2
,
v2
);
this
.
setBasisFromMatrix3
(
t2
,
m2
);
this
.
freeVector3
(
v1
);
this
.
freeVector3
(
v2
);
return
t2
;
},
multiplyMatrices3
:
function
(
m1
,
m2
)
{
var
m3
=
[];
var
v10
=
this
.
rowOfMatrix3
(
m1
,
0
);
var
v11
=
this
.
rowOfMatrix3
(
m1
,
1
);
var
v12
=
this
.
rowOfMatrix3
(
m1
,
2
);
var
v20
=
this
.
columnOfMatrix3
(
m2
,
0
);
var
v21
=
this
.
columnOfMatrix3
(
m2
,
1
);
var
v22
=
this
.
columnOfMatrix3
(
m2
,
2
);
m3
[
0
]
=
this
.
dotVectors3
(
v10
,
v20
);
m3
[
1
]
=
this
.
dotVectors3
(
v10
,
v21
);
m3
[
2
]
=
this
.
dotVectors3
(
v10
,
v22
);
m3
[
3
]
=
this
.
dotVectors3
(
v11
,
v20
);
m3
[
4
]
=
this
.
dotVectors3
(
v11
,
v21
);
m3
[
5
]
=
this
.
dotVectors3
(
v11
,
v22
);
m3
[
6
]
=
this
.
dotVectors3
(
v12
,
v20
);
m3
[
7
]
=
this
.
dotVectors3
(
v12
,
v21
);
m3
[
8
]
=
this
.
dotVectors3
(
v12
,
v22
);
this
.
freeVector3
(
v10
);
this
.
freeVector3
(
v11
);
this
.
freeVector3
(
v12
);
this
.
freeVector3
(
v20
);
this
.
freeVector3
(
v21
);
this
.
freeVector3
(
v22
);
return
m3
;
},
addVector3
:
function
(
v1
,
v2
)
{
var
v
=
this
.
allocVector3
();
v
.
setValue
(
v1
.
x
()
+
v2
.
x
(),
v1
.
y
()
+
v2
.
y
(),
v1
.
z
()
+
v2
.
z
()
);
return
v
;
},
dotVectors3
:
function
(
v1
,
v2
)
{
return
v1
.
x
()
*
v2
.
x
()
+
v1
.
y
()
*
v2
.
y
()
+
v1
.
z
()
*
v2
.
z
();
},
rowOfMatrix3
:
function
(
m
,
i
)
{
var
v
=
this
.
allocVector3
();
v
.
setValue
(
m
[
i
*
3
+
0
],
m
[
i
*
3
+
1
],
m
[
i
*
3
+
2
]
);
return
v
;
},
columnOfMatrix3
:
function
(
m
,
i
)
{
var
v
=
this
.
allocVector3
();
v
.
setValue
(
m
[
i
+
0
],
m
[
i
+
3
],
m
[
i
+
6
]
);
return
v
;
},
negativeVector3
:
function
(
v
)
{
var
v2
=
this
.
allocVector3
();
v2
.
setValue
(
-
v
.
x
(),
-
v
.
y
(),
-
v
.
z
()
);
return
v2
;
},
multiplyMatrix3ByVector3
:
function
(
m
,
v
)
{
var
v4
=
this
.
allocVector3
();
var
v0
=
this
.
rowOfMatrix3
(
m
,
0
);
var
v1
=
this
.
rowOfMatrix3
(
m
,
1
);
var
v2
=
this
.
rowOfMatrix3
(
m
,
2
);
var
x
=
this
.
dotVectors3
(
v0
,
v
);
var
y
=
this
.
dotVectors3
(
v1
,
v
);
var
z
=
this
.
dotVectors3
(
v2
,
v
);
v4
.
setValue
(
x
,
y
,
z
);
this
.
freeVector3
(
v0
);
this
.
freeVector3
(
v1
);
this
.
freeVector3
(
v2
);
return
v4
;
},
transposeMatrix3
:
function
(
m
)
{
var
m2
=
[];
m2
[
0
]
=
m
[
0
];
m2
[
1
]
=
m
[
3
];
m2
[
2
]
=
m
[
6
];
m2
[
3
]
=
m
[
1
];
m2
[
4
]
=
m
[
4
];
m2
[
5
]
=
m
[
7
];
m2
[
6
]
=
m
[
2
];
m2
[
7
]
=
m
[
5
];
m2
[
8
]
=
m
[
8
];
return
m2
;
},
quaternionToMatrix3
:
function
(
q
)
{
var
m
=
[];
var
x
=
q
.
x
();
var
y
=
q
.
y
();
var
z
=
q
.
z
();
var
w
=
q
.
w
();
var
xx
=
x
*
x
;
var
yy
=
y
*
y
;
var
zz
=
z
*
z
;
var
xy
=
x
*
y
;
var
yz
=
y
*
z
;
var
zx
=
z
*
x
;
var
xw
=
x
*
w
;
var
yw
=
y
*
w
;
var
zw
=
z
*
w
;
m
[
0
]
=
1
-
2
*
(
yy
+
zz
);
m
[
1
]
=
2
*
(
xy
-
zw
);
m
[
2
]
=
2
*
(
zx
+
yw
);
m
[
3
]
=
2
*
(
xy
+
zw
);
m
[
4
]
=
1
-
2
*
(
zz
+
xx
);
m
[
5
]
=
2
*
(
yz
-
xw
);
m
[
6
]
=
2
*
(
zx
-
yw
);
m
[
7
]
=
2
*
(
yz
+
xw
);
m
[
8
]
=
1
-
2
*
(
xx
+
yy
);
return
m
;
},
matrix3ToQuaternion
:
function
(
m
)
{
var
t
=
m
[
0
]
+
m
[
4
]
+
m
[
8
];
var
s
,
x
,
y
,
z
,
w
;
if
(
t
>
0
)
{
s
=
Math
.
sqrt
(
t
+
1.0
)
*
2
;
w
=
0.25
*
s
;
x
=
(
m
[
7
]
-
m
[
5
]
)
/
s
;
y
=
(
m
[
2
]
-
m
[
6
]
)
/
s
;
z
=
(
m
[
3
]
-
m
[
1
]
)
/
s
;
}
else
if
(
(
m
[
0
]
>
m
[
4
]
)
&&
(
m
[
0
]
>
m
[
8
]
)
)
{
s
=
Math
.
sqrt
(
1.0
+
m
[
0
]
-
m
[
4
]
-
m
[
8
]
)
*
2
;
w
=
(
m
[
7
]
-
m
[
5
]
)
/
s
;
x
=
0.25
*
s
;
y
=
(
m
[
1
]
+
m
[
3
]
)
/
s
;
z
=
(
m
[
2
]
+
m
[
6
]
)
/
s
;
}
else
if
(
m
[
4
]
>
m
[
8
]
)
{
s
=
Math
.
sqrt
(
1.0
+
m
[
4
]
-
m
[
0
]
-
m
[
8
]
)
*
2
;
w
=
(
m
[
2
]
-
m
[
6
]
)
/
s
;
x
=
(
m
[
1
]
+
m
[
3
]
)
/
s
;
y
=
0.25
*
s
;
z
=
(
m
[
5
]
+
m
[
7
]
)
/
s
;
}
else
{
s
=
Math
.
sqrt
(
1.0
+
m
[
8
]
-
m
[
0
]
-
m
[
4
]
)
*
2
;
w
=
(
m
[
3
]
-
m
[
1
]
)
/
s
;
x
=
(
m
[
2
]
+
m
[
6
]
)
/
s
;
y
=
(
m
[
5
]
+
m
[
7
]
)
/
s
;
z
=
0.25
*
s
;
}
var
q
=
this
.
allocQuaternion
();
q
.
setX
(
x
);
q
.
setY
(
y
);
q
.
setZ
(
z
);
q
.
setW
(
w
);
return
q
;
},
};
THREE
.
MMDPhysics
.
RigidBody
=
function
(
mesh
,
world
,
params
,
helper
)
{
this
.
mesh
=
mesh
;
this
.
world
=
world
;
this
.
params
=
params
;
this
.
helper
=
helper
;
this
.
body
=
null
;
this
.
bone
=
null
;
this
.
boneOffsetForm
=
null
;
this
.
boneOffsetFormInverse
=
null
;
this
.
init
();
};
THREE
.
MMDPhysics
.
RigidBody
.
prototype
=
{
constructor
:
THREE
.
MMDPhysics
.
RigidBody
,
init
:
function
()
{
function
generateShape
(
p
)
{
switch
(
p
.
shapeType
)
{
case
0
:
return
new
Ammo
.
btSphereShape
(
p
.
width
);
case
1
:
return
new
Ammo
.
btBoxShape
(
new
Ammo
.
btVector3
(
p
.
width
,
p
.
height
,
p
.
depth
)
);
case
2
:
return
new
Ammo
.
btCapsuleShape
(
p
.
width
,
p
.
height
);
default
:
throw
'
unknown shape type
'
+
p
.
shapeType
;
}
};
var
helper
=
this
.
helper
;
var
params
=
this
.
params
;
var
bones
=
this
.
mesh
.
skeleton
.
bones
;
var
bone
=
(
params
.
boneIndex
===
-
1
)
?
new
THREE
.
Bone
()
:
bones
[
params
.
boneIndex
];
var
shape
=
generateShape
(
params
);
var
weight
=
(
params
.
type
===
0
)
?
0
:
params
.
weight
;
var
localInertia
=
helper
.
allocVector3
();
localInertia
.
setValue
(
0
,
0
,
0
);
if
(
weight
!==
0
)
{
shape
.
calculateLocalInertia
(
weight
,
localInertia
);
}
var
boneOffsetForm
=
helper
.
allocTransform
();
helper
.
setIdentity
(
boneOffsetForm
);
helper
.
setOriginFromArray3
(
boneOffsetForm
,
params
.
position
);
helper
.
setBasisFromArray3
(
boneOffsetForm
,
params
.
rotation
);
var
boneForm
=
helper
.
allocTransform
();
helper
.
setIdentity
(
boneForm
);
helper
.
setOriginFromArray3
(
boneForm
,
bone
.
getWorldPosition
().
toArray
()
);
var
form
=
helper
.
multiplyTransforms
(
boneForm
,
boneOffsetForm
);
var
state
=
new
Ammo
.
btDefaultMotionState
(
form
);
var
info
=
new
Ammo
.
btRigidBodyConstructionInfo
(
weight
,
state
,
shape
,
localInertia
);
info
.
set_m_friction
(
params
.
friction
);
info
.
set_m_restitution
(
params
.
restriction
);
var
body
=
new
Ammo
.
btRigidBody
(
info
);
if
(
params
.
type
===
0
)
{
body
.
setCollisionFlags
(
body
.
getCollisionFlags
()
|
2
);
body
.
setActivationState
(
4
);
}
body
.
setDamping
(
params
.
positionDamping
,
params
.
rotationDamping
);
body
.
setSleepingThresholds
(
0
,
0
);
this
.
world
.
addRigidBody
(
body
,
1
<<
params
.
groupIndex
,
params
.
groupTarget
);
this
.
body
=
body
;
this
.
bone
=
bone
;
this
.
boneOffsetForm
=
boneOffsetForm
;
this
.
boneOffsetFormInverse
=
helper
.
inverseTransform
(
boneOffsetForm
);
helper
.
freeVector3
(
localInertia
);
helper
.
freeTransform
(
form
);
helper
.
freeTransform
(
boneForm
);
},
reset
:
function
()
{
this
.
setTransformFromBone
();
},
updateFromBone
:
function
()
{
if
(
this
.
params
.
boneIndex
===
-
1
)
{
return
;
}
if
(
this
.
params
.
type
===
0
)
{
this
.
setTransformFromBone
();
}
if
(
this
.
params
.
type
===
2
)
{
this
.
setPositionFromBone
();
}
},
updateBone
:
function
()
{
if
(
this
.
params
.
type
===
0
||
this
.
params
.
boneIndex
===
-
1
)
{
return
;
}
this
.
updateBoneRotation
();
if
(
this
.
params
.
type
===
1
)
{
this
.
updateBonePosition
();
}
this
.
bone
.
updateMatrixWorld
(
true
);
},
getBoneTransform
:
function
()
{
var
helper
=
this
.
helper
;
var
p
=
this
.
bone
.
getWorldPosition
();
var
q
=
this
.
bone
.
getWorldQuaternion
();
var
tr
=
helper
.
allocTransform
();
helper
.
setOriginFromArray3
(
tr
,
p
.
toArray
()
);
helper
.
setBasisFromArray4
(
tr
,
q
.
toArray
()
);
var
form
=
helper
.
multiplyTransforms
(
tr
,
this
.
boneOffsetForm
);
helper
.
freeTransform
(
tr
);
return
form
;
},
getWorldTransformForBone
:
function
()
{
var
helper
=
this
.
helper
;
var
tr
=
helper
.
allocTransform
();
this
.
body
.
getMotionState
().
getWorldTransform
(
tr
);
var
tr2
=
helper
.
multiplyTransforms
(
tr
,
this
.
boneOffsetFormInverse
);
helper
.
freeTransform
(
tr
);
return
tr2
;
},
setTransformFromBone
:
function
()
{
var
helper
=
this
.
helper
;
var
form
=
this
.
getBoneTransform
();
// TODO: check the most appropriate way to set
//this.body.setWorldTransform( form );
this
.
body
.
setCenterOfMassTransform
(
form
);
this
.
body
.
getMotionState
().
setWorldTransform
(
form
);
helper
.
freeTransform
(
form
);
},
setPositionFromBone
:
function
()
{
var
helper
=
this
.
helper
;
var
form
=
this
.
getBoneTransform
();
var
tr
=
helper
.
allocTransform
();
this
.
body
.
getMotionState
().
getWorldTransform
(
tr
);
helper
.
copyOrigin
(
tr
,
form
);
// TODO: check the most appropriate way to set
//this.body.setWorldTransform( tr );
this
.
body
.
setCenterOfMassTransform
(
tr
);
this
.
body
.
getMotionState
().
setWorldTransform
(
tr
);
helper
.
freeTransform
(
tr
);
helper
.
freeTransform
(
form
);
},
updateBoneRotation
:
function
()
{
this
.
bone
.
updateMatrixWorld
(
true
);
var
helper
=
this
.
helper
;
var
tr
=
this
.
getWorldTransformForBone
();
var
q
=
helper
.
getBasis
(
tr
);
var
thQ
=
helper
.
allocThreeQuaternion
();
var
thQ2
=
helper
.
allocThreeQuaternion
();
thQ
.
set
(
q
.
x
(),
q
.
y
(),
q
.
z
(),
q
.
w
()
);
thQ2
.
setFromRotationMatrix
(
this
.
bone
.
matrixWorld
);
thQ2
.
conjugate
()
thQ2
.
multiply
(
thQ
);
this
.
bone
.
quaternion
.
multiply
(
thQ2
);
helper
.
freeThreeQuaternion
(
thQ
);
helper
.
freeThreeQuaternion
(
thQ2
);
helper
.
freeQuaternion
(
q
);
helper
.
freeTransform
(
tr
);
},
updateBonePosition
:
function
()
{
var
helper
=
this
.
helper
;
var
tr
=
this
.
getWorldTransformForBone
();
var
thV
=
helper
.
allocThreeVector3
();
var
o
=
helper
.
getOrigin
(
tr
);
thV
.
set
(
o
.
x
(),
o
.
y
(),
o
.
z
()
);
var
v
=
this
.
bone
.
worldToLocal
(
thV
);
this
.
bone
.
position
.
add
(
v
);
helper
.
freeThreeVector3
(
thV
);
helper
.
freeTransform
(
tr
);
}
};
THREE
.
MMDPhysics
.
Constraint
=
function
(
mesh
,
world
,
bodyA
,
bodyB
,
params
,
helper
)
{
this
.
mesh
=
mesh
;
this
.
world
=
world
;
this
.
bodyA
=
bodyA
;
this
.
bodyB
=
bodyB
;
this
.
params
=
params
;
this
.
helper
=
helper
;
this
.
constraint
=
null
;
this
.
init
();
};
THREE
.
MMDPhysics
.
Constraint
.
prototype
=
{
constructor
:
THREE
.
MMDPhysics
.
Constraint
,
init
:
function
()
{
var
helper
=
this
.
helper
;
var
params
=
this
.
params
;
var
bodyA
=
this
.
bodyA
;
var
bodyB
=
this
.
bodyB
;
var
form
=
helper
.
allocTransform
();
helper
.
setIdentity
(
form
);
helper
.
setOriginFromArray3
(
form
,
params
.
position
);
helper
.
setBasisFromArray3
(
form
,
params
.
rotation
);
var
formA
=
helper
.
allocTransform
();
var
formB
=
helper
.
allocTransform
();
bodyA
.
body
.
getMotionState
().
getWorldTransform
(
formA
);
bodyB
.
body
.
getMotionState
().
getWorldTransform
(
formB
);
var
formInverseA
=
helper
.
inverseTransform
(
formA
);
var
formInverseB
=
helper
.
inverseTransform
(
formB
);
var
formA2
=
helper
.
multiplyTransforms
(
formInverseA
,
form
);
var
formB2
=
helper
.
multiplyTransforms
(
formInverseB
,
form
);
var
constraint
=
new
Ammo
.
btGeneric6DofSpringConstraint
(
bodyA
.
body
,
bodyB
.
body
,
formA2
,
formB2
,
true
);
var
lll
=
helper
.
allocVector3
();
var
lul
=
helper
.
allocVector3
();
var
all
=
helper
.
allocVector3
();
var
aul
=
helper
.
allocVector3
();
lll
.
setValue
(
params
.
translationLimitation1
[
0
],
params
.
translationLimitation1
[
1
],
params
.
translationLimitation1
[
2
]
);
lul
.
setValue
(
params
.
translationLimitation2
[
0
],
params
.
translationLimitation2
[
1
],
params
.
translationLimitation2
[
2
]
);
all
.
setValue
(
params
.
rotationLimitation1
[
0
],
params
.
rotationLimitation1
[
1
],
params
.
rotationLimitation1
[
2
]
);
aul
.
setValue
(
params
.
rotationLimitation2
[
0
],
params
.
rotationLimitation2
[
1
],
params
.
rotationLimitation2
[
2
]
);
constraint
.
setLinearLowerLimit
(
lll
);
constraint
.
setLinearUpperLimit
(
lul
);
constraint
.
setAngularLowerLimit
(
all
);
constraint
.
setAngularUpperLimit
(
aul
);
for
(
var
i
=
0
;
i
<
3
;
i
++
)
{
if
(
params
.
springPosition
[
i
]
!==
0
)
{
constraint
.
enableSpring
(
i
,
true
);
constraint
.
setStiffness
(
i
,
params
.
springPosition
[
i
]
);
}
}
for
(
var
i
=
0
;
i
<
3
;
i
++
)
{
if
(
params
.
springRotation
[
i
]
!==
0
)
{
constraint
.
enableSpring
(
i
+
3
,
true
);
constraint
.
setStiffness
(
i
+
3
,
params
.
springRotation
[
i
]
);
}
}
this
.
world
.
addConstraint
(
constraint
,
true
);
this
.
constraint
=
constraint
;
helper
.
freeTransform
(
form
);
helper
.
freeTransform
(
formA
);
helper
.
freeTransform
(
formB
);
helper
.
freeTransform
(
formInverseA
);
helper
.
freeTransform
(
formInverseB
);
helper
.
freeTransform
(
formA2
);
helper
.
freeTransform
(
formB2
);
helper
.
freeVector3
(
lll
);
helper
.
freeVector3
(
lul
);
helper
.
freeVector3
(
all
);
helper
.
freeVector3
(
aul
);
}
};
examples/js/libs/ammo.js
0 → 100644
浏览文件 @
a5642d0f
此差异已折叠。
点击以展开。
examples/js/loaders/MMDLoader.js
浏览文件 @
a5642d0f
...
...
@@ -2,7 +2,7 @@
* @author takahiro / https://github.com/takahirox
*
* Dependencies
* charset-encoder-js https://github.com/takahirox/charset-encoder-js
*
-
charset-encoder-js https://github.com/takahirox/charset-encoder-js
*
*
* This loader loads and parses PMD/PMX and VMD binary files
...
...
@@ -24,27 +24,26 @@
* http://gulshan-i-raz.geo.jp/labs/2012/10/17/pmx-format1/
*
* Model data requirements
* convert .tga files to .png files if exist. (Should I use THREE.TGALoader?)
* resize the texture image files to power_of_2*power_of_2
*
-
convert .tga files to .png files if exist. (Should I use THREE.TGALoader?)
*
-
resize the texture image files to power_of_2*power_of_2
*
*
* TODO
* separate model/vmd loaders.
* multi vmd files support.
* edge(outline) support.
* culling support.
* toon(cel) shadering support.
* add-sphere-mapping support.
* physics support.
* camera motion in vmd support.
* light motion in vmd support.
* music support.
* make own shader for the performance and functionarity.
* SDEF support.
* uv/material/bone morphing support.
* tga file loading support.
* supply skinning support.
* shadow support.
* - separate model/vmd loaders.
* - multi vmd files support.
* - edge(outline) support.
* - culling support.
* - toon(cel) shadering support.
* - add-sphere-mapping support.
* - camera motion in vmd support.
* - light motion in vmd support.
* - music support.
* - make own shader for the performance and functionarity.
* - SDEF support.
* - uv/material/bone morphing support.
* - tga file loading support.
* - supply skinning support.
* - shadow support.
*/
THREE
.
MMDLoader
=
function
(
showStatus
,
manager
)
{
...
...
@@ -267,10 +266,10 @@ THREE.MMDLoader.prototype.parsePmd = function ( buffer ) {
// So using charcode strings as workaround and keep original strings in .originalName.
p
.
originalName
=
dv
.
getSjisStringsAsUnicode
(
20
);
p
.
name
=
dv
.
toCharcodeStrings
(
p
.
originalName
);
p
.
parentIndex
=
dv
.
get
Ui
nt16
();
p
.
tailIndex
=
dv
.
get
Ui
nt16
();
p
.
parentIndex
=
dv
.
get
I
nt16
();
p
.
tailIndex
=
dv
.
get
I
nt16
();
p
.
type
=
dv
.
getUint8
();
p
.
ikIndex
=
dv
.
get
Ui
nt16
();
p
.
ikIndex
=
dv
.
get
I
nt16
();
p
.
position
=
dv
.
getFloat32Array
(
3
);
return
p
;
...
...
@@ -363,6 +362,265 @@ THREE.MMDLoader.prototype.parsePmd = function ( buffer ) {
};
var
parseMorphFrames
=
function
()
{
var
parseMorphFrame
=
function
()
{
var
p
=
{};
p
.
index
=
dv
.
getUint16
();
return
p
;
};
var
metadata
=
pmd
.
metadata
;
metadata
.
morphFrameCount
=
dv
.
getUint8
();
pmd
.
morphFrames
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
morphFrameCount
;
i
++
)
{
pmd
.
morphFrames
.
push
(
parseMorphFrame
()
);
}
};
var
parseBoneFrameNames
=
function
()
{
var
parseBoneFrameName
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getSjisStringsAsUnicode
(
50
);
return
p
;
};
var
metadata
=
pmd
.
metadata
;
metadata
.
boneFrameNameCount
=
dv
.
getUint8
();
pmd
.
boneFrameNames
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
boneFrameNameCount
;
i
++
)
{
pmd
.
boneFrameNames
.
push
(
parseBoneFrameName
()
);
}
};
var
parseBoneFrames
=
function
()
{
var
parseBoneFrame
=
function
()
{
var
p
=
{};
p
.
boneIndex
=
dv
.
getInt16
();
p
.
frameIndex
=
dv
.
getUint8
();
return
p
;
};
var
metadata
=
pmd
.
metadata
;
metadata
.
boneFrameCount
=
dv
.
getUint32
();
pmd
.
boneFrames
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
boneFrameCount
;
i
++
)
{
pmd
.
boneFrames
.
push
(
parseBoneFrame
()
);
}
};
var
parseEnglishHeader
=
function
()
{
var
metadata
=
pmd
.
metadata
;
metadata
.
englishCompatibility
=
dv
.
getUint8
();
if
(
metadata
.
englishCompatibility
>
0
)
{
metadata
.
englishModelName
=
dv
.
getSjisStringsAsUnicode
(
20
);
metadata
.
englishComment
=
dv
.
getSjisStringsAsUnicode
(
256
);
}
};
var
parseEnglishBoneNames
=
function
()
{
var
parseEnglishBoneName
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getSjisStringsAsUnicode
(
20
);
return
p
;
};
var
metadata
=
pmd
.
metadata
;
if
(
metadata
.
englishCompatibility
===
0
)
{
return
;
}
pmd
.
englishBoneNames
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
boneCount
;
i
++
)
{
pmd
.
englishBoneNames
.
push
(
parseEnglishBoneName
()
);
}
};
var
parseEnglishMorphNames
=
function
()
{
var
parseEnglishMorphName
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getSjisStringsAsUnicode
(
20
);
return
p
;
};
var
metadata
=
pmd
.
metadata
;
if
(
metadata
.
englishCompatibility
===
0
)
{
return
;
}
pmd
.
englishMorphNames
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
morphCount
-
1
;
i
++
)
{
pmd
.
englishMorphNames
.
push
(
parseEnglishMorphName
()
);
}
};
var
parseEnglishBoneFrameNames
=
function
()
{
var
parseEnglishBoneFrameName
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getSjisStringsAsUnicode
(
50
);
return
p
;
};
var
metadata
=
pmd
.
metadata
;
if
(
metadata
.
englishCompatibility
===
0
)
{
return
;
}
pmd
.
englishBoneFrameNames
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
boneFrameNameCount
;
i
++
)
{
pmd
.
englishBoneFrameNames
.
push
(
parseEnglishBoneFrameName
()
);
}
};
var
parseToonTextures
=
function
()
{
var
parseToonTexture
=
function
()
{
var
p
=
{};
p
.
fileName
=
dv
.
getSjisStringsAsUnicode
(
100
);
return
p
;
};
pmd
.
toonTextures
=
[];
for
(
var
i
=
0
;
i
<
10
;
i
++
)
{
pmd
.
toonTextures
.
push
(
parseToonTexture
()
);
}
};
var
parseRigidBodies
=
function
()
{
var
parseRigidBody
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getSjisStringsAsUnicode
(
20
);
p
.
boneIndex
=
dv
.
getInt16
();
p
.
groupIndex
=
dv
.
getUint8
();
p
.
groupTarget
=
dv
.
getUint16
();
p
.
shapeType
=
dv
.
getUint8
();
p
.
width
=
dv
.
getFloat32
();
p
.
height
=
dv
.
getFloat32
();
p
.
depth
=
dv
.
getFloat32
();
p
.
position
=
dv
.
getFloat32Array
(
3
);
p
.
rotation
=
dv
.
getFloat32Array
(
3
);
p
.
weight
=
dv
.
getFloat32
();
p
.
positionDamping
=
dv
.
getFloat32
();
p
.
rotationDamping
=
dv
.
getFloat32
();
p
.
restriction
=
dv
.
getFloat32
();
p
.
friction
=
dv
.
getFloat32
();
p
.
type
=
dv
.
getUint8
();
return
p
;
};
var
metadata
=
pmd
.
metadata
;
metadata
.
rigidBodyCount
=
dv
.
getUint32
();
pmd
.
rigidBodies
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
rigidBodyCount
;
i
++
)
{
pmd
.
rigidBodies
.
push
(
parseRigidBody
()
);
}
};
var
parseConstraints
=
function
()
{
var
parseConstraint
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getSjisStringsAsUnicode
(
20
);
p
.
rigidBodyIndex1
=
dv
.
getUint32
();
p
.
rigidBodyIndex2
=
dv
.
getUint32
();
p
.
position
=
dv
.
getFloat32Array
(
3
);
p
.
rotation
=
dv
.
getFloat32Array
(
3
);
p
.
translationLimitation1
=
dv
.
getFloat32Array
(
3
);
p
.
translationLimitation2
=
dv
.
getFloat32Array
(
3
);
p
.
rotationLimitation1
=
dv
.
getFloat32Array
(
3
);
p
.
rotationLimitation2
=
dv
.
getFloat32Array
(
3
);
p
.
springPosition
=
dv
.
getFloat32Array
(
3
);
p
.
springRotation
=
dv
.
getFloat32Array
(
3
);
return
p
;
};
var
metadata
=
pmd
.
metadata
;
metadata
.
constraintCount
=
dv
.
getUint32
();
pmd
.
constraints
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
constraintCount
;
i
++
)
{
pmd
.
constraints
.
push
(
parseConstraint
()
);
}
};
parseHeader
();
parseVertices
();
parseFaces
();
...
...
@@ -370,6 +628,18 @@ THREE.MMDLoader.prototype.parsePmd = function ( buffer ) {
parseBones
();
parseIks
();
parseMorphs
();
parseMorphFrames
();
parseBoneFrameNames
();
parseBoneFrames
();
parseEnglishHeader
();
parseEnglishBoneNames
();
parseEnglishMorphNames
();
parseEnglishBoneFrameNames
();
parseToonTextures
();
parseRigidBodies
();
parseConstraints
();
// console.log( pmd ); // for console debug
return
pmd
;
...
...
@@ -412,7 +682,7 @@ THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
metadata
.
materialIndexSize
=
dv
.
getUint8
();
metadata
.
boneIndexSize
=
dv
.
getUint8
();
metadata
.
morphIndexSize
=
dv
.
getUint8
();
metadata
.
rigid
b
odyIndexSize
=
dv
.
getUint8
();
metadata
.
rigid
B
odyIndexSize
=
dv
.
getUint8
();
metadata
.
modelName
=
dv
.
getTextBuffer
();
metadata
.
englishModelName
=
dv
.
getTextBuffer
();
metadata
.
comment
=
dv
.
getTextBuffer
();
...
...
@@ -771,6 +1041,117 @@ THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
};
var
parseFrames
=
function
()
{
var
parseFrame
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getTextBuffer
();
p
.
englishName
=
dv
.
getTextBuffer
();
p
.
type
=
dv
.
getUint8
();
p
.
elementCount
=
dv
.
getUint32
();
p
.
elements
=
[];
for
(
var
i
=
0
;
i
<
p
.
elementCount
;
i
++
)
{
var
e
=
{};
e
.
target
=
dv
.
getUint8
();
e
.
index
=
(
e
.
target
===
0
)
?
dv
.
getNumber
(
pmx
.
metadata
.
boneIndexSize
)
:
dv
.
getNumber
(
pmx
.
metadata
.
morphIndexSize
);
p
.
elements
.
push
(
e
);
}
return
p
;
};
var
metadata
=
pmx
.
metadata
;
metadata
.
frameCount
=
dv
.
getUint32
();
pmx
.
frames
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
frameCount
;
i
++
)
{
pmx
.
frames
.
push
(
parseFrame
()
);
}
};
var
parseRigidBodies
=
function
()
{
var
parseRigidBody
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getTextBuffer
();
p
.
englishName
=
dv
.
getTextBuffer
();
p
.
boneIndex
=
dv
.
getNumber
(
pmx
.
metadata
.
boneIndexSize
);
p
.
groupIndex
=
dv
.
getUint8
();
p
.
groupTarget
=
dv
.
getUint16
();
p
.
shapeType
=
dv
.
getUint8
();
p
.
width
=
dv
.
getFloat32
();
p
.
height
=
dv
.
getFloat32
();
p
.
depth
=
dv
.
getFloat32
();
p
.
position
=
dv
.
getFloat32Array
(
3
);
p
.
rotation
=
dv
.
getFloat32Array
(
3
);
p
.
weight
=
dv
.
getFloat32
();
p
.
positionDamping
=
dv
.
getFloat32
();
p
.
rotationDamping
=
dv
.
getFloat32
();
p
.
restriction
=
dv
.
getFloat32
();
p
.
friction
=
dv
.
getFloat32
();
p
.
type
=
dv
.
getUint8
();
return
p
;
};
var
metadata
=
pmx
.
metadata
;
metadata
.
rigidBodyCount
=
dv
.
getUint32
();
pmx
.
rigidBodies
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
rigidBodyCount
;
i
++
)
{
pmx
.
rigidBodies
.
push
(
parseRigidBody
()
);
}
};
var
parseConstraints
=
function
()
{
var
parseConstraint
=
function
()
{
var
p
=
{};
p
.
name
=
dv
.
getTextBuffer
();
p
.
englishName
=
dv
.
getTextBuffer
();
p
.
type
=
dv
.
getUint8
();
p
.
rigidBodyIndex1
=
dv
.
getNumber
(
pmx
.
metadata
.
rigidBodyIndexSize
);
p
.
rigidBodyIndex2
=
dv
.
getNumber
(
pmx
.
metadata
.
rigidBodyIndexSize
);
p
.
position
=
dv
.
getFloat32Array
(
3
);
p
.
rotation
=
dv
.
getFloat32Array
(
3
);
p
.
translationLimitation1
=
dv
.
getFloat32Array
(
3
);
p
.
translationLimitation2
=
dv
.
getFloat32Array
(
3
);
p
.
rotationLimitation1
=
dv
.
getFloat32Array
(
3
);
p
.
rotationLimitation2
=
dv
.
getFloat32Array
(
3
);
p
.
springPosition
=
dv
.
getFloat32Array
(
3
);
p
.
springRotation
=
dv
.
getFloat32Array
(
3
);
return
p
;
};
var
metadata
=
pmx
.
metadata
;
metadata
.
constraintCount
=
dv
.
getUint32
();
pmx
.
constraints
=
[];
for
(
var
i
=
0
;
i
<
metadata
.
constraintCount
;
i
++
)
{
pmx
.
constraints
.
push
(
parseConstraint
()
);
}
};
parseHeader
();
parseVertices
();
parseFaces
();
...
...
@@ -778,6 +1159,9 @@ THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
parseMaterials
();
parseBones
();
parseMorphs
();
parseFrames
();
parseRigidBodies
();
parseConstraints
();
// console.log( pmx ); // for console debug
...
...
@@ -892,6 +1276,13 @@ THREE.MMDLoader.prototype.createMesh = function ( model, vmd, texturePath, onPro
};
var
convertEuler
=
function
(
r
)
{
r
[
0
]
=
-
r
[
0
];
r
[
1
]
=
-
r
[
1
];
};
var
convertIndexOrder
=
function
(
p
)
{
var
tmp
=
p
[
2
];
...
...
@@ -900,6 +1291,25 @@ THREE.MMDLoader.prototype.createMesh = function ( model, vmd, texturePath, onPro
};
var
convertVectorRange
=
function
(
v1
,
v2
)
{
var
tmp
=
-
v2
[
2
];
v2
[
2
]
=
-
v1
[
2
];
v1
[
2
]
=
tmp
;
};
var
convertEulerRange
=
function
(
r1
,
r2
)
{
var
tmp1
=
-
r2
[
0
];
var
tmp2
=
-
r2
[
1
];
r2
[
0
]
=
-
r1
[
0
];
r2
[
1
]
=
-
r1
[
1
];
r1
[
0
]
=
tmp1
;
r1
[
1
]
=
tmp2
;
};
for
(
var
i
=
0
;
i
<
model
.
metadata
.
vertexCount
;
i
++
)
{
convertVector
(
model
.
vertices
[
i
].
position
);
...
...
@@ -946,6 +1356,22 @@ THREE.MMDLoader.prototype.createMesh = function ( model, vmd, texturePath, onPro
}
for
(
var
i
=
0
;
i
<
model
.
metadata
.
rigidBodyCount
;
i
++
)
{
convertVector
(
model
.
rigidBodies
[
i
].
position
);
convertEuler
(
model
.
rigidBodies
[
i
].
rotation
);
}
for
(
var
i
=
0
;
i
<
model
.
metadata
.
constraintCount
;
i
++
)
{
convertVector
(
model
.
constraints
[
i
].
position
);
convertEuler
(
model
.
constraints
[
i
].
rotation
);
convertVectorRange
(
model
.
constraints
[
i
].
translationLimitation1
,
model
.
constraints
[
i
].
translationLimitation2
);
convertEulerRange
(
model
.
constraints
[
i
].
rotationLimitation1
,
model
.
constraints
[
i
].
rotationLimitation2
);
}
if
(
vmd
===
null
)
{
return
;
...
...
@@ -1034,13 +1460,6 @@ THREE.MMDLoader.prototype.createMesh = function ( model, vmd, texturePath, onPro
var
b
=
model
.
bones
[
i
];
bone
.
parent
=
b
.
parentIndex
;
if
(
model
.
metadata
.
format
===
'
pmd
'
)
{
bone
.
parent
=
(
b
.
parentIndex
===
0xFFFF
)
?
-
1
:
b
.
parentIndex
;
}
bone
.
name
=
b
.
name
;
bone
.
pos
=
[
b
.
position
[
0
],
b
.
position
[
1
],
b
.
position
[
2
]
];
bone
.
rotq
=
[
0
,
0
,
0
,
1
];
...
...
@@ -1403,6 +1822,88 @@ THREE.MMDLoader.prototype.createMesh = function ( model, vmd, texturePath, onPro
};
var
initPhysics
=
function
()
{
var
rigidBodies
=
[];
var
constraints
=
[];
for
(
var
i
=
0
;
i
<
model
.
metadata
.
rigidBodyCount
;
i
++
)
{
var
b
=
model
.
rigidBodies
[
i
];
var
keys
=
Object
.
keys
(
b
);
var
p
=
{};
for
(
var
j
=
0
;
j
<
keys
.
length
;
j
++
)
{
var
key
=
keys
[
j
];
p
[
key
]
=
b
[
key
];
}
/*
* RigidBody position parameter in PMX seems global position
* while the one in PMD seems offset from corresponding bone.
* So unify being offset.
*/
if
(
model
.
metadata
.
format
===
'
pmx
'
)
{
if
(
p
.
boneIndex
!==
-
1
)
{
var
bone
=
model
.
bones
[
p
.
boneIndex
];
p
.
position
[
0
]
-=
bone
.
position
[
0
];
p
.
position
[
1
]
-=
bone
.
position
[
1
];
p
.
position
[
2
]
-=
bone
.
position
[
2
];
}
}
rigidBodies
.
push
(
p
);
}
for
(
var
i
=
0
;
i
<
model
.
metadata
.
constraintCount
;
i
++
)
{
var
c
=
model
.
constraints
[
i
];
var
keys
=
Object
.
keys
(
c
);
var
p
=
{};
for
(
var
j
=
0
;
j
<
keys
.
length
;
j
++
)
{
var
key
=
keys
[
j
];
p
[
key
]
=
c
[
key
];
}
var
bodyA
=
rigidBodies
[
p
.
rigidBodyIndex1
];
var
bodyB
=
rigidBodies
[
p
.
rigidBodyIndex2
];
/*
* Refer http://www20.atpages.jp/katwat/wp/?p=4135
* for what this is for
*/
if
(
bodyA
.
type
!==
0
&&
bodyB
.
type
===
2
)
{
if
(
bodyA
.
boneIndex
!==
-
1
&&
bodyB
.
boneIndex
!==
-
1
&&
model
.
bones
[
bodyB
.
boneIndex
].
parentIndex
===
bodyA
.
boneIndex
)
{
bodyB
.
type
=
1
;
}
}
constraints
.
push
(
p
);
}
geometry
.
rigidBodies
=
rigidBodies
;
geometry
.
constraints
=
constraints
;
};
var
initMotionAnimations
=
function
()
{
var
orderedMotions
=
[];
...
...
@@ -1680,6 +2181,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, vmd, texturePath, onPro
initIKs
();
initMorphs
();
initMaterials
();
initPhysics
();
if
(
vmd
!==
null
)
{
...
...
examples/webgl_loader_mmd.html
浏览文件 @
a5642d0f
...
...
@@ -36,8 +36,10 @@
<script
src=
"../build/three.min.js"
></script>
<script
src=
"js/libs/charsetencoder.min.js"
></script>
<script
src=
"js/libs/ammo.js"
></script>
<script
src=
"js/loaders/MMDLoader.js"
></script>
<script
src=
"js/animation/CCDIKSolver.js"
></script>
<script
src=
"js/animation/MMDPhysics.js"
></script>
<script
src=
"js/Detector.js"
></script>
<script
src=
"js/libs/stats.min.js"
></script>
...
...
@@ -47,10 +49,15 @@
var
container
,
stats
;
var
mesh
,
camera
,
mixer
,
scene
,
renderer
;
var
ikSolver
;
var
mouseX
=
0
,
mouseY
=
0
;
/*
* Caution: Physics calculation is pretty heavy.
* It may be not acceptable for most mobile devices yet.
*/
var
physics
;
var
ikSolver
;
var
mouseX
=
0
,
mouseY
=
0
;
var
windowHalfX
=
window
.
innerWidth
/
2
;
var
windowHalfY
=
window
.
innerHeight
/
2
;
...
...
@@ -60,7 +67,6 @@
init
();
animate
();
function
init
()
{
container
=
document
.
createElement
(
'
div
'
);
...
...
@@ -104,6 +110,12 @@
mixer
.
clipAction
(
mesh
.
geometry
.
morphAnimations
[
0
]
).
play
();
ikSolver
=
new
THREE
.
CCDIKSolver
(
mesh
);
physics
=
new
THREE
.
MMDPhysics
(
mesh
);
// see below for what this's for
initBackupBones
(
mesh
);
physics
.
warmup
(
10
);
},
onProgress
,
onError
);
...
...
@@ -160,23 +172,76 @@
if
(
mesh
)
{
mixer
.
update
(
clock
.
getDelta
()
);
/* Note: ikSolver.resetLinks() is workaround for r74dev.
* THREE.PropertyMixer.apply() seems to have buffer cache
* when mixer.update() is called.
* ikSolver.update() change bone position/quaternion
* without mixer.update() then buffer cache will be inconsistent.
* ikSolver.resetLinks() explicitly resets IK link bones quaternion and
* tries to avoid issues caused by this inconsistent.
*/
ikSolver
.
resetLinks
();
var
delta
=
clock
.
getDelta
();
mixer
.
update
(
delta
);
// see below for what this's for
backupBones
(
mesh
);
ikSolver
.
update
();
physics
.
update
(
delta
);
}
renderer
.
render
(
scene
,
camera
);
if
(
mesh
)
{
// see below for what this's for
restoreBones
(
mesh
);
}
}
/*
* Note: These following three functions are workaround for r74dev.
* THREE.PropertyMixer.apply() seems to save values into buffer cache
* when mixer.update() is called.
* ikSolver.update() and physics.update() change bone position/quaternion
* without mixer.update() then buffer cache will be inconsistent.
* So trying to avoid buffer cache inconsistency by doing
* backup bones position/quaternion right after mixer.update() call
* and then restore them after rendering.
*/
function
initBackupBones
(
mesh
)
{
mesh
.
skeleton
.
backupBones
=
[];
for
(
var
i
=
0
;
i
<
mesh
.
skeleton
.
bones
.
length
;
i
++
)
{
mesh
.
skeleton
.
backupBones
.
push
(
mesh
.
skeleton
.
bones
[
i
].
clone
()
);
}
}
function
backupBones
(
mesh
)
{
for
(
var
i
=
0
;
i
<
mesh
.
skeleton
.
bones
.
length
;
i
++
)
{
var
b
=
mesh
.
skeleton
.
backupBones
[
i
];
var
b2
=
mesh
.
skeleton
.
bones
[
i
];
b
.
position
.
copy
(
b2
.
position
);
b
.
quaternion
.
copy
(
b2
.
quaternion
);
}
}
function
restoreBones
(
mesh
)
{
for
(
var
i
=
0
;
i
<
mesh
.
skeleton
.
bones
.
length
;
i
++
)
{
var
b
=
mesh
.
skeleton
.
bones
[
i
];
var
b2
=
mesh
.
skeleton
.
backupBones
[
i
];
b
.
position
.
copy
(
b2
.
position
);
b
.
quaternion
.
copy
(
b2
.
quaternion
);
}
}
</script>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录