Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
3452a4e3
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,体验更适合开发者的 AI 搜索 >>
未验证
提交
3452a4e3
编写于
4月 09, 2021
作者:
M
Michael Herzog
提交者:
GitHub
4月 09, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Examples: Convert misc to ES6. (#21618)
上级
8f6cc7df
变更
17
展开全部
隐藏空白更改
内联
并排
Showing
17 changed file
with
2093 addition
and
2034 deletion
+2093
-2034
examples/js/misc/ConvexObjectBreaker.js
examples/js/misc/ConvexObjectBreaker.js
+158
-158
examples/js/misc/GPUComputationRenderer.js
examples/js/misc/GPUComputationRenderer.js
+178
-174
examples/js/misc/Gyroscope.js
examples/js/misc/Gyroscope.js
+22
-19
examples/js/misc/MD2Character.js
examples/js/misc/MD2Character.js
+104
-99
examples/js/misc/MD2CharacterComplex.js
examples/js/misc/MD2CharacterComplex.js
+126
-116
examples/js/misc/MorphAnimMesh.js
examples/js/misc/MorphAnimMesh.js
+36
-35
examples/js/misc/MorphBlendMesh.js
examples/js/misc/MorphBlendMesh.js
+83
-70
examples/js/misc/RollerCoaster.js
examples/js/misc/RollerCoaster.js
+354
-344
examples/jsm/misc/ConvexObjectBreaker.js
examples/jsm/misc/ConvexObjectBreaker.js
+135
-142
examples/jsm/misc/GPUComputationRenderer.js
examples/jsm/misc/GPUComputationRenderer.js
+186
-180
examples/jsm/misc/Gyroscope.js
examples/jsm/misc/Gyroscope.js
+17
-20
examples/jsm/misc/MD2Character.js
examples/jsm/misc/MD2Character.js
+99
-95
examples/jsm/misc/MD2CharacterComplex.js
examples/jsm/misc/MD2CharacterComplex.js
+130
-127
examples/jsm/misc/MorphAnimMesh.js
examples/jsm/misc/MorphAnimMesh.js
+36
-35
examples/jsm/misc/MorphBlendMesh.js
examples/jsm/misc/MorphBlendMesh.js
+71
-71
examples/jsm/misc/RollerCoaster.js
examples/jsm/misc/RollerCoaster.js
+358
-348
examples/webgl_loader_md2_control.html
examples/webgl_loader_md2_control.html
+0
-1
未找到文件。
examples/js/misc/ConvexObjectBreaker.js
浏览文件 @
3452a4e3
...
...
@@ -29,40 +29,42 @@
*
*/
var
ConvexObjectBreaker
=
function
(
minSizeForBreak
,
smallDelta
)
{
this
.
minSizeForBreak
=
minSizeForBreak
||
1.4
;
this
.
smallDelta
=
smallDelta
||
0.0001
;
this
.
tempLine1
=
new
THREE
.
Line3
();
this
.
tempPlane1
=
new
THREE
.
Plane
();
this
.
tempPlane2
=
new
THREE
.
Plane
();
this
.
tempPlane_Cut
=
new
THREE
.
Plane
();
this
.
tempCM1
=
new
THREE
.
Vector3
();
this
.
tempCM2
=
new
THREE
.
Vector3
();
this
.
tempVector3
=
new
THREE
.
Vector3
();
this
.
tempVector3_2
=
new
THREE
.
Vector3
();
this
.
tempVector3_3
=
new
THREE
.
Vector3
();
this
.
tempVector3_P0
=
new
THREE
.
Vector3
();
this
.
tempVector3_P1
=
new
THREE
.
Vector3
();
this
.
tempVector3_P2
=
new
THREE
.
Vector3
();
this
.
tempVector3_N0
=
new
THREE
.
Vector3
();
this
.
tempVector3_N1
=
new
THREE
.
Vector3
();
this
.
tempVector3_AB
=
new
THREE
.
Vector3
();
this
.
tempVector3_CB
=
new
THREE
.
Vector3
();
this
.
tempResultObjects
=
{
object1
:
null
,
object2
:
null
};
this
.
segments
=
[];
var
n
=
30
*
30
;
for
(
var
i
=
0
;
i
<
n
;
i
++
)
this
.
segments
[
i
]
=
false
;
};
ConvexObjectBreaker
.
prototype
=
{
constructor
:
ConvexObjectBreaker
,
prepareBreakableObject
:
function
(
object
,
mass
,
velocity
,
angularVelocity
,
breakable
)
{
const
_v1
=
new
THREE
.
Vector3
();
class
ConvexObjectBreaker
{
constructor
(
minSizeForBreak
=
1.4
,
smallDelta
=
0.0001
)
{
this
.
minSizeForBreak
=
minSizeForBreak
;
this
.
smallDelta
=
smallDelta
;
this
.
tempLine1
=
new
THREE
.
Line3
();
this
.
tempPlane1
=
new
THREE
.
Plane
();
this
.
tempPlane2
=
new
THREE
.
Plane
();
this
.
tempPlane_Cut
=
new
THREE
.
Plane
();
this
.
tempCM1
=
new
THREE
.
Vector3
();
this
.
tempCM2
=
new
THREE
.
Vector3
();
this
.
tempVector3
=
new
THREE
.
Vector3
();
this
.
tempVector3_2
=
new
THREE
.
Vector3
();
this
.
tempVector3_3
=
new
THREE
.
Vector3
();
this
.
tempVector3_P0
=
new
THREE
.
Vector3
();
this
.
tempVector3_P1
=
new
THREE
.
Vector3
();
this
.
tempVector3_P2
=
new
THREE
.
Vector3
();
this
.
tempVector3_N0
=
new
THREE
.
Vector3
();
this
.
tempVector3_N1
=
new
THREE
.
Vector3
();
this
.
tempVector3_AB
=
new
THREE
.
Vector3
();
this
.
tempVector3_CB
=
new
THREE
.
Vector3
();
this
.
tempResultObjects
=
{
object1
:
null
,
object2
:
null
};
this
.
segments
=
[];
const
n
=
30
*
30
;
for
(
let
i
=
0
;
i
<
n
;
i
++
)
this
.
segments
[
i
]
=
false
;
}
prepareBreakableObject
(
object
,
mass
,
velocity
,
angularVelocity
,
breakable
)
{
// object is a Object3d (normally a THREE.Mesh), must have a BufferGeometry, and it must be convex.
// Its material property is propagated to its children (sub-pieces)
...
...
@@ -73,29 +75,30 @@
}
var
userData
=
object
.
userData
;
const
userData
=
object
.
userData
;
userData
.
mass
=
mass
;
userData
.
velocity
=
velocity
.
clone
();
userData
.
angularVelocity
=
angularVelocity
.
clone
();
userData
.
breakable
=
breakable
;
},
}
/*
* @param {int} maxRadialIterations Iterations for radial cuts.
* @param {int} maxRandomIterations Max random iterations for not-radial cuts
*
* Returns the array of pieces
*/
subdivideByImpact
:
function
(
object
,
pointOfImpact
,
normal
,
maxRadialIterations
,
maxRandomIterations
)
{
var
debris
=
[];
var
tempPlane1
=
this
.
tempPlane1
;
var
tempPlane2
=
this
.
tempPlane2
;
subdivideByImpact
(
object
,
pointOfImpact
,
normal
,
maxRadialIterations
,
maxRandomIterations
)
{
const
debris
=
[];
const
tempPlane1
=
this
.
tempPlane1
;
const
tempPlane2
=
this
.
tempPlane2
;
this
.
tempVector3
.
addVectors
(
pointOfImpact
,
normal
);
tempPlane1
.
setFromCoplanarPoints
(
pointOfImpact
,
object
.
position
,
this
.
tempVector3
);
var
maxTotalIterations
=
maxRandomIterations
+
maxRadialIterations
;
var
scope
=
this
;
const
maxTotalIterations
=
maxRandomIterations
+
maxRadialIterations
;
const
scope
=
this
;
function
subdivideRadial
(
subObject
,
startAngle
,
endAngle
,
numIterations
)
{
...
...
@@ -106,7 +109,7 @@
}
var
angle
=
Math
.
PI
;
let
angle
=
Math
.
PI
;
if
(
numIterations
===
0
)
{
...
...
@@ -136,8 +139,8 @@
scope
.
cutByPlane
(
subObject
,
tempPlane2
,
scope
.
tempResultObjects
);
var
obj1
=
scope
.
tempResultObjects
.
object1
;
var
obj2
=
scope
.
tempResultObjects
.
object2
;
const
obj1
=
scope
.
tempResultObjects
.
object1
;
const
obj2
=
scope
.
tempResultObjects
.
object2
;
if
(
obj1
)
{
...
...
@@ -156,19 +159,20 @@
subdivideRadial
(
object
,
0
,
2
*
Math
.
PI
,
0
);
return
debris
;
},
cutByPlane
:
function
(
object
,
plane
,
output
)
{
}
cutByPlane
(
object
,
plane
,
output
)
{
// Returns breakable objects in output.object1 and output.object2 members, the resulting 2 pieces of the cut.
// object2 can be null if the plane doesn't cut the object.
// object1 can be null only in case of internal error
// Returned value is number of pieces, 0 for error.
var
geometry
=
object
.
geometry
;
var
coords
=
geometry
.
attributes
.
position
.
array
;
var
normals
=
geometry
.
attributes
.
normal
.
array
;
var
numPoints
=
coords
.
length
/
3
;
var
numFaces
=
numPoints
/
3
;
var
indices
=
geometry
.
getIndex
();
const
geometry
=
object
.
geometry
;
const
coords
=
geometry
.
attributes
.
position
.
array
;
const
normals
=
geometry
.
attributes
.
normal
.
array
;
const
numPoints
=
coords
.
length
/
3
;
let
numFaces
=
numPoints
/
3
;
let
indices
=
geometry
.
getIndex
();
if
(
indices
)
{
...
...
@@ -180,40 +184,40 @@
function
getVertexIndex
(
faceIdx
,
vert
)
{
// vert = 0, 1 or 2.
var
idx
=
faceIdx
*
3
+
vert
;
const
idx
=
faceIdx
*
3
+
vert
;
return
indices
?
indices
[
idx
]
:
idx
;
}
var
points1
=
[];
var
points2
=
[];
var
delta
=
this
.
smallDelta
;
// Reset segments mark
const
points1
=
[];
const
points2
=
[];
const
delta
=
this
.
smallDelta
;
// Reset segments mark
var
numPointPairs
=
numPoints
*
numPoints
;
const
numPointPairs
=
numPoints
*
numPoints
;
for
(
var
i
=
0
;
i
<
numPointPairs
;
i
++
)
this
.
segments
[
i
]
=
false
;
for
(
let
i
=
0
;
i
<
numPointPairs
;
i
++
)
this
.
segments
[
i
]
=
false
;
var
p0
=
this
.
tempVector3_P0
;
var
p1
=
this
.
tempVector3_P1
;
var
n0
=
this
.
tempVector3_N0
;
var
n1
=
this
.
tempVector3_N1
;
// Iterate through the faces to mark edges shared by coplanar faces
const
p0
=
this
.
tempVector3_P0
;
const
p1
=
this
.
tempVector3_P1
;
const
n0
=
this
.
tempVector3_N0
;
const
n1
=
this
.
tempVector3_N1
;
// Iterate through the faces to mark edges shared by coplanar faces
for
(
var
i
=
0
;
i
<
numFaces
-
1
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numFaces
-
1
;
i
++
)
{
var
a1
=
getVertexIndex
(
i
,
0
);
var
b1
=
getVertexIndex
(
i
,
1
);
var
c1
=
getVertexIndex
(
i
,
2
);
// Assuming all 3 vertices have the same normal
const
a1
=
getVertexIndex
(
i
,
0
);
const
b1
=
getVertexIndex
(
i
,
1
);
const
c1
=
getVertexIndex
(
i
,
2
);
// Assuming all 3 vertices have the same normal
n0
.
set
(
normals
[
a1
],
normals
[
a1
]
+
1
,
normals
[
a1
]
+
2
);
for
(
var
j
=
i
+
1
;
j
<
numFaces
;
j
++
)
{
for
(
let
j
=
i
+
1
;
j
<
numFaces
;
j
++
)
{
var
a2
=
getVertexIndex
(
j
,
0
);
var
b2
=
getVertexIndex
(
j
,
1
);
var
c2
=
getVertexIndex
(
j
,
2
);
// Assuming all 3 vertices have the same normal
const
a2
=
getVertexIndex
(
j
,
0
);
const
b2
=
getVertexIndex
(
j
,
1
);
const
c2
=
getVertexIndex
(
j
,
2
);
// Assuming all 3 vertices have the same normal
n1
.
set
(
normals
[
a2
],
normals
[
a2
]
+
1
,
normals
[
a2
]
+
2
);
var
coplanar
=
1
-
n0
.
dot
(
n1
)
<
delta
;
const
coplanar
=
1
-
n0
.
dot
(
n1
)
<
delta
;
if
(
coplanar
)
{
...
...
@@ -245,21 +249,21 @@
}
// Transform the plane to object local space
var
localPlane
=
this
.
tempPlane_Cut
;
const
localPlane
=
this
.
tempPlane_Cut
;
object
.
updateMatrix
();
ConvexObjectBreaker
.
transformPlaneToLocalSpace
(
plane
,
object
.
matrix
,
localPlane
);
// Iterate through the faces adding points to both pieces
for
(
var
i
=
0
;
i
<
numFaces
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numFaces
;
i
++
)
{
var
va
=
getVertexIndex
(
i
,
0
);
var
vb
=
getVertexIndex
(
i
,
1
);
var
vc
=
getVertexIndex
(
i
,
2
);
const
va
=
getVertexIndex
(
i
,
0
);
const
vb
=
getVertexIndex
(
i
,
1
);
const
vc
=
getVertexIndex
(
i
,
2
);
for
(
var
segment
=
0
;
segment
<
3
;
segment
++
)
{
for
(
let
segment
=
0
;
segment
<
3
;
segment
++
)
{
var
i0
=
segment
===
0
?
va
:
segment
===
1
?
vb
:
vc
;
var
i1
=
segment
===
0
?
vb
:
segment
===
1
?
vc
:
va
;
var
segmentState
=
this
.
segments
[
i0
*
numPoints
+
i1
];
const
i0
=
segment
===
0
?
va
:
segment
===
1
?
vb
:
vc
;
const
i1
=
segment
===
0
?
vb
:
segment
===
1
?
vc
:
va
;
const
segmentState
=
this
.
segments
[
i0
*
numPoints
+
i1
];
if
(
segmentState
)
continue
;
// The segment already has been processed in another face
// Mark segment as processed (also inverted segment)
...
...
@@ -268,8 +272,8 @@
p0
.
set
(
coords
[
3
*
i0
],
coords
[
3
*
i0
+
1
],
coords
[
3
*
i0
+
2
]
);
p1
.
set
(
coords
[
3
*
i1
],
coords
[
3
*
i1
+
1
],
coords
[
3
*
i1
+
2
]
);
// mark: 1 for negative side, 2 for positive side, 3 for coplanar point
var
mark0
=
0
;
var
d
=
localPlane
.
distanceToPoint
(
p0
);
let
mark0
=
0
;
let
d
=
localPlane
.
distanceToPoint
(
p0
);
if
(
d
>
delta
)
{
...
...
@@ -290,8 +294,8 @@
}
// mark: 1 for negative side, 2 for positive side, 3 for coplanar point
var
mark1
=
0
;
var
d
=
localPlane
.
distanceToPoint
(
p1
);
let
mark1
=
0
;
d
=
localPlane
.
distanceToPoint
(
p1
);
if
(
d
>
delta
)
{
...
...
@@ -316,7 +320,7 @@
// Intersection of segment with the plane
this
.
tempLine1
.
start
.
copy
(
p0
);
this
.
tempLine1
.
end
.
copy
(
p1
);
var
intersection
=
new
THREE
.
Vector3
();
let
intersection
=
new
THREE
.
Vector3
();
intersection
=
localPlane
.
intersectLine
(
this
.
tempLine1
,
intersection
);
if
(
intersection
===
null
)
{
...
...
@@ -339,21 +343,21 @@
}
// Calculate debris mass (very fast and imprecise):
var
newMass
=
object
.
userData
.
mass
*
0.5
;
// Calculate debris Center of Mass (again fast and imprecise)
const
newMass
=
object
.
userData
.
mass
*
0.5
;
// Calculate debris Center of Mass (again fast and imprecise)
this
.
tempCM1
.
set
(
0
,
0
,
0
);
var
radius1
=
0
;
var
numPoints1
=
points1
.
length
;
let
radius1
=
0
;
const
numPoints1
=
points1
.
length
;
if
(
numPoints1
>
0
)
{
for
(
var
i
=
0
;
i
<
numPoints1
;
i
++
)
this
.
tempCM1
.
add
(
points1
[
i
]
);
for
(
let
i
=
0
;
i
<
numPoints1
;
i
++
)
this
.
tempCM1
.
add
(
points1
[
i
]
);
this
.
tempCM1
.
divideScalar
(
numPoints1
);
for
(
var
i
=
0
;
i
<
numPoints1
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numPoints1
;
i
++
)
{
var
p
=
points1
[
i
];
const
p
=
points1
[
i
];
p
.
sub
(
this
.
tempCM1
);
radius1
=
Math
.
max
(
radius1
,
p
.
x
,
p
.
y
,
p
.
z
);
...
...
@@ -364,18 +368,18 @@
}
this
.
tempCM2
.
set
(
0
,
0
,
0
);
var
radius2
=
0
;
var
numPoints2
=
points2
.
length
;
let
radius2
=
0
;
const
numPoints2
=
points2
.
length
;
if
(
numPoints2
>
0
)
{
for
(
var
i
=
0
;
i
<
numPoints2
;
i
++
)
this
.
tempCM2
.
add
(
points2
[
i
]
);
for
(
let
i
=
0
;
i
<
numPoints2
;
i
++
)
this
.
tempCM2
.
add
(
points2
[
i
]
);
this
.
tempCM2
.
divideScalar
(
numPoints2
);
for
(
var
i
=
0
;
i
<
numPoints2
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numPoints2
;
i
++
)
{
var
p
=
points2
[
i
];
const
p
=
points2
[
i
];
p
.
sub
(
this
.
tempCM2
);
radius2
=
Math
.
max
(
radius2
,
p
.
x
,
p
.
y
,
p
.
z
);
...
...
@@ -385,9 +389,9 @@
}
var
object1
=
null
;
var
object2
=
null
;
var
numObjects
=
0
;
let
object1
=
null
;
let
object2
=
null
;
let
numObjects
=
0
;
if
(
numPoints1
>
4
)
{
...
...
@@ -414,71 +418,67 @@
return
numObjects
;
}
};
ConvexObjectBreaker
.
transformFreeVector
=
function
(
v
,
m
)
{
// input:
// vector interpreted as a free vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
var
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
var
e
=
m
.
elements
;
v
.
x
=
e
[
0
]
*
x
+
e
[
4
]
*
y
+
e
[
8
]
*
z
;
v
.
y
=
e
[
1
]
*
x
+
e
[
5
]
*
y
+
e
[
9
]
*
z
;
v
.
z
=
e
[
2
]
*
x
+
e
[
6
]
*
y
+
e
[
10
]
*
z
;
return
v
;
};
ConvexObjectBreaker
.
transformFreeVectorInverse
=
function
(
v
,
m
)
{
// input:
// vector interpreted as a free vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
var
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
var
e
=
m
.
elements
;
v
.
x
=
e
[
0
]
*
x
+
e
[
1
]
*
y
+
e
[
2
]
*
z
;
v
.
y
=
e
[
4
]
*
x
+
e
[
5
]
*
y
+
e
[
6
]
*
z
;
v
.
z
=
e
[
8
]
*
x
+
e
[
9
]
*
y
+
e
[
10
]
*
z
;
return
v
;
};
ConvexObjectBreaker
.
transformTiedVectorInverse
=
function
(
v
,
m
)
{
// input:
// vector interpreted as a tied (ordinary) vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
var
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
var
e
=
m
.
elements
;
v
.
x
=
e
[
0
]
*
x
+
e
[
1
]
*
y
+
e
[
2
]
*
z
-
e
[
12
];
v
.
y
=
e
[
4
]
*
x
+
e
[
5
]
*
y
+
e
[
6
]
*
z
-
e
[
13
];
v
.
z
=
e
[
8
]
*
x
+
e
[
9
]
*
y
+
e
[
10
]
*
z
-
e
[
14
];
return
v
;
};
ConvexObjectBreaker
.
transformPlaneToLocalSpace
=
function
()
{
var
v1
=
new
THREE
.
Vector3
();
return
function
transformPlaneToLocalSpace
(
plane
,
m
,
resultPlane
)
{
static
transformFreeVector
(
v
,
m
)
{
// input:
// vector interpreted as a free vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
const
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
const
e
=
m
.
elements
;
v
.
x
=
e
[
0
]
*
x
+
e
[
4
]
*
y
+
e
[
8
]
*
z
;
v
.
y
=
e
[
1
]
*
x
+
e
[
5
]
*
y
+
e
[
9
]
*
z
;
v
.
z
=
e
[
2
]
*
x
+
e
[
6
]
*
y
+
e
[
10
]
*
z
;
return
v
;
}
static
transformFreeVectorInverse
(
v
,
m
)
{
// input:
// vector interpreted as a free vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
const
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
const
e
=
m
.
elements
;
v
.
x
=
e
[
0
]
*
x
+
e
[
1
]
*
y
+
e
[
2
]
*
z
;
v
.
y
=
e
[
4
]
*
x
+
e
[
5
]
*
y
+
e
[
6
]
*
z
;
v
.
z
=
e
[
8
]
*
x
+
e
[
9
]
*
y
+
e
[
10
]
*
z
;
return
v
;
}
static
transformTiedVectorInverse
(
v
,
m
)
{
// input:
// vector interpreted as a tied (ordinary) vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
const
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
const
e
=
m
.
elements
;
v
.
x
=
e
[
0
]
*
x
+
e
[
1
]
*
y
+
e
[
2
]
*
z
-
e
[
12
];
v
.
y
=
e
[
4
]
*
x
+
e
[
5
]
*
y
+
e
[
6
]
*
z
-
e
[
13
];
v
.
z
=
e
[
8
]
*
x
+
e
[
9
]
*
y
+
e
[
10
]
*
z
-
e
[
14
];
return
v
;
}
static
transformPlaneToLocalSpace
(
plane
,
m
,
resultPlane
)
{
resultPlane
.
normal
.
copy
(
plane
.
normal
);
resultPlane
.
constant
=
plane
.
constant
;
var
referencePoint
=
ConvexObjectBreaker
.
transformTiedVectorInverse
(
plane
.
coplanarPoint
(
v1
),
m
);
const
referencePoint
=
ConvexObjectBreaker
.
transformTiedVectorInverse
(
plane
.
coplanarPoint
(
_
v1
),
m
);
ConvexObjectBreaker
.
transformFreeVectorInverse
(
resultPlane
.
normal
,
m
);
// recalculate constant (like in setFromNormalAndCoplanarPoint)
resultPlane
.
constant
=
-
referencePoint
.
dot
(
resultPlane
.
normal
);
}
;
}
}
();
}
THREE
.
ConvexObjectBreaker
=
ConvexObjectBreaker
;
...
...
examples/js/misc/GPUComputationRenderer.js
浏览文件 @
3452a4e3
...
...
@@ -28,16 +28,16 @@
* // Initialization...
*
* // Create computation renderer
*
var
gpuCompute = new GPUComputationRenderer( 1024, 1024, renderer );
*
const
gpuCompute = new GPUComputationRenderer( 1024, 1024, renderer );
*
* // Create initial state float textures
*
var
pos0 = gpuCompute.createTexture();
*
var
vel0 = gpuCompute.createTexture();
*
const
pos0 = gpuCompute.createTexture();
*
const
vel0 = gpuCompute.createTexture();
* // and fill in here the texture data...
*
* // Add texture variables
*
var
velVar = gpuCompute.addVariable( "textureVelocity", fragmentShaderVel, pos0 );
*
var
posVar = gpuCompute.addVariable( "texturePosition", fragmentShaderPos, vel0 );
*
const
velVar = gpuCompute.addVariable( "textureVelocity", fragmentShaderVel, pos0 );
*
const
posVar = gpuCompute.addVariable( "texturePosition", fragmentShaderPos, vel0 );
*
* // Add variable dependencies
* gpuCompute.setVariableDependencies( velVar, [ velVar, posVar ] );
...
...
@@ -47,7 +47,7 @@
* velVar.material.uniforms.time = { value: 0.0 };
*
* // Check for completeness
*
var
error = gpuCompute.init();
*
const
error = gpuCompute.init();
* if ( error !== null ) {
* console.error( error );
* }
...
...
@@ -69,19 +69,19 @@
* Also, you can use utility functions to create THREE.ShaderMaterial and perform computations (rendering between textures)
* Note that the shaders can have multiple input textures.
*
*
var
myFilter1 = gpuCompute.createShaderMaterial( myFilterFragmentShader1, { theTexture: { value: null } } );
*
var
myFilter2 = gpuCompute.createShaderMaterial( myFilterFragmentShader2, { theTexture: { value: null } } );
*
const
myFilter1 = gpuCompute.createShaderMaterial( myFilterFragmentShader1, { theTexture: { value: null } } );
*
const
myFilter2 = gpuCompute.createShaderMaterial( myFilterFragmentShader2, { theTexture: { value: null } } );
*
*
var
inputTexture = gpuCompute.createTexture();
*
const
inputTexture = gpuCompute.createTexture();
*
* // Fill in here inputTexture...
*
* myFilter1.uniforms.theTexture.value = inputTexture;
*
*
var
myRenderTarget = gpuCompute.createRenderTarget();
*
const
myRenderTarget = gpuCompute.createRenderTarget();
* myFilter2.uniforms.theTexture.value = myRenderTarget.texture;
*
*
var
outputRenderTarget = gpuCompute.createRenderTarget();
*
const
outputRenderTarget = gpuCompute.createRenderTarget();
*
* // Now use the output texture where you want:
* myMaterial.uniforms.map.value = outputRenderTarget.texture;
...
...
@@ -97,257 +97,261 @@
* @param {WebGLRenderer} renderer The renderer
*/
var
GPUComputationRenderer
=
function
(
sizeX
,
sizeY
,
renderer
)
{
this
.
variables
=
[];
this
.
currentTextureIndex
=
0
;
var
dataType
=
THREE
.
FloatType
;
var
scene
=
new
THREE
.
Scene
();
var
camera
=
new
THREE
.
Camera
();
camera
.
position
.
z
=
1
;
var
passThruUniforms
=
{
passThruTexture
:
{
value
:
null
}
};
var
passThruShader
=
createShaderMaterial
(
getPassThroughFragmentShader
(),
passThruUniforms
);
var
mesh
=
new
THREE
.
Mesh
(
new
THREE
.
PlaneGeometry
(
2
,
2
),
passThruShader
);
scene
.
add
(
mesh
);
this
.
setDataType
=
function
(
type
)
{
dataType
=
type
;
return
this
;
};
this
.
addVariable
=
function
(
variableName
,
computeFragmentShader
,
initialValueTexture
)
{
var
material
=
this
.
createShaderMaterial
(
computeFragmentShader
);
var
variable
=
{
name
:
variableName
,
initialValueTexture
:
initialValueTexture
,
material
:
material
,
dependencies
:
null
,
renderTargets
:
[],
wrapS
:
null
,
wrapT
:
null
,
minFilter
:
THREE
.
NearestFilter
,
magFilter
:
THREE
.
NearestFilter
class
GPUComputationRenderer
{
constructor
(
sizeX
,
sizeY
,
renderer
)
{
this
.
variables
=
[];
this
.
currentTextureIndex
=
0
;
let
dataType
=
THREE
.
FloatType
;
const
scene
=
new
THREE
.
Scene
();
const
camera
=
new
THREE
.
Camera
();
camera
.
position
.
z
=
1
;
const
passThruUniforms
=
{
passThruTexture
:
{
value
:
null
}
};
this
.
variables
.
push
(
variable
);
return
variable
;
const
passThruShader
=
createShaderMaterial
(
getPassThroughFragmentShader
(),
passThruUniforms
);
const
mesh
=
new
THREE
.
Mesh
(
new
THREE
.
PlaneGeometry
(
2
,
2
),
passThruShader
);
scene
.
add
(
mesh
);
};
this
.
setDataType
=
function
(
type
)
{
this
.
setVariableDependencies
=
function
(
variable
,
dependencies
)
{
dataType
=
type
;
return
this
;
variable
.
dependencies
=
dependencies
;
}
;
};
this
.
addVariable
=
function
(
variableName
,
computeFragmentShader
,
initialValueTexture
)
{
const
material
=
this
.
createShaderMaterial
(
computeFragmentShader
);
const
variable
=
{
name
:
variableName
,
initialValueTexture
:
initialValueTexture
,
material
:
material
,
dependencies
:
null
,
renderTargets
:
[],
wrapS
:
null
,
wrapT
:
null
,
minFilter
:
THREE
.
NearestFilter
,
magFilter
:
THREE
.
NearestFilter
};
this
.
variables
.
push
(
variable
);
return
variable
;
this
.
init
=
function
()
{
};
if
(
renderer
.
capabilities
.
isWebGL2
===
false
&&
renderer
.
extensions
.
has
(
'
OES_texture_float
'
)
===
false
)
{
this
.
setVariableDependencies
=
function
(
variable
,
dependencies
)
{
return
'
No OES_texture_float support for float textures.
'
;
variable
.
dependencies
=
dependencies
;
}
}
;
if
(
renderer
.
capabilities
.
maxVertexTextures
===
0
)
{
this
.
init
=
function
(
)
{
return
'
No support for vertex shader textures.
'
;
if
(
renderer
.
capabilities
.
isWebGL2
===
false
&&
renderer
.
extensions
.
has
(
'
OES_texture_float
'
)
===
false
)
{
}
return
'
No OES_texture_float support for float textures.
'
;
}
if
(
renderer
.
capabilities
.
maxVertexTextures
===
0
)
{
return
'
No support for vertex shader textures.
'
;
}
for
(
let
i
=
0
;
i
<
this
.
variables
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
this
.
variables
.
length
;
i
++
)
{
const
variable
=
this
.
variables
[
i
];
// Creates rendertargets and initialize them with input texture
var
variable
=
this
.
variables
[
i
];
// Creates rendertargets and initialize them with input texture
variable
.
renderTargets
[
0
]
=
this
.
createRenderTarget
(
sizeX
,
sizeY
,
variable
.
wrapS
,
variable
.
wrapT
,
variable
.
minFilter
,
variable
.
magFilter
);
variable
.
renderTargets
[
1
]
=
this
.
createRenderTarget
(
sizeX
,
sizeY
,
variable
.
wrapS
,
variable
.
wrapT
,
variable
.
minFilter
,
variable
.
magFilter
);
this
.
renderTexture
(
variable
.
initialValueTexture
,
variable
.
renderTargets
[
0
]
);
this
.
renderTexture
(
variable
.
initialValueTexture
,
variable
.
renderTargets
[
1
]
);
// Adds dependencies uniforms to the THREE.ShaderMaterial
variable
.
renderTargets
[
0
]
=
this
.
createRenderTarget
(
sizeX
,
sizeY
,
variable
.
wrapS
,
variable
.
wrapT
,
variable
.
minFilter
,
variable
.
magFilter
);
variable
.
renderTargets
[
1
]
=
this
.
createRenderTarget
(
sizeX
,
sizeY
,
variable
.
wrapS
,
variable
.
wrapT
,
variable
.
minFilter
,
variable
.
magFilter
);
this
.
renderTexture
(
variable
.
initialValueTexture
,
variable
.
renderTargets
[
0
]
);
this
.
renderTexture
(
variable
.
initialValueTexture
,
variable
.
renderTargets
[
1
]
);
// Adds dependencies uniforms to the THREE.ShaderMaterial
const
material
=
variable
.
material
;
const
uniforms
=
material
.
uniforms
;
var
material
=
variable
.
material
;
var
uniforms
=
material
.
uniforms
;
if
(
variable
.
dependencies
!==
null
)
{
if
(
variable
.
dependencies
!==
null
)
{
for
(
let
d
=
0
;
d
<
variable
.
dependencies
.
length
;
d
++
)
{
for
(
var
d
=
0
;
d
<
variable
.
dependencies
.
length
;
d
++
)
{
const
depVar
=
variable
.
dependencies
[
d
];
var
depVar
=
variable
.
dependencies
[
d
];
if
(
depVar
.
name
!==
variable
.
name
)
{
if
(
depVar
.
name
!==
variable
.
name
)
{
// Checks if variable exists
let
found
=
false
;
// Checks if variable exists
var
found
=
false
;
for
(
let
j
=
0
;
j
<
this
.
variables
.
length
;
j
++
)
{
for
(
var
j
=
0
;
j
<
this
.
variables
.
length
;
j
++
)
{
if
(
depVar
.
name
===
this
.
variables
[
j
].
name
)
{
if
(
depVar
.
name
===
this
.
variables
[
j
].
name
)
{
found
=
true
;
break
;
found
=
true
;
break
;
}
}
}
if
(
!
found
)
{
if
(
!
found
)
{
return
'
Variable dependency not found. Variable=
'
+
variable
.
name
+
'
, dependency=
'
+
depVar
.
name
;
return
'
Variable dependency not found. Variable=
'
+
variable
.
name
+
'
, dependency=
'
+
depVar
.
name
;
}
}
}
uniforms
[
depVar
.
name
]
=
{
value
:
null
};
material
.
fragmentShader
=
'
\n
uniform sampler2D
'
+
depVar
.
name
+
'
;
\n
'
+
material
.
fragmentShader
;
uniforms
[
depVar
.
name
]
=
{
value
:
null
};
material
.
fragmentShader
=
'
\n
uniform sampler2D
'
+
depVar
.
name
+
'
;
\n
'
+
material
.
fragmentShader
;
}
}
}
}
this
.
currentTextureIndex
=
0
;
return
null
;
this
.
currentTextureIndex
=
0
;
return
null
;
};
};
this
.
compute
=
function
()
{
this
.
compute
=
function
()
{
var
currentTextureIndex
=
this
.
currentTextureIndex
;
var
nextTextureIndex
=
this
.
currentTextureIndex
===
0
?
1
:
0
;
const
currentTextureIndex
=
this
.
currentTextureIndex
;
const
nextTextureIndex
=
this
.
currentTextureIndex
===
0
?
1
:
0
;
for
(
var
i
=
0
,
il
=
this
.
variables
.
length
;
i
<
il
;
i
++
)
{
for
(
let
i
=
0
,
il
=
this
.
variables
.
length
;
i
<
il
;
i
++
)
{
var
variable
=
this
.
variables
[
i
];
// Sets texture dependencies uniforms
const
variable
=
this
.
variables
[
i
];
// Sets texture dependencies uniforms
if
(
variable
.
dependencies
!==
null
)
{
if
(
variable
.
dependencies
!==
null
)
{
var
uniforms
=
variable
.
material
.
uniforms
;
const
uniforms
=
variable
.
material
.
uniforms
;
for
(
var
d
=
0
,
dl
=
variable
.
dependencies
.
length
;
d
<
dl
;
d
++
)
{
for
(
let
d
=
0
,
dl
=
variable
.
dependencies
.
length
;
d
<
dl
;
d
++
)
{
var
depVar
=
variable
.
dependencies
[
d
];
uniforms
[
depVar
.
name
].
value
=
depVar
.
renderTargets
[
currentTextureIndex
].
texture
;
const
depVar
=
variable
.
dependencies
[
d
];
uniforms
[
depVar
.
name
].
value
=
depVar
.
renderTargets
[
currentTextureIndex
].
texture
;
}
}
}
// Performs the computation for this variable
}
// Performs the computation for this variable
this
.
doRenderTarget
(
variable
.
material
,
variable
.
renderTargets
[
nextTextureIndex
]
);
this
.
doRenderTarget
(
variable
.
material
,
variable
.
renderTargets
[
nextTextureIndex
]
);
}
}
this
.
currentTextureIndex
=
nextTextureIndex
;
this
.
currentTextureIndex
=
nextTextureIndex
;
};
};
this
.
getCurrentRenderTarget
=
function
(
variable
)
{
this
.
getCurrentRenderTarget
=
function
(
variable
)
{
return
variable
.
renderTargets
[
this
.
currentTextureIndex
];
return
variable
.
renderTargets
[
this
.
currentTextureIndex
];
};
};
this
.
getAlternateRenderTarget
=
function
(
variable
)
{
this
.
getAlternateRenderTarget
=
function
(
variable
)
{
return
variable
.
renderTargets
[
this
.
currentTextureIndex
===
0
?
1
:
0
];
return
variable
.
renderTargets
[
this
.
currentTextureIndex
===
0
?
1
:
0
];
};
};
function
addResolutionDefine
(
materialShader
)
{
function
addResolutionDefine
(
materialShader
)
{
materialShader
.
defines
.
resolution
=
'
vec2(
'
+
sizeX
.
toFixed
(
1
)
+
'
,
'
+
sizeY
.
toFixed
(
1
)
+
'
)
'
;
materialShader
.
defines
.
resolution
=
'
vec2(
'
+
sizeX
.
toFixed
(
1
)
+
'
,
'
+
sizeY
.
toFixed
(
1
)
+
'
)
'
;
}
this
.
addResolutionDefine
=
addResolutionDefine
;
// The following functions can be used to compute things manually
}
function
createShaderMaterial
(
computeFragmentShader
,
uniforms
)
{
this
.
addResolutionDefine
=
addResolutionDefine
;
// The following functions can be used to compute things manually
uniforms
=
uniforms
||
{};
var
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
uniforms
,
vertexShader
:
getPassThroughVertexShader
(),
fragmentShader
:
computeFragmentShader
}
);
addResolutionDefine
(
material
);
return
material
;
function
createShaderMaterial
(
computeFragmentShader
,
uniforms
)
{
}
uniforms
=
uniforms
||
{};
const
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
uniforms
,
vertexShader
:
getPassThroughVertexShader
(),
fragmentShader
:
computeFragmentShader
}
);
addResolutionDefine
(
material
);
return
material
;
this
.
createShaderMaterial
=
createShaderMaterial
;
}
this
.
createRenderTarget
=
function
(
sizeXTexture
,
sizeYTexture
,
wrapS
,
wrapT
,
minFilter
,
magFilter
)
{
this
.
createShaderMaterial
=
createShaderMaterial
;
this
.
createRenderTarget
=
function
(
sizeXTexture
,
sizeYTexture
,
wrapS
,
wrapT
,
minFilter
,
magFilter
)
{
sizeXTexture
=
sizeXTexture
||
sizeX
;
sizeYTexture
=
sizeYTexture
||
sizeY
;
wrapS
=
wrapS
||
THREE
.
ClampToEdgeWrapping
;
wrapT
=
wrapT
||
THREE
.
ClampToEdgeWrapping
;
minFilter
=
minFilter
||
THREE
.
NearestFilter
;
magFilter
=
magFilter
||
THREE
.
NearestFilter
;
const
renderTarget
=
new
THREE
.
WebGLRenderTarget
(
sizeXTexture
,
sizeYTexture
,
{
wrapS
:
wrapS
,
wrapT
:
wrapT
,
minFilter
:
minFilter
,
magFilter
:
magFilter
,
format
:
THREE
.
RGBAFormat
,
type
:
dataType
,
depthBuffer
:
false
}
);
return
renderTarget
;
sizeXTexture
=
sizeXTexture
||
sizeX
;
sizeYTexture
=
sizeYTexture
||
sizeY
;
wrapS
=
wrapS
||
THREE
.
ClampToEdgeWrapping
;
wrapT
=
wrapT
||
THREE
.
ClampToEdgeWrapping
;
minFilter
=
minFilter
||
THREE
.
NearestFilter
;
magFilter
=
magFilter
||
THREE
.
NearestFilter
;
var
renderTarget
=
new
THREE
.
WebGLRenderTarget
(
sizeXTexture
,
sizeYTexture
,
{
wrapS
:
wrapS
,
wrapT
:
wrapT
,
minFilter
:
minFilter
,
magFilter
:
magFilter
,
format
:
THREE
.
RGBAFormat
,
type
:
dataType
,
depthBuffer
:
false
}
);
return
renderTarget
;
};
};
this
.
createTexture
=
function
()
{
this
.
createTexture
=
function
()
{
const
data
=
new
Float32Array
(
sizeX
*
sizeY
*
4
);
return
new
THREE
.
DataTexture
(
data
,
sizeX
,
sizeY
,
THREE
.
RGBAFormat
,
THREE
.
FloatType
);
var
data
=
new
Float32Array
(
sizeX
*
sizeY
*
4
);
return
new
THREE
.
DataTexture
(
data
,
sizeX
,
sizeY
,
THREE
.
RGBAFormat
,
THREE
.
FloatType
);
};
};
this
.
renderTexture
=
function
(
input
,
output
)
{
this
.
renderTexture
=
function
(
input
,
output
)
{
// Takes a texture, and render out in rendertarget
// input = Texture
// output = RenderTarget
passThruUniforms
.
passThruTexture
.
value
=
input
;
this
.
doRenderTarget
(
passThruShader
,
output
);
passThruUniforms
.
passThruTexture
.
value
=
null
;
// Takes a texture, and render out in rendertarget
// input = Texture
// output = RenderTarget
passThruUniforms
.
passThruTexture
.
value
=
input
;
this
.
doRenderTarget
(
passThruShader
,
output
);
passThruUniforms
.
passThruTexture
.
value
=
null
;
};
};
this
.
doRenderTarget
=
function
(
material
,
output
)
{
this
.
doRenderTarget
=
function
(
material
,
output
)
{
const
currentRenderTarget
=
renderer
.
getRenderTarget
();
mesh
.
material
=
material
;
renderer
.
setRenderTarget
(
output
);
renderer
.
render
(
scene
,
camera
);
mesh
.
material
=
passThruShader
;
renderer
.
setRenderTarget
(
currentRenderTarget
);
var
currentRenderTarget
=
renderer
.
getRenderTarget
();
mesh
.
material
=
material
;
renderer
.
setRenderTarget
(
output
);
renderer
.
render
(
scene
,
camera
);
mesh
.
material
=
passThruShader
;
renderer
.
setRenderTarget
(
currentRenderTarget
);
};
// Shaders
};
// Shaders
function
getPassThroughVertexShader
()
{
function
getPassThroughVertexShader
()
{
return
'
void main() {
\n
'
+
'
\n
'
+
'
gl_Position = vec4( position, 1.0 );
\n
'
+
'
\n
'
+
'
}
\n
'
;
return
'
void main() {
\n
'
+
'
\n
'
+
'
gl_Position = vec4( position, 1.0 );
\n
'
+
'
\n
'
+
'
}
\n
'
;
}
}
function
getPassThroughFragmentShader
()
{
function
getPassThroughFragmentShader
()
{
return
'
uniform sampler2D passThruTexture;
\n
'
+
'
\n
'
+
'
void main() {
\n
'
+
'
\n
'
+
'
vec2 uv = gl_FragCoord.xy / resolution.xy;
\n
'
+
'
\n
'
+
'
gl_FragColor = texture2D( passThruTexture, uv );
\n
'
+
'
\n
'
+
'
}
\n
'
;
return
'
uniform sampler2D passThruTexture;
\n
'
+
'
\n
'
+
'
void main() {
\n
'
+
'
\n
'
+
'
vec2 uv = gl_FragCoord.xy / resolution.xy;
\n
'
+
'
\n
'
+
'
gl_FragColor = texture2D( passThruTexture, uv );
\n
'
+
'
\n
'
+
'
}
\n
'
;
}
}
}
;
}
THREE
.
GPUComputationRenderer
=
GPUComputationRenderer
;
...
...
examples/js/misc/Gyroscope.js
浏览文件 @
3452a4e3
(
function
()
{
var
Gyroscope
=
function
()
{
const
_translationObject
=
new
THREE
.
Vector3
();
THREE
.
Object3D
.
call
(
this
);
const
_quaternionObject
=
new
THREE
.
Quaternion
(
);
}
;
const
_scaleObject
=
new
THREE
.
Vector3
()
;
Gyroscope
.
prototype
=
Object
.
create
(
THREE
.
Object3D
.
prototype
);
Gyroscope
.
prototype
.
constructor
=
Gyroscope
;
const
_translationWorld
=
new
THREE
.
Vector3
();
Gyroscope
.
prototype
.
updateMatrixWorld
=
function
()
{
const
_quaternionWorld
=
new
THREE
.
Quaternion
();
var
translationObject
=
new
THREE
.
Vector3
();
var
quaternionObject
=
new
THREE
.
Quaternion
();
var
scaleObject
=
new
THREE
.
Vector3
();
var
translationWorld
=
new
THREE
.
Vector3
();
var
quaternionWorld
=
new
THREE
.
Quaternion
();
var
scaleWorld
=
new
THREE
.
Vector3
();
return
function
updateMatrixWorld
(
force
)
{
const
_scaleWorld
=
new
THREE
.
Vector3
();
class
Gyroscope
extends
THREE
.
Object3D
{
constructor
()
{
super
();
}
updateMatrixWorld
(
force
)
{
this
.
matrixAutoUpdate
&&
this
.
updateMatrix
();
// update matrixWorld
...
...
@@ -26,9 +29,9 @@
if
(
this
.
parent
!==
null
)
{
this
.
matrixWorld
.
multiplyMatrices
(
this
.
parent
.
matrixWorld
,
this
.
matrix
);
this
.
matrixWorld
.
decompose
(
translationWorld
,
quaternionWorld
,
scaleWorld
);
this
.
matrix
.
decompose
(
translationObject
,
quaternionObject
,
scaleObject
);
this
.
matrixWorld
.
compose
(
translationWorld
,
quaternionObject
,
scaleWorld
);
this
.
matrixWorld
.
decompose
(
_translationWorld
,
_quaternionWorld
,
_
scaleWorld
);
this
.
matrix
.
decompose
(
_translationObject
,
_quaternionObject
,
_
scaleObject
);
this
.
matrixWorld
.
compose
(
_translationWorld
,
_quaternionObject
,
_
scaleWorld
);
}
else
{
...
...
@@ -42,15 +45,15 @@
}
// update children
for
(
var
i
=
0
,
l
=
this
.
children
.
length
;
i
<
l
;
i
++
)
{
for
(
let
i
=
0
,
l
=
this
.
children
.
length
;
i
<
l
;
i
++
)
{
this
.
children
[
i
].
updateMatrixWorld
(
force
);
}
}
;
}
}
();
}
THREE
.
Gyroscope
=
Gyroscope
;
...
...
examples/js/misc/MD2Character.js
浏览文件 @
3452a4e3
(
function
()
{
var
MD2Character
=
function
()
{
class
MD2Character
{
var
scope
=
this
;
this
.
scale
=
1
;
this
.
animationFPS
=
6
;
this
.
root
=
new
THREE
.
Object3D
();
this
.
meshBody
=
null
;
this
.
meshWeapon
=
null
;
this
.
skinsBody
=
[];
this
.
skinsWeapon
=
[];
this
.
weapons
=
[];
this
.
activeAnimation
=
null
;
this
.
mixer
=
null
;
constructor
()
{
this
.
onLoadComplete
=
function
()
{};
this
.
scale
=
1
;
this
.
animationFPS
=
6
;
this
.
root
=
new
THREE
.
Object3D
();
this
.
meshBody
=
null
;
this
.
meshWeapon
=
null
;
this
.
skinsBody
=
[];
this
.
skinsWeapon
=
[];
this
.
weapons
=
[];
this
.
activeAnimation
=
null
;
this
.
mixer
=
null
;
this
.
loadCounter
=
0
;
this
.
onLoadComplete
=
function
()
{}
;
this
.
loadParts
=
function
(
config
)
{
this
.
loadCounter
=
0
;
}
loadParts
(
config
)
{
const
scope
=
this
;
function
createPart
(
geometry
,
skinMap
)
{
const
materialWireframe
=
new
THREE
.
MeshLambertMaterial
(
{
color
:
0xffaa00
,
wireframe
:
true
,
morphTargets
:
true
,
morphNormals
:
true
}
);
const
materialTexture
=
new
THREE
.
MeshLambertMaterial
(
{
color
:
0xffffff
,
wireframe
:
false
,
map
:
skinMap
,
morphTargets
:
true
,
morphNormals
:
true
}
);
//
const
mesh
=
new
THREE
.
Mesh
(
geometry
,
materialTexture
);
mesh
.
rotation
.
y
=
-
Math
.
PI
/
2
;
mesh
.
castShadow
=
true
;
mesh
.
receiveShadow
=
true
;
//
mesh
.
materialTexture
=
materialTexture
;
mesh
.
materialWireframe
=
materialWireframe
;
return
mesh
;
}
function
loadTextures
(
baseUrl
,
textureUrls
)
{
const
textureLoader
=
new
THREE
.
TextureLoader
();
const
textures
=
[];
for
(
let
i
=
0
;
i
<
textureUrls
.
length
;
i
++
)
{
textures
[
i
]
=
textureLoader
.
load
(
baseUrl
+
textureUrls
[
i
],
checkLoadingComplete
);
textures
[
i
].
mapping
=
THREE
.
UVMapping
;
textures
[
i
].
name
=
textureUrls
[
i
];
textures
[
i
].
encoding
=
THREE
.
sRGBEncoding
;
}
return
textures
;
}
function
checkLoadingComplete
()
{
scope
.
loadCounter
-=
1
;
if
(
scope
.
loadCounter
===
0
)
scope
.
onLoadComplete
();
}
this
.
loadCounter
=
config
.
weapons
.
length
*
2
+
config
.
skins
.
length
+
1
;
var
weaponsTextures
=
[];
const
weaponsTextures
=
[];
for
(
var
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
weaponsTextures
[
i
]
=
config
.
weapons
[
i
][
1
];
// SKINS
for
(
let
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
weaponsTextures
[
i
]
=
config
.
weapons
[
i
][
1
];
// SKINS
this
.
skinsBody
=
loadTextures
(
config
.
baseUrl
+
'
skins/
'
,
config
.
skins
);
this
.
skinsWeapon
=
loadTextures
(
config
.
baseUrl
+
'
skins/
'
,
weaponsTextures
);
// BODY
var
loader
=
new
THREE
.
MD2Loader
();
const
loader
=
new
THREE
.
MD2Loader
();
loader
.
load
(
config
.
baseUrl
+
config
.
body
,
function
(
geo
)
{
var
boundingBox
=
new
THREE
.
Box3
();
const
boundingBox
=
new
THREE
.
Box3
();
boundingBox
.
setFromBufferAttribute
(
geo
.
attributes
.
position
);
scope
.
root
.
position
.
y
=
-
scope
.
scale
*
boundingBox
.
min
.
y
;
var
mesh
=
createPart
(
geo
,
scope
.
skinsBody
[
0
]
);
const
mesh
=
createPart
(
geo
,
scope
.
skinsBody
[
0
]
);
mesh
.
scale
.
set
(
scope
.
scale
,
scope
.
scale
,
scope
.
scale
);
scope
.
root
.
add
(
mesh
);
scope
.
meshBody
=
mesh
;
...
...
@@ -46,11 +103,11 @@
}
);
// WEAPONS
var
generateCallback
=
function
(
index
,
name
)
{
const
generateCallback
=
function
(
index
,
name
)
{
return
function
(
geo
)
{
var
mesh
=
createPart
(
geo
,
scope
.
skinsWeapon
[
index
]
);
const
mesh
=
createPart
(
geo
,
scope
.
skinsWeapon
[
index
]
);
mesh
.
scale
.
set
(
scope
.
scale
,
scope
.
scale
,
scope
.
scale
);
mesh
.
visible
=
false
;
mesh
.
name
=
name
;
...
...
@@ -63,15 +120,15 @@
};
for
(
var
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
{
loader
.
load
(
config
.
baseUrl
+
config
.
weapons
[
i
][
0
],
generateCallback
(
i
,
config
.
weapons
[
i
][
0
]
)
);
}
}
;
}
this
.
setPlaybackRate
=
function
(
rate
)
{
setPlaybackRate
(
rate
)
{
if
(
rate
!==
0
)
{
...
...
@@ -83,9 +140,9 @@
}
}
;
}
this
.
setWireframe
=
function
(
wireframeEnabled
)
{
setWireframe
(
wireframeEnabled
)
{
if
(
wireframeEnabled
)
{
...
...
@@ -99,9 +156,9 @@
}
}
;
}
this
.
setSkin
=
function
(
index
)
{
setSkin
(
index
)
{
if
(
this
.
meshBody
&&
this
.
meshBody
.
material
.
wireframe
===
false
)
{
...
...
@@ -109,25 +166,25 @@
}
}
;
}
this
.
setWeapon
=
function
(
index
)
{
setWeapon
(
index
)
{
for
(
var
i
=
0
;
i
<
this
.
weapons
.
length
;
i
++
)
this
.
weapons
[
i
].
visible
=
false
;
for
(
let
i
=
0
;
i
<
this
.
weapons
.
length
;
i
++
)
this
.
weapons
[
i
].
visible
=
false
;
var
activeWeapon
=
this
.
weapons
[
index
];
const
activeWeapon
=
this
.
weapons
[
index
];
if
(
activeWeapon
)
{
activeWeapon
.
visible
=
true
;
this
.
meshWeapon
=
activeWeapon
;
scope
.
syncWeaponAnimation
();
this
.
syncWeaponAnimation
();
}
}
;
}
this
.
setAnimation
=
function
(
clipName
)
{
setAnimation
(
clipName
)
{
if
(
this
.
meshBody
)
{
...
...
@@ -138,7 +195,7 @@
}
var
action
=
this
.
mixer
.
clipAction
(
clipName
,
this
.
meshBody
);
const
action
=
this
.
mixer
.
clipAction
(
clipName
,
this
.
meshBody
);
if
(
action
)
{
...
...
@@ -148,16 +205,16 @@
}
scope
.
activeClipName
=
clipName
;
scope
.
syncWeaponAnimation
();
this
.
activeClipName
=
clipName
;
this
.
syncWeaponAnimation
();
}
;
}
this
.
syncWeaponAnimation
=
function
()
{
syncWeaponAnimation
()
{
var
clipName
=
scope
.
activeClipName
;
const
clipName
=
this
.
activeClipName
;
if
(
scope
.
meshWeapon
)
{
if
(
this
.
meshWeapon
)
{
if
(
this
.
meshWeapon
.
activeAction
)
{
...
...
@@ -166,7 +223,7 @@
}
var
action
=
this
.
mixer
.
clipAction
(
clipName
,
this
.
meshWeapon
);
const
action
=
this
.
mixer
.
clipAction
(
clipName
,
this
.
meshWeapon
);
if
(
action
)
{
...
...
@@ -176,67 +233,15 @@
}
};
this
.
update
=
function
(
delta
)
{
if
(
this
.
mixer
)
this
.
mixer
.
update
(
delta
);
};
function
loadTextures
(
baseUrl
,
textureUrls
)
{
var
textureLoader
=
new
THREE
.
TextureLoader
();
var
textures
=
[];
for
(
var
i
=
0
;
i
<
textureUrls
.
length
;
i
++
)
{
textures
[
i
]
=
textureLoader
.
load
(
baseUrl
+
textureUrls
[
i
],
checkLoadingComplete
);
textures
[
i
].
mapping
=
THREE
.
UVMapping
;
textures
[
i
].
name
=
textureUrls
[
i
];
textures
[
i
].
encoding
=
THREE
.
sRGBEncoding
;
}
return
textures
;
}
function
createPart
(
geometry
,
skinMap
)
{
var
materialWireframe
=
new
THREE
.
MeshLambertMaterial
(
{
color
:
0xffaa00
,
wireframe
:
true
,
morphTargets
:
true
,
morphNormals
:
true
}
);
var
materialTexture
=
new
THREE
.
MeshLambertMaterial
(
{
color
:
0xffffff
,
wireframe
:
false
,
map
:
skinMap
,
morphTargets
:
true
,
morphNormals
:
true
}
);
//
var
mesh
=
new
THREE
.
Mesh
(
geometry
,
materialTexture
);
mesh
.
rotation
.
y
=
-
Math
.
PI
/
2
;
mesh
.
castShadow
=
true
;
mesh
.
receiveShadow
=
true
;
//
mesh
.
materialTexture
=
materialTexture
;
mesh
.
materialWireframe
=
materialWireframe
;
return
mesh
;
}
update
(
delta
)
{
function
checkLoadingComplete
()
{
scope
.
loadCounter
-=
1
;
if
(
scope
.
loadCounter
===
0
)
scope
.
onLoadComplete
();
if
(
this
.
mixer
)
this
.
mixer
.
update
(
delta
);
}
}
;
}
THREE
.
MD2Character
=
MD2Character
;
...
...
examples/js/misc/MD2CharacterComplex.js
浏览文件 @
3452a4e3
(
function
()
{
var
MD2CharacterComplex
=
function
()
{
class
MD2CharacterComplex
{
var
scope
=
this
;
this
.
scale
=
1
;
// animation parameters
constructor
()
{
this
.
animationFPS
=
6
;
this
.
transitionFrames
=
15
;
// movement model parameters
this
.
scale
=
1
;
// animation parameters
this
.
maxSpeed
=
275
;
this
.
maxReverseSpeed
=
-
275
;
this
.
frontAcceleration
=
600
;
this
.
backAcceleration
=
600
;
this
.
frontDecceleration
=
600
;
this
.
angularSpeed
=
2.5
;
// rig
this
.
animationFPS
=
6
;
this
.
transitionFrames
=
15
;
// movement model parameters
this
.
root
=
new
THREE
.
Object3D
();
this
.
meshBody
=
null
;
this
.
meshWeapon
=
null
;
this
.
controls
=
null
;
// skins
this
.
maxSpeed
=
275
;
this
.
maxReverseSpeed
=
-
275
;
this
.
frontAcceleration
=
600
;
this
.
backAcceleration
=
600
;
this
.
frontDecceleration
=
600
;
this
.
angularSpeed
=
2.5
;
// rig
this
.
skinsBody
=
[]
;
this
.
skinsWeapon
=
[]
;
this
.
weapons
=
[]
;
this
.
currentSkin
=
undefined
;
//
this
.
root
=
new
THREE
.
Object3D
()
;
this
.
meshBody
=
null
;
this
.
meshWeapon
=
null
;
this
.
controls
=
null
;
// skins
this
.
onLoadComplete
=
function
()
{};
// internals
this
.
skinsBody
=
[];
this
.
skinsWeapon
=
[];
this
.
weapons
=
[];
this
.
currentSkin
=
undefined
;
//
this
.
onLoadComplete
=
function
()
{};
// internals
this
.
meshes
=
[];
this
.
animations
=
{};
this
.
loadCounter
=
0
;
// internal movement control variables
this
.
speed
=
0
;
this
.
bodyOrientation
=
0
;
this
.
walkSpeed
=
this
.
maxSpeed
;
this
.
crouchSpeed
=
this
.
maxSpeed
*
0.5
;
// internal animation parameters
this
.
meshes
=
[];
this
.
animations
=
{};
this
.
loadCounter
=
0
;
// internal movement control variables
this
.
activeAnimation
=
null
;
this
.
oldAnimation
=
null
;
// API
this
.
speed
=
0
;
this
.
bodyOrientation
=
0
;
this
.
walkSpeed
=
this
.
maxSpeed
;
this
.
crouchSpeed
=
this
.
maxSpeed
*
0.5
;
// internal animation parameters
this
.
enableShadows
=
function
(
enable
)
{
this
.
activeAnimation
=
null
;
this
.
oldAnimation
=
null
;
// API
for
(
var
i
=
0
;
i
<
this
.
meshes
.
length
;
i
++
)
{
}
enableShadows
(
enable
)
{
for
(
let
i
=
0
;
i
<
this
.
meshes
.
length
;
i
++
)
{
this
.
meshes
[
i
].
castShadow
=
enable
;
this
.
meshes
[
i
].
receiveShadow
=
enable
;
}
}
;
}
this
.
setVisible
=
function
(
enable
)
{
setVisible
(
enable
)
{
for
(
var
i
=
0
;
i
<
this
.
meshes
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
this
.
meshes
.
length
;
i
++
)
{
this
.
meshes
[
i
].
visible
=
enable
;
this
.
meshes
[
i
].
visible
=
enable
;
}
}
;
}
this
.
shareParts
=
function
(
original
)
{
shareParts
(
original
)
{
this
.
animations
=
original
.
animations
;
this
.
walkSpeed
=
original
.
walkSpeed
;
...
...
@@ -70,16 +73,18 @@
this
.
skinsBody
=
original
.
skinsBody
;
this
.
skinsWeapon
=
original
.
skinsWeapon
;
// BODY
var
mesh
=
createPart
(
original
.
meshBody
.
geometry
,
this
.
skinsBody
[
0
]
);
const
mesh
=
this
.
_createPart
(
original
.
meshBody
.
geometry
,
this
.
skinsBody
[
0
]
);
mesh
.
scale
.
set
(
this
.
scale
,
this
.
scale
,
this
.
scale
);
this
.
root
.
position
.
y
=
original
.
root
.
position
.
y
;
this
.
root
.
add
(
mesh
);
this
.
meshBody
=
mesh
;
this
.
meshes
.
push
(
mesh
);
// WEAPONS
for
(
var
i
=
0
;
i
<
original
.
weapons
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
original
.
weapons
.
length
;
i
++
)
{
const
meshWeapon
=
this
.
_createPart
(
original
.
weapons
[
i
].
geometry
,
this
.
skinsWeapon
[
i
]
);
var
meshWeapon
=
createPart
(
original
.
weapons
[
i
].
geometry
,
this
.
skinsWeapon
[
i
]
);
meshWeapon
.
scale
.
set
(
this
.
scale
,
this
.
scale
,
this
.
scale
);
meshWeapon
.
visible
=
false
;
meshWeapon
.
name
=
original
.
weapons
[
i
].
name
;
...
...
@@ -90,29 +95,58 @@
}
};
}
loadParts
(
config
)
{
const
scope
=
this
;
function
loadTextures
(
baseUrl
,
textureUrls
)
{
const
textureLoader
=
new
THREE
.
TextureLoader
();
const
textures
=
[];
for
(
let
i
=
0
;
i
<
textureUrls
.
length
;
i
++
)
{
textures
[
i
]
=
textureLoader
.
load
(
baseUrl
+
textureUrls
[
i
],
checkLoadingComplete
);
textures
[
i
].
mapping
=
THREE
.
UVMapping
;
textures
[
i
].
name
=
textureUrls
[
i
];
textures
[
i
].
encoding
=
THREE
.
sRGBEncoding
;
}
return
textures
;
}
function
checkLoadingComplete
()
{
scope
.
loadCounter
-=
1
;
if
(
scope
.
loadCounter
===
0
)
scope
.
onLoadComplete
();
this
.
loadParts
=
function
(
config
)
{
}
this
.
animations
=
config
.
animations
;
this
.
walkSpeed
=
config
.
walkSpeed
;
this
.
crouchSpeed
=
config
.
crouchSpeed
;
this
.
loadCounter
=
config
.
weapons
.
length
*
2
+
config
.
skins
.
length
+
1
;
var
weaponsTextures
=
[];
const
weaponsTextures
=
[];
for
(
var
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
weaponsTextures
[
i
]
=
config
.
weapons
[
i
][
1
];
// SKINS
for
(
let
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
weaponsTextures
[
i
]
=
config
.
weapons
[
i
][
1
];
// SKINS
this
.
skinsBody
=
loadTextures
(
config
.
baseUrl
+
'
skins/
'
,
config
.
skins
);
this
.
skinsWeapon
=
loadTextures
(
config
.
baseUrl
+
'
skins/
'
,
weaponsTextures
);
// BODY
var
loader
=
new
THREE
.
MD2Loader
();
const
loader
=
new
THREE
.
MD2Loader
();
loader
.
load
(
config
.
baseUrl
+
config
.
body
,
function
(
geo
)
{
var
boundingBox
=
new
THREE
.
Box3
();
const
boundingBox
=
new
THREE
.
Box3
();
boundingBox
.
setFromBufferAttribute
(
geo
.
attributes
.
position
);
scope
.
root
.
position
.
y
=
-
scope
.
scale
*
boundingBox
.
min
.
y
;
var
mesh
=
createPart
(
geo
,
scope
.
skinsBody
[
0
]
);
const
mesh
=
scope
.
_createPart
(
geo
,
scope
.
skinsBody
[
0
]
);
mesh
.
scale
.
set
(
scope
.
scale
,
scope
.
scale
,
scope
.
scale
);
scope
.
root
.
add
(
mesh
);
scope
.
meshBody
=
mesh
;
...
...
@@ -121,11 +155,12 @@
}
);
// WEAPONS
var
generateCallback
=
function
(
index
,
name
)
{
const
generateCallback
=
function
(
index
,
name
)
{
return
function
(
geo
)
{
var
mesh
=
createPart
(
geo
,
scope
.
skinsWeapon
[
index
]
);
const
mesh
=
scope
.
_createPart
(
geo
,
scope
.
skinsWeapon
[
index
]
);
mesh
.
scale
.
set
(
scope
.
scale
,
scope
.
scale
,
scope
.
scale
);
mesh
.
visible
=
false
;
mesh
.
name
=
name
;
...
...
@@ -139,22 +174,22 @@
};
for
(
var
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
{
loader
.
load
(
config
.
baseUrl
+
config
.
weapons
[
i
][
0
],
generateCallback
(
i
,
config
.
weapons
[
i
][
0
]
)
);
}
}
;
}
this
.
setPlaybackRate
=
function
(
rate
)
{
setPlaybackRate
(
rate
)
{
if
(
this
.
meshBody
)
this
.
meshBody
.
duration
=
this
.
meshBody
.
baseDuration
/
rate
;
if
(
this
.
meshWeapon
)
this
.
meshWeapon
.
duration
=
this
.
meshWeapon
.
baseDuration
/
rate
;
}
;
}
this
.
setWireframe
=
function
(
wireframeEnabled
)
{
setWireframe
(
wireframeEnabled
)
{
if
(
wireframeEnabled
)
{
...
...
@@ -168,9 +203,9 @@
}
}
;
}
this
.
setSkin
=
function
(
index
)
{
setSkin
(
index
)
{
if
(
this
.
meshBody
&&
this
.
meshBody
.
material
.
wireframe
===
false
)
{
...
...
@@ -179,13 +214,13 @@
}
}
;
}
this
.
setWeapon
=
function
(
index
)
{
setWeapon
(
index
)
{
for
(
var
i
=
0
;
i
<
this
.
weapons
.
length
;
i
++
)
this
.
weapons
[
i
].
visible
=
false
;
for
(
let
i
=
0
;
i
<
this
.
weapons
.
length
;
i
++
)
this
.
weapons
[
i
].
visible
=
false
;
var
activeWeapon
=
this
.
weapons
[
index
];
const
activeWeapon
=
this
.
weapons
[
index
];
if
(
activeWeapon
)
{
...
...
@@ -201,9 +236,9 @@
}
}
;
}
this
.
setAnimation
=
function
(
animationName
)
{
setAnimation
(
animationName
)
{
if
(
animationName
===
this
.
activeAnimation
||
!
animationName
)
return
;
...
...
@@ -224,9 +259,9 @@
}
}
;
}
this
.
update
=
function
(
delta
)
{
update
(
delta
)
{
if
(
this
.
controls
)
this
.
updateMovementModel
(
delta
);
...
...
@@ -237,11 +272,11 @@
}
}
;
}
this
.
updateAnimations
=
function
(
delta
)
{
updateAnimations
(
delta
)
{
var
mix
=
1
;
let
mix
=
1
;
if
(
this
.
blendCounter
>
0
)
{
...
...
@@ -266,13 +301,13 @@
}
}
;
}
this
.
updateBehaviors
=
function
()
{
updateBehaviors
()
{
var
controls
=
this
.
controls
;
var
animations
=
this
.
animations
;
var
moveAnimation
,
idleAnimation
;
// crouch vs stand
const
controls
=
this
.
controls
;
const
animations
=
this
.
animations
;
let
moveAnimation
,
idleAnimation
;
// crouch vs stand
if
(
controls
.
crouch
)
{
...
...
@@ -368,11 +403,17 @@
}
};
}
updateMovementModel
(
delta
)
{
this
.
updateMovementModel
=
function
(
delta
)
{
function
exponentialEaseOut
(
k
)
{
var
controls
=
this
.
controls
;
// speed based on controls
return
k
===
1
?
1
:
-
Math
.
pow
(
2
,
-
10
*
k
)
+
1
;
}
const
controls
=
this
.
controls
;
// speed based on controls
if
(
controls
.
crouch
)
this
.
maxSpeed
=
this
.
crouchSpeed
;
else
this
.
maxSpeed
=
this
.
walkSpeed
;
this
.
maxReverseSpeed
=
-
this
.
maxSpeed
;
...
...
@@ -380,7 +421,7 @@
if
(
controls
.
moveBackward
)
this
.
speed
=
THREE
.
MathUtils
.
clamp
(
this
.
speed
-
delta
*
this
.
backAcceleration
,
this
.
maxReverseSpeed
,
this
.
maxSpeed
);
// orientation based on controls
// (don't just stand while turning)
var
dir
=
1
;
const
dir
=
1
;
if
(
controls
.
moveLeft
)
{
...
...
@@ -401,12 +442,12 @@
if
(
this
.
speed
>
0
)
{
var
k
=
exponentialEaseOut
(
this
.
speed
/
this
.
maxSpeed
);
const
k
=
exponentialEaseOut
(
this
.
speed
/
this
.
maxSpeed
);
this
.
speed
=
THREE
.
MathUtils
.
clamp
(
this
.
speed
-
k
*
delta
*
this
.
frontDecceleration
,
0
,
this
.
maxSpeed
);
}
else
{
var
k
=
exponentialEaseOut
(
this
.
speed
/
this
.
maxReverseSpeed
);
const
k
=
exponentialEaseOut
(
this
.
speed
/
this
.
maxReverseSpeed
);
this
.
speed
=
THREE
.
MathUtils
.
clamp
(
this
.
speed
+
k
*
delta
*
this
.
backAcceleration
,
this
.
maxReverseSpeed
,
0
);
}
...
...
@@ -414,42 +455,24 @@
}
// displacement
var
forwardDelta
=
this
.
speed
*
delta
;
const
forwardDelta
=
this
.
speed
*
delta
;
this
.
root
.
position
.
x
+=
Math
.
sin
(
this
.
bodyOrientation
)
*
forwardDelta
;
this
.
root
.
position
.
z
+=
Math
.
cos
(
this
.
bodyOrientation
)
*
forwardDelta
;
// steering
this
.
root
.
rotation
.
y
=
this
.
bodyOrientation
;
};
// internal helpers
}
// internal
function
loadTextures
(
baseUrl
,
textureUrls
)
{
var
textureLoader
=
new
THREE
.
TextureLoader
();
var
textures
=
[];
_createPart
(
geometry
,
skinMap
)
{
for
(
var
i
=
0
;
i
<
textureUrls
.
length
;
i
++
)
{
textures
[
i
]
=
textureLoader
.
load
(
baseUrl
+
textureUrls
[
i
],
checkLoadingComplete
);
textures
[
i
].
mapping
=
THREE
.
UVMapping
;
textures
[
i
].
name
=
textureUrls
[
i
];
textures
[
i
].
encoding
=
THREE
.
sRGBEncoding
;
}
return
textures
;
}
function
createPart
(
geometry
,
skinMap
)
{
var
materialWireframe
=
new
THREE
.
MeshLambertMaterial
(
{
const
materialWireframe
=
new
THREE
.
MeshLambertMaterial
(
{
color
:
0xffaa00
,
wireframe
:
true
,
morphTargets
:
true
,
morphNormals
:
true
}
);
var
materialTexture
=
new
THREE
.
MeshLambertMaterial
(
{
const
materialTexture
=
new
THREE
.
MeshLambertMaterial
(
{
color
:
0xffffff
,
wireframe
:
false
,
map
:
skinMap
,
...
...
@@ -457,31 +480,18 @@
morphNormals
:
true
}
);
//
var
mesh
=
new
THREE
.
MorphBlendMesh
(
geometry
,
materialTexture
);
const
mesh
=
new
THREE
.
MorphBlendMesh
(
geometry
,
materialTexture
);
mesh
.
rotation
.
y
=
-
Math
.
PI
/
2
;
//
mesh
.
materialTexture
=
materialTexture
;
mesh
.
materialWireframe
=
materialWireframe
;
//
mesh
.
autoCreateAnimations
(
scope
.
animationFPS
);
mesh
.
autoCreateAnimations
(
this
.
animationFPS
);
return
mesh
;
}
function
checkLoadingComplete
()
{
scope
.
loadCounter
-=
1
;
if
(
scope
.
loadCounter
===
0
)
scope
.
onLoadComplete
();
}
function
exponentialEaseOut
(
k
)
{
return
k
===
1
?
1
:
-
Math
.
pow
(
2
,
-
10
*
k
)
+
1
;
}
};
}
THREE
.
MD2CharacterComplex
=
MD2CharacterComplex
;
...
...
examples/js/misc/MorphAnimMesh.js
浏览文件 @
3452a4e3
(
function
()
{
var
MorphAnimMesh
=
function
(
geometry
,
material
)
{
class
MorphAnimMesh
extends
THREE
.
Mesh
{
THREE
.
Mesh
.
call
(
this
,
geometry
,
material
);
this
.
type
=
'
MorphAnimMesh
'
;
this
.
mixer
=
new
THREE
.
AnimationMixer
(
this
);
this
.
activeAction
=
null
;
constructor
(
geometry
,
material
)
{
};
super
(
geometry
,
material
);
this
.
type
=
'
MorphAnimMesh
'
;
this
.
mixer
=
new
THREE
.
AnimationMixer
(
this
);
this
.
activeAction
=
null
;
MorphAnimMesh
.
prototype
=
Object
.
create
(
THREE
.
Mesh
.
prototype
);
MorphAnimMesh
.
prototype
.
constructor
=
MorphAnimMesh
;
}
MorphAnimMesh
.
prototype
.
setDirectionForward
=
function
()
{
setDirectionForward
()
{
this
.
mixer
.
timeScale
=
1.0
;
this
.
mixer
.
timeScale
=
1.0
;
};
}
MorphAnimMesh
.
prototype
.
setDirectionBackward
=
function
()
{
setDirectionBackward
()
{
this
.
mixer
.
timeScale
=
-
1.0
;
this
.
mixer
.
timeScale
=
-
1.0
;
};
}
MorphAnimMesh
.
prototype
.
playAnimation
=
function
(
label
,
fps
)
{
playAnimation
(
label
,
fps
)
{
if
(
this
.
activeAction
)
{
if
(
this
.
activeAction
)
{
this
.
activeAction
.
stop
();
this
.
activeAction
=
null
;
this
.
activeAction
.
stop
();
this
.
activeAction
=
null
;
}
}
const
clip
=
THREE
.
AnimationClip
.
findByName
(
this
,
label
);
var
clip
=
THREE
.
AnimationClip
.
findByName
(
this
,
label
);
if
(
clip
)
{
if
(
clip
)
{
const
action
=
this
.
mixer
.
clipAction
(
clip
);
action
.
timeScale
=
clip
.
tracks
.
length
*
fps
/
clip
.
duration
;
this
.
activeAction
=
action
.
play
();
var
action
=
this
.
mixer
.
clipAction
(
clip
);
action
.
timeScale
=
clip
.
tracks
.
length
*
fps
/
clip
.
duration
;
this
.
activeAction
=
action
.
play
();
}
else
{
}
else
{
throw
new
Error
(
'
THREE.MorphAnimMesh: animations[
'
+
label
+
'
] undefined in .playAnimation()
'
);
throw
new
Error
(
'
THREE.MorphAnimMesh: animations[
'
+
label
+
'
] undefined in .playAnimation()
'
);
}
}
};
updateAnimation
(
delta
)
{
MorphAnimMesh
.
prototype
.
updateAnimation
=
function
(
delta
)
{
this
.
mixer
.
update
(
delta
);
this
.
mixer
.
update
(
delta
);
}
};
copy
(
source
)
{
MorphAnimMesh
.
prototype
.
copy
=
function
(
source
)
{
super
.
copy
(
source
);
this
.
mixer
=
new
THREE
.
AnimationMixer
(
this
);
return
this
;
THREE
.
Mesh
.
prototype
.
copy
.
call
(
this
,
source
);
this
.
mixer
=
new
THREE
.
AnimationMixer
(
this
);
return
this
;
}
}
;
}
THREE
.
MorphAnimMesh
=
MorphAnimMesh
;
...
...
examples/js/misc/MorphBlendMesh.js
浏览文件 @
3452a4e3
(
function
()
{
var
MorphBlendMesh
=
function
(
geometry
,
material
)
{
class
MorphBlendMesh
extends
THREE
.
Mesh
{
THREE
.
Mesh
.
call
(
this
,
geometry
,
material
);
this
.
animationsMap
=
{};
this
.
animationsList
=
[];
// prepare default animation
// (all frames played together in 1 second)
constructor
(
geometry
,
material
)
{
var
numFrames
=
Object
.
keys
(
this
.
morphTargetDictionary
).
length
;
var
name
=
'
__default
'
;
var
startFrame
=
0
;
var
endFrame
=
numFrames
-
1
;
var
fps
=
numFrames
/
1
;
this
.
createAnimation
(
name
,
startFrame
,
endFrame
,
fps
);
this
.
setAnimationWeight
(
name
,
1
);
super
(
geometry
,
material
);
this
.
animationsMap
=
{};
this
.
animationsList
=
[];
// prepare default animation
// (all frames played together in 1 second)
};
const
numFrames
=
Object
.
keys
(
this
.
morphTargetDictionary
).
length
;
const
name
=
'
__default
'
;
const
startFrame
=
0
;
const
endFrame
=
numFrames
-
1
;
const
fps
=
numFrames
/
1
;
this
.
createAnimation
(
name
,
startFrame
,
endFrame
,
fps
);
this
.
setAnimationWeight
(
name
,
1
);
MorphBlendMesh
.
prototype
=
Object
.
assign
(
Object
.
create
(
THREE
.
Mesh
.
prototype
),
{
constructor
:
MorphBlendMesh
,
createAnimation
:
function
(
name
,
start
,
end
,
fps
)
{
}
createAnimation
(
name
,
start
,
end
,
fps
)
{
var
animation
=
{
const
animation
=
{
start
:
start
,
end
:
end
,
length
:
end
-
start
+
1
,
...
...
@@ -39,26 +39,27 @@
this
.
animationsMap
[
name
]
=
animation
;
this
.
animationsList
.
push
(
animation
);
},
autoCreateAnimations
:
function
(
fps
)
{
}
autoCreateAnimations
(
fps
)
{
var
pattern
=
/
([
a-z
]
+
)
_
?(\d
+
)
/i
;
var
firstAnimation
,
frameRanges
=
{};
var
i
=
0
;
const
pattern
=
/
([
a-z
]
+
)
_
?(\d
+
)
/i
;
let
firstAnimation
;
const
frameRanges
=
{};
let
i
=
0
;
for
(
var
key
in
this
.
morphTargetDictionary
)
{
for
(
const
key
in
this
.
morphTargetDictionary
)
{
var
chunks
=
key
.
match
(
pattern
);
const
chunks
=
key
.
match
(
pattern
);
if
(
chunks
&&
chunks
.
length
>
1
)
{
var
name
=
chunks
[
1
];
const
name
=
chunks
[
1
];
if
(
!
frameRanges
[
name
]
)
frameRanges
[
name
]
=
{
start
:
Infinity
,
end
:
-
Infinity
};
var
range
=
frameRanges
[
name
];
const
range
=
frameRanges
[
name
];
if
(
i
<
range
.
start
)
range
.
start
=
i
;
if
(
i
>
range
.
end
)
range
.
end
=
i
;
if
(
!
firstAnimation
)
firstAnimation
=
name
;
...
...
@@ -69,19 +70,20 @@
}
for
(
var
name
in
frameRanges
)
{
for
(
const
name
in
frameRanges
)
{
var
range
=
frameRanges
[
name
];
const
range
=
frameRanges
[
name
];
this
.
createAnimation
(
name
,
range
.
start
,
range
.
end
,
fps
);
}
this
.
firstAnimation
=
firstAnimation
;
},
setAnimationDirectionForward
:
function
(
name
)
{
}
setAnimationDirectionForward
(
name
)
{
var
animation
=
this
.
animationsMap
[
name
];
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -90,10 +92,11 @@
}
},
setAnimationDirectionBackward
:
function
(
name
)
{
}
setAnimationDirectionBackward
(
name
)
{
var
animation
=
this
.
animationsMap
[
name
];
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -102,10 +105,11 @@
}
},
setAnimationFPS
:
function
(
name
,
fps
)
{
}
setAnimationFPS
(
name
,
fps
)
{
var
animation
=
this
.
animationsMap
[
name
];
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -114,10 +118,11 @@
}
},
setAnimationDuration
:
function
(
name
,
duration
)
{
}
var
animation
=
this
.
animationsMap
[
name
];
setAnimationDuration
(
name
,
duration
)
{
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -126,10 +131,11 @@
}
},
setAnimationWeight
:
function
(
name
,
weight
)
{
}
setAnimationWeight
(
name
,
weight
)
{
var
animation
=
this
.
animationsMap
[
name
];
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -137,10 +143,11 @@
}
},
setAnimationTime
:
function
(
name
,
time
)
{
}
setAnimationTime
(
name
,
time
)
{
var
animation
=
this
.
animationsMap
[
name
];
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -148,11 +155,12 @@
}
},
getAnimationTime
:
function
(
name
)
{
}
getAnimationTime
(
name
)
{
var
time
=
0
;
var
animation
=
this
.
animationsMap
[
name
];
let
time
=
0
;
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -162,11 +170,12 @@
return
time
;
},
getAnimationDuration
:
function
(
name
)
{
}
getAnimationDuration
(
name
)
{
var
duration
=
-
1
;
var
animation
=
this
.
animationsMap
[
name
];
let
duration
=
-
1
;
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -176,10 +185,11 @@
return
duration
;
},
playAnimation
:
function
(
name
)
{
}
var
animation
=
this
.
animationsMap
[
name
];
playAnimation
(
name
)
{
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -192,10 +202,11 @@
}
},
stopAnimation
:
function
(
name
)
{
}
stopAnimation
(
name
)
{
var
animation
=
this
.
animationsMap
[
name
];
const
animation
=
this
.
animationsMap
[
name
];
if
(
animation
)
{
...
...
@@ -203,14 +214,15 @@
}
},
update
:
function
(
delta
)
{
}
update
(
delta
)
{
for
(
var
i
=
0
,
il
=
this
.
animationsList
.
length
;
i
<
il
;
i
++
)
{
for
(
let
i
=
0
,
il
=
this
.
animationsList
.
length
;
i
<
il
;
i
++
)
{
var
animation
=
this
.
animationsList
[
i
];
const
animation
=
this
.
animationsList
[
i
];
if
(
!
animation
.
active
)
continue
;
var
frameTime
=
animation
.
duration
/
animation
.
length
;
const
frameTime
=
animation
.
duration
/
animation
.
length
;
animation
.
time
+=
animation
.
direction
*
delta
;
if
(
animation
.
mirroredLoop
)
{
...
...
@@ -242,8 +254,8 @@
}
var
keyframe
=
animation
.
start
+
THREE
.
MathUtils
.
clamp
(
Math
.
floor
(
animation
.
time
/
frameTime
),
0
,
animation
.
length
-
1
);
var
weight
=
animation
.
weight
;
const
keyframe
=
animation
.
start
+
THREE
.
MathUtils
.
clamp
(
Math
.
floor
(
animation
.
time
/
frameTime
),
0
,
animation
.
length
-
1
);
const
weight
=
animation
.
weight
;
if
(
keyframe
!==
animation
.
currentFrame
)
{
...
...
@@ -255,7 +267,7 @@
}
var
mix
=
animation
.
time
%
frameTime
/
frameTime
;
let
mix
=
animation
.
time
%
frameTime
/
frameTime
;
if
(
animation
.
directionBackwards
)
mix
=
1
-
mix
;
if
(
animation
.
currentFrame
!==
animation
.
lastFrame
)
{
...
...
@@ -272,7 +284,8 @@
}
}
}
);
}
THREE
.
MorphBlendMesh
=
MorphBlendMesh
;
...
...
examples/js/misc/RollerCoaster.js
浏览文件 @
3452a4e3
此差异已折叠。
点击以展开。
examples/jsm/misc/ConvexObjectBreaker.js
浏览文件 @
3452a4e3
...
...
@@ -35,40 +35,40 @@ import { ConvexGeometry } from '../geometries/ConvexGeometry.js';
*
*/
var
ConvexObjectBreaker
=
function
(
minSizeForBreak
,
smallDelta
)
{
const
_v1
=
new
Vector3
();
class
ConvexObjectBreaker
{
constructor
(
minSizeForBreak
=
1.4
,
smallDelta
=
0.0001
)
{
this
.
minSizeForBreak
=
minSizeForBreak
;
this
.
smallDelta
=
smallDelta
;
this
.
tempLine1
=
new
Line3
();
this
.
tempPlane1
=
new
Plane
();
this
.
tempPlane2
=
new
Plane
();
this
.
tempPlane_Cut
=
new
Plane
();
this
.
tempCM1
=
new
Vector3
();
this
.
tempCM2
=
new
Vector3
();
this
.
tempVector3
=
new
Vector3
();
this
.
tempVector3_2
=
new
Vector3
();
this
.
tempVector3_3
=
new
Vector3
();
this
.
tempVector3_P0
=
new
Vector3
();
this
.
tempVector3_P1
=
new
Vector3
();
this
.
tempVector3_P2
=
new
Vector3
();
this
.
tempVector3_N0
=
new
Vector3
();
this
.
tempVector3_N1
=
new
Vector3
();
this
.
tempVector3_AB
=
new
Vector3
();
this
.
tempVector3_CB
=
new
Vector3
();
this
.
tempResultObjects
=
{
object1
:
null
,
object2
:
null
};
this
.
segments
=
[];
const
n
=
30
*
30
;
for
(
let
i
=
0
;
i
<
n
;
i
++
)
this
.
segments
[
i
]
=
false
;
this
.
minSizeForBreak
=
minSizeForBreak
||
1.4
;
this
.
smallDelta
=
smallDelta
||
0.0001
;
this
.
tempLine1
=
new
Line3
();
this
.
tempPlane1
=
new
Plane
();
this
.
tempPlane2
=
new
Plane
();
this
.
tempPlane_Cut
=
new
Plane
();
this
.
tempCM1
=
new
Vector3
();
this
.
tempCM2
=
new
Vector3
();
this
.
tempVector3
=
new
Vector3
();
this
.
tempVector3_2
=
new
Vector3
();
this
.
tempVector3_3
=
new
Vector3
();
this
.
tempVector3_P0
=
new
Vector3
();
this
.
tempVector3_P1
=
new
Vector3
();
this
.
tempVector3_P2
=
new
Vector3
();
this
.
tempVector3_N0
=
new
Vector3
();
this
.
tempVector3_N1
=
new
Vector3
();
this
.
tempVector3_AB
=
new
Vector3
();
this
.
tempVector3_CB
=
new
Vector3
();
this
.
tempResultObjects
=
{
object1
:
null
,
object2
:
null
};
this
.
segments
=
[];
var
n
=
30
*
30
;
for
(
var
i
=
0
;
i
<
n
;
i
++
)
this
.
segments
[
i
]
=
false
;
};
ConvexObjectBreaker
.
prototype
=
{
constructor
:
ConvexObjectBreaker
,
}
prepareBreakableObject
:
function
(
object
,
mass
,
velocity
,
angularVelocity
,
breakable
)
{
prepareBreakableObject
(
object
,
mass
,
velocity
,
angularVelocity
,
breakable
)
{
// object is a Object3d (normally a Mesh), must have a BufferGeometry, and it must be convex.
// Its material property is propagated to its children (sub-pieces)
...
...
@@ -80,13 +80,13 @@ ConvexObjectBreaker.prototype = {
}
var
userData
=
object
.
userData
;
const
userData
=
object
.
userData
;
userData
.
mass
=
mass
;
userData
.
velocity
=
velocity
.
clone
();
userData
.
angularVelocity
=
angularVelocity
.
clone
();
userData
.
breakable
=
breakable
;
}
,
}
/*
* @param {int} maxRadialIterations Iterations for radial cuts.
...
...
@@ -94,19 +94,19 @@ ConvexObjectBreaker.prototype = {
*
* Returns the array of pieces
*/
subdivideByImpact
:
function
(
object
,
pointOfImpact
,
normal
,
maxRadialIterations
,
maxRandomIterations
)
{
subdivideByImpact
(
object
,
pointOfImpact
,
normal
,
maxRadialIterations
,
maxRandomIterations
)
{
var
debris
=
[];
const
debris
=
[];
var
tempPlane1
=
this
.
tempPlane1
;
var
tempPlane2
=
this
.
tempPlane2
;
const
tempPlane1
=
this
.
tempPlane1
;
const
tempPlane2
=
this
.
tempPlane2
;
this
.
tempVector3
.
addVectors
(
pointOfImpact
,
normal
);
tempPlane1
.
setFromCoplanarPoints
(
pointOfImpact
,
object
.
position
,
this
.
tempVector3
);
var
maxTotalIterations
=
maxRandomIterations
+
maxRadialIterations
;
const
maxTotalIterations
=
maxRandomIterations
+
maxRadialIterations
;
var
scope
=
this
;
const
scope
=
this
;
function
subdivideRadial
(
subObject
,
startAngle
,
endAngle
,
numIterations
)
{
...
...
@@ -118,7 +118,7 @@ ConvexObjectBreaker.prototype = {
}
var
angle
=
Math
.
PI
;
let
angle
=
Math
.
PI
;
if
(
numIterations
===
0
)
{
...
...
@@ -151,8 +151,8 @@ ConvexObjectBreaker.prototype = {
// Perform the cut
scope
.
cutByPlane
(
subObject
,
tempPlane2
,
scope
.
tempResultObjects
);
var
obj1
=
scope
.
tempResultObjects
.
object1
;
var
obj2
=
scope
.
tempResultObjects
.
object2
;
const
obj1
=
scope
.
tempResultObjects
.
object1
;
const
obj2
=
scope
.
tempResultObjects
.
object2
;
if
(
obj1
)
{
...
...
@@ -172,23 +172,23 @@ ConvexObjectBreaker.prototype = {
return
debris
;
}
,
}
cutByPlane
:
function
(
object
,
plane
,
output
)
{
cutByPlane
(
object
,
plane
,
output
)
{
// Returns breakable objects in output.object1 and output.object2 members, the resulting 2 pieces of the cut.
// object2 can be null if the plane doesn't cut the object.
// object1 can be null only in case of internal error
// Returned value is number of pieces, 0 for error.
var
geometry
=
object
.
geometry
;
var
coords
=
geometry
.
attributes
.
position
.
array
;
var
normals
=
geometry
.
attributes
.
normal
.
array
;
const
geometry
=
object
.
geometry
;
const
coords
=
geometry
.
attributes
.
position
.
array
;
const
normals
=
geometry
.
attributes
.
normal
.
array
;
var
numPoints
=
coords
.
length
/
3
;
var
numFaces
=
numPoints
/
3
;
const
numPoints
=
coords
.
length
/
3
;
let
numFaces
=
numPoints
/
3
;
var
indices
=
geometry
.
getIndex
();
let
indices
=
geometry
.
getIndex
();
if
(
indices
)
{
...
...
@@ -201,46 +201,46 @@ ConvexObjectBreaker.prototype = {
// vert = 0, 1 or 2.
var
idx
=
faceIdx
*
3
+
vert
;
const
idx
=
faceIdx
*
3
+
vert
;
return
indices
?
indices
[
idx
]
:
idx
;
}
var
points1
=
[];
var
points2
=
[];
const
points1
=
[];
const
points2
=
[];
var
delta
=
this
.
smallDelta
;
const
delta
=
this
.
smallDelta
;
// Reset segments mark
var
numPointPairs
=
numPoints
*
numPoints
;
for
(
var
i
=
0
;
i
<
numPointPairs
;
i
++
)
this
.
segments
[
i
]
=
false
;
const
numPointPairs
=
numPoints
*
numPoints
;
for
(
let
i
=
0
;
i
<
numPointPairs
;
i
++
)
this
.
segments
[
i
]
=
false
;
var
p0
=
this
.
tempVector3_P0
;
var
p1
=
this
.
tempVector3_P1
;
var
n0
=
this
.
tempVector3_N0
;
var
n1
=
this
.
tempVector3_N1
;
const
p0
=
this
.
tempVector3_P0
;
const
p1
=
this
.
tempVector3_P1
;
const
n0
=
this
.
tempVector3_N0
;
const
n1
=
this
.
tempVector3_N1
;
// Iterate through the faces to mark edges shared by coplanar faces
for
(
var
i
=
0
;
i
<
numFaces
-
1
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numFaces
-
1
;
i
++
)
{
var
a1
=
getVertexIndex
(
i
,
0
);
var
b1
=
getVertexIndex
(
i
,
1
);
var
c1
=
getVertexIndex
(
i
,
2
);
const
a1
=
getVertexIndex
(
i
,
0
);
const
b1
=
getVertexIndex
(
i
,
1
);
const
c1
=
getVertexIndex
(
i
,
2
);
// Assuming all 3 vertices have the same normal
n0
.
set
(
normals
[
a1
],
normals
[
a1
]
+
1
,
normals
[
a1
]
+
2
);
for
(
var
j
=
i
+
1
;
j
<
numFaces
;
j
++
)
{
for
(
let
j
=
i
+
1
;
j
<
numFaces
;
j
++
)
{
var
a2
=
getVertexIndex
(
j
,
0
);
var
b2
=
getVertexIndex
(
j
,
1
);
var
c2
=
getVertexIndex
(
j
,
2
);
const
a2
=
getVertexIndex
(
j
,
0
);
const
b2
=
getVertexIndex
(
j
,
1
);
const
c2
=
getVertexIndex
(
j
,
2
);
// Assuming all 3 vertices have the same normal
n1
.
set
(
normals
[
a2
],
normals
[
a2
]
+
1
,
normals
[
a2
]
+
2
);
var
coplanar
=
1
-
n0
.
dot
(
n1
)
<
delta
;
const
coplanar
=
1
-
n0
.
dot
(
n1
)
<
delta
;
if
(
coplanar
)
{
...
...
@@ -272,23 +272,23 @@ ConvexObjectBreaker.prototype = {
}
// Transform the plane to object local space
var
localPlane
=
this
.
tempPlane_Cut
;
const
localPlane
=
this
.
tempPlane_Cut
;
object
.
updateMatrix
();
ConvexObjectBreaker
.
transformPlaneToLocalSpace
(
plane
,
object
.
matrix
,
localPlane
);
// Iterate through the faces adding points to both pieces
for
(
var
i
=
0
;
i
<
numFaces
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numFaces
;
i
++
)
{
var
va
=
getVertexIndex
(
i
,
0
);
var
vb
=
getVertexIndex
(
i
,
1
);
var
vc
=
getVertexIndex
(
i
,
2
);
const
va
=
getVertexIndex
(
i
,
0
);
const
vb
=
getVertexIndex
(
i
,
1
);
const
vc
=
getVertexIndex
(
i
,
2
);
for
(
var
segment
=
0
;
segment
<
3
;
segment
++
)
{
for
(
let
segment
=
0
;
segment
<
3
;
segment
++
)
{
var
i0
=
segment
===
0
?
va
:
(
segment
===
1
?
vb
:
vc
);
var
i1
=
segment
===
0
?
vb
:
(
segment
===
1
?
vc
:
va
);
const
i0
=
segment
===
0
?
va
:
(
segment
===
1
?
vb
:
vc
);
const
i1
=
segment
===
0
?
vb
:
(
segment
===
1
?
vc
:
va
);
var
segmentState
=
this
.
segments
[
i0
*
numPoints
+
i1
];
const
segmentState
=
this
.
segments
[
i0
*
numPoints
+
i1
];
if
(
segmentState
)
continue
;
// The segment already has been processed in another face
...
...
@@ -300,9 +300,9 @@ ConvexObjectBreaker.prototype = {
p1
.
set
(
coords
[
3
*
i1
],
coords
[
3
*
i1
+
1
],
coords
[
3
*
i1
+
2
]
);
// mark: 1 for negative side, 2 for positive side, 3 for coplanar point
var
mark0
=
0
;
let
mark0
=
0
;
var
d
=
localPlane
.
distanceToPoint
(
p0
);
let
d
=
localPlane
.
distanceToPoint
(
p0
);
if
(
d
>
delta
)
{
...
...
@@ -323,9 +323,9 @@ ConvexObjectBreaker.prototype = {
}
// mark: 1 for negative side, 2 for positive side, 3 for coplanar point
var
mark1
=
0
;
let
mark1
=
0
;
var
d
=
localPlane
.
distanceToPoint
(
p1
);
d
=
localPlane
.
distanceToPoint
(
p1
);
if
(
d
>
delta
)
{
...
...
@@ -352,7 +352,7 @@ ConvexObjectBreaker.prototype = {
this
.
tempLine1
.
start
.
copy
(
p0
);
this
.
tempLine1
.
end
.
copy
(
p1
);
var
intersection
=
new
Vector3
();
let
intersection
=
new
Vector3
();
intersection
=
localPlane
.
intersectLine
(
this
.
tempLine1
,
intersection
);
if
(
intersection
===
null
)
{
...
...
@@ -375,21 +375,21 @@ ConvexObjectBreaker.prototype = {
}
// Calculate debris mass (very fast and imprecise):
var
newMass
=
object
.
userData
.
mass
*
0.5
;
const
newMass
=
object
.
userData
.
mass
*
0.5
;
// Calculate debris Center of Mass (again fast and imprecise)
this
.
tempCM1
.
set
(
0
,
0
,
0
);
var
radius1
=
0
;
var
numPoints1
=
points1
.
length
;
let
radius1
=
0
;
const
numPoints1
=
points1
.
length
;
if
(
numPoints1
>
0
)
{
for
(
var
i
=
0
;
i
<
numPoints1
;
i
++
)
this
.
tempCM1
.
add
(
points1
[
i
]
);
for
(
let
i
=
0
;
i
<
numPoints1
;
i
++
)
this
.
tempCM1
.
add
(
points1
[
i
]
);
this
.
tempCM1
.
divideScalar
(
numPoints1
);
for
(
var
i
=
0
;
i
<
numPoints1
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numPoints1
;
i
++
)
{
var
p
=
points1
[
i
];
const
p
=
points1
[
i
];
p
.
sub
(
this
.
tempCM1
);
radius1
=
Math
.
max
(
radius1
,
p
.
x
,
p
.
y
,
p
.
z
);
...
...
@@ -400,16 +400,16 @@ ConvexObjectBreaker.prototype = {
}
this
.
tempCM2
.
set
(
0
,
0
,
0
);
var
radius2
=
0
;
var
numPoints2
=
points2
.
length
;
let
radius2
=
0
;
const
numPoints2
=
points2
.
length
;
if
(
numPoints2
>
0
)
{
for
(
var
i
=
0
;
i
<
numPoints2
;
i
++
)
this
.
tempCM2
.
add
(
points2
[
i
]
);
for
(
let
i
=
0
;
i
<
numPoints2
;
i
++
)
this
.
tempCM2
.
add
(
points2
[
i
]
);
this
.
tempCM2
.
divideScalar
(
numPoints2
);
for
(
var
i
=
0
;
i
<
numPoints2
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numPoints2
;
i
++
)
{
var
p
=
points2
[
i
];
const
p
=
points2
[
i
];
p
.
sub
(
this
.
tempCM2
);
radius2
=
Math
.
max
(
radius2
,
p
.
x
,
p
.
y
,
p
.
z
);
...
...
@@ -419,10 +419,10 @@ ConvexObjectBreaker.prototype = {
}
var
object1
=
null
;
var
object2
=
null
;
let
object1
=
null
;
let
object2
=
null
;
var
numObjects
=
0
;
let
numObjects
=
0
;
if
(
numPoints1
>
4
)
{
...
...
@@ -455,78 +455,71 @@ ConvexObjectBreaker.prototype = {
}
};
static
transformFreeVector
(
v
,
m
)
{
ConvexObjectBreaker
.
transformFreeVector
=
function
(
v
,
m
)
{
// input:
// vector interpreted as a free vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
// input:
// vector interpreted as a free vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
const
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
const
e
=
m
.
elements
;
var
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
var
e
=
m
.
elements
;
v
.
x
=
e
[
0
]
*
x
+
e
[
4
]
*
y
+
e
[
8
]
*
z
;
v
.
y
=
e
[
1
]
*
x
+
e
[
5
]
*
y
+
e
[
9
]
*
z
;
v
.
z
=
e
[
2
]
*
x
+
e
[
6
]
*
y
+
e
[
10
]
*
z
;
v
.
x
=
e
[
0
]
*
x
+
e
[
4
]
*
y
+
e
[
8
]
*
z
;
v
.
y
=
e
[
1
]
*
x
+
e
[
5
]
*
y
+
e
[
9
]
*
z
;
v
.
z
=
e
[
2
]
*
x
+
e
[
6
]
*
y
+
e
[
10
]
*
z
;
return
v
;
return
v
;
};
ConvexObjectBreaker
.
transformFreeVectorInverse
=
function
(
v
,
m
)
{
// input:
// vector interpreted as a free vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
}
var
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
var
e
=
m
.
elements
;
static
transformFreeVectorInverse
(
v
,
m
)
{
v
.
x
=
e
[
0
]
*
x
+
e
[
1
]
*
y
+
e
[
2
]
*
z
;
v
.
y
=
e
[
4
]
*
x
+
e
[
5
]
*
y
+
e
[
6
]
*
z
;
v
.
z
=
e
[
8
]
*
x
+
e
[
9
]
*
y
+
e
[
10
]
*
z
;
// input:
// vector interpreted as a free vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
return
v
;
const
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
const
e
=
m
.
elements
;
};
v
.
x
=
e
[
0
]
*
x
+
e
[
1
]
*
y
+
e
[
2
]
*
z
;
v
.
y
=
e
[
4
]
*
x
+
e
[
5
]
*
y
+
e
[
6
]
*
z
;
v
.
z
=
e
[
8
]
*
x
+
e
[
9
]
*
y
+
e
[
10
]
*
z
;
ConvexObjectBreaker
.
transformTiedVectorInverse
=
function
(
v
,
m
)
{
return
v
;
// input:
// vector interpreted as a tied (ordinary) vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
}
var
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
var
e
=
m
.
elements
;
static
transformTiedVectorInverse
(
v
,
m
)
{
v
.
x
=
e
[
0
]
*
x
+
e
[
1
]
*
y
+
e
[
2
]
*
z
-
e
[
12
];
v
.
y
=
e
[
4
]
*
x
+
e
[
5
]
*
y
+
e
[
6
]
*
z
-
e
[
13
];
v
.
z
=
e
[
8
]
*
x
+
e
[
9
]
*
y
+
e
[
10
]
*
z
-
e
[
14
];
// input:
// vector interpreted as a tied (ordinary) vector
// THREE.Matrix4 orthogonal matrix (matrix without scale)
return
v
;
const
x
=
v
.
x
,
y
=
v
.
y
,
z
=
v
.
z
;
const
e
=
m
.
elements
;
};
v
.
x
=
e
[
0
]
*
x
+
e
[
1
]
*
y
+
e
[
2
]
*
z
-
e
[
12
];
v
.
y
=
e
[
4
]
*
x
+
e
[
5
]
*
y
+
e
[
6
]
*
z
-
e
[
13
];
v
.
z
=
e
[
8
]
*
x
+
e
[
9
]
*
y
+
e
[
10
]
*
z
-
e
[
14
];
ConvexObjectBreaker
.
transformPlaneToLocalSpace
=
function
()
{
return
v
;
var
v1
=
new
Vector3
();
}
return
function
transformPlaneToLocalSpace
(
plane
,
m
,
resultPlane
)
{
static
transformPlaneToLocalSpace
(
plane
,
m
,
resultPlane
)
{
resultPlane
.
normal
.
copy
(
plane
.
normal
);
resultPlane
.
constant
=
plane
.
constant
;
var
referencePoint
=
ConvexObjectBreaker
.
transformTiedVectorInverse
(
plane
.
coplanarPoint
(
v1
),
m
);
const
referencePoint
=
ConvexObjectBreaker
.
transformTiedVectorInverse
(
plane
.
coplanarPoint
(
_
v1
),
m
);
ConvexObjectBreaker
.
transformFreeVectorInverse
(
resultPlane
.
normal
,
m
);
// recalculate constant (like in setFromNormalAndCoplanarPoint)
resultPlane
.
constant
=
-
referencePoint
.
dot
(
resultPlane
.
normal
);
}
};
}();
}
export
{
ConvexObjectBreaker
};
examples/jsm/misc/GPUComputationRenderer.js
浏览文件 @
3452a4e3
...
...
@@ -40,16 +40,16 @@ import {
* // Initialization...
*
* // Create computation renderer
*
var
gpuCompute = new GPUComputationRenderer( 1024, 1024, renderer );
*
const
gpuCompute = new GPUComputationRenderer( 1024, 1024, renderer );
*
* // Create initial state float textures
*
var
pos0 = gpuCompute.createTexture();
*
var
vel0 = gpuCompute.createTexture();
*
const
pos0 = gpuCompute.createTexture();
*
const
vel0 = gpuCompute.createTexture();
* // and fill in here the texture data...
*
* // Add texture variables
*
var
velVar = gpuCompute.addVariable( "textureVelocity", fragmentShaderVel, pos0 );
*
var
posVar = gpuCompute.addVariable( "texturePosition", fragmentShaderPos, vel0 );
*
const
velVar = gpuCompute.addVariable( "textureVelocity", fragmentShaderVel, pos0 );
*
const
posVar = gpuCompute.addVariable( "texturePosition", fragmentShaderPos, vel0 );
*
* // Add variable dependencies
* gpuCompute.setVariableDependencies( velVar, [ velVar, posVar ] );
...
...
@@ -59,7 +59,7 @@ import {
* velVar.material.uniforms.time = { value: 0.0 };
*
* // Check for completeness
*
var
error = gpuCompute.init();
*
const
error = gpuCompute.init();
* if ( error !== null ) {
* console.error( error );
* }
...
...
@@ -81,19 +81,19 @@ import {
* Also, you can use utility functions to create ShaderMaterial and perform computations (rendering between textures)
* Note that the shaders can have multiple input textures.
*
*
var
myFilter1 = gpuCompute.createShaderMaterial( myFilterFragmentShader1, { theTexture: { value: null } } );
*
var
myFilter2 = gpuCompute.createShaderMaterial( myFilterFragmentShader2, { theTexture: { value: null } } );
*
const
myFilter1 = gpuCompute.createShaderMaterial( myFilterFragmentShader1, { theTexture: { value: null } } );
*
const
myFilter2 = gpuCompute.createShaderMaterial( myFilterFragmentShader2, { theTexture: { value: null } } );
*
*
var
inputTexture = gpuCompute.createTexture();
*
const
inputTexture = gpuCompute.createTexture();
*
* // Fill in here inputTexture...
*
* myFilter1.uniforms.theTexture.value = inputTexture;
*
*
var
myRenderTarget = gpuCompute.createRenderTarget();
*
const
myRenderTarget = gpuCompute.createRenderTarget();
* myFilter2.uniforms.theTexture.value = myRenderTarget.texture;
*
*
var
outputRenderTarget = gpuCompute.createRenderTarget();
*
const
outputRenderTarget = gpuCompute.createRenderTarget();
*
* // Now use the output texture where you want:
* myMaterial.uniforms.map.value = outputRenderTarget.texture;
...
...
@@ -109,295 +109,301 @@ import {
* @param {WebGLRenderer} renderer The renderer
*/
var
GPUComputationRenderer
=
function
(
sizeX
,
sizeY
,
renderer
)
{
class
GPUComputationRenderer
{
this
.
variables
=
[];
constructor
(
sizeX
,
sizeY
,
renderer
)
{
this
.
currentTextureIndex
=
0
;
this
.
variables
=
[]
;
var
dataType
=
FloatType
;
this
.
currentTextureIndex
=
0
;
var
scene
=
new
Scene
()
;
let
dataType
=
FloatType
;
var
camera
=
new
Camera
();
camera
.
position
.
z
=
1
;
const
scene
=
new
Scene
();
var
passThruUniforms
=
{
passThruTexture
:
{
value
:
null
}
};
const
camera
=
new
Camera
();
camera
.
position
.
z
=
1
;
var
passThruShader
=
createShaderMaterial
(
getPassThroughFragmentShader
(),
passThruUniforms
);
const
passThruUniforms
=
{
passThruTexture
:
{
value
:
null
}
};
var
mesh
=
new
Mesh
(
new
PlaneGeometry
(
2
,
2
),
passThruShader
);
scene
.
add
(
mesh
);
const
passThruShader
=
createShaderMaterial
(
getPassThroughFragmentShader
(),
passThruUniforms
);
const
mesh
=
new
Mesh
(
new
PlaneGeometry
(
2
,
2
),
passThruShader
);
scene
.
add
(
mesh
);
this
.
setDataType
=
function
(
type
)
{
dataType
=
type
;
return
this
;
this
.
setDataType
=
function
(
type
)
{
};
dataType
=
type
;
return
this
;
this
.
addVariable
=
function
(
variableName
,
computeFragmentShader
,
initialValueTexture
)
{
};
var
material
=
this
.
createShaderMaterial
(
computeFragmentShader
);
this
.
addVariable
=
function
(
variableName
,
computeFragmentShader
,
initialValueTexture
)
{
var
variable
=
{
name
:
variableName
,
initialValueTexture
:
initialValueTexture
,
material
:
material
,
dependencies
:
null
,
renderTargets
:
[],
wrapS
:
null
,
wrapT
:
null
,
minFilter
:
NearestFilter
,
magFilter
:
NearestFilter
};
const
material
=
this
.
createShaderMaterial
(
computeFragmentShader
);
const
variable
=
{
name
:
variableName
,
initialValueTexture
:
initialValueTexture
,
material
:
material
,
dependencies
:
null
,
renderTargets
:
[],
wrapS
:
null
,
wrapT
:
null
,
minFilter
:
NearestFilter
,
magFilter
:
NearestFilter
};
this
.
variables
.
push
(
variable
);
this
.
variables
.
push
(
variable
);
return
variable
;
return
variable
;
};
};
this
.
setVariableDependencies
=
function
(
variable
,
dependencies
)
{
this
.
setVariableDependencies
=
function
(
variable
,
dependencies
)
{
variable
.
dependencies
=
dependencies
;
variable
.
dependencies
=
dependencies
;
};
};
this
.
init
=
function
()
{
this
.
init
=
function
()
{
if
(
renderer
.
capabilities
.
isWebGL2
===
false
&&
renderer
.
extensions
.
has
(
'
OES_texture_float
'
)
===
false
)
{
if
(
renderer
.
capabilities
.
isWebGL2
===
false
&&
renderer
.
extensions
.
has
(
'
OES_texture_float
'
)
===
false
)
{
return
'
No OES_texture_float support for float textures.
'
;
return
'
No OES_texture_float support for float textures.
'
;
}
}
if
(
renderer
.
capabilities
.
maxVertexTextures
===
0
)
{
if
(
renderer
.
capabilities
.
maxVertexTextures
===
0
)
{
return
'
No support for vertex shader textures.
'
;
return
'
No support for vertex shader textures.
'
;
}
}
for
(
let
i
=
0
;
i
<
this
.
variables
.
length
;
i
++
)
{
const
variable
=
this
.
variables
[
i
];
for
(
var
i
=
0
;
i
<
this
.
variables
.
length
;
i
++
)
{
// Creates rendertargets and initialize them with input texture
variable
.
renderTargets
[
0
]
=
this
.
createRenderTarget
(
sizeX
,
sizeY
,
variable
.
wrapS
,
variable
.
wrapT
,
variable
.
minFilter
,
variable
.
magFilter
);
variable
.
renderTargets
[
1
]
=
this
.
createRenderTarget
(
sizeX
,
sizeY
,
variable
.
wrapS
,
variable
.
wrapT
,
variable
.
minFilter
,
variable
.
magFilter
);
this
.
renderTexture
(
variable
.
initialValueTexture
,
variable
.
renderTargets
[
0
]
);
this
.
renderTexture
(
variable
.
initialValueTexture
,
variable
.
renderTargets
[
1
]
);
var
variable
=
this
.
variables
[
i
];
// Adds dependencies uniforms to the ShaderMaterial
const
material
=
variable
.
material
;
const
uniforms
=
material
.
uniforms
;
// Creates rendertargets and initialize them with input texture
variable
.
renderTargets
[
0
]
=
this
.
createRenderTarget
(
sizeX
,
sizeY
,
variable
.
wrapS
,
variable
.
wrapT
,
variable
.
minFilter
,
variable
.
magFilter
);
variable
.
renderTargets
[
1
]
=
this
.
createRenderTarget
(
sizeX
,
sizeY
,
variable
.
wrapS
,
variable
.
wrapT
,
variable
.
minFilter
,
variable
.
magFilter
);
this
.
renderTexture
(
variable
.
initialValueTexture
,
variable
.
renderTargets
[
0
]
);
this
.
renderTexture
(
variable
.
initialValueTexture
,
variable
.
renderTargets
[
1
]
);
if
(
variable
.
dependencies
!==
null
)
{
// Adds dependencies uniforms to the ShaderMaterial
var
material
=
variable
.
material
;
var
uniforms
=
material
.
uniforms
;
for
(
let
d
=
0
;
d
<
variable
.
dependencies
.
length
;
d
++
)
{
if
(
variable
.
dependencies
!==
null
)
{
const
depVar
=
variable
.
dependencies
[
d
];
for
(
var
d
=
0
;
d
<
variable
.
dependencies
.
length
;
d
++
)
{
if
(
depVar
.
name
!==
variable
.
name
)
{
var
depVar
=
variable
.
dependencies
[
d
];
// Checks if variable exists
let
found
=
false
;
if
(
depVar
.
name
!==
variable
.
name
)
{
for
(
let
j
=
0
;
j
<
this
.
variables
.
length
;
j
++
)
{
// Checks if variable exists
var
found
=
false
;
for
(
var
j
=
0
;
j
<
this
.
variables
.
length
;
j
++
)
{
if
(
depVar
.
name
===
this
.
variables
[
j
].
name
)
{
if
(
depVar
.
name
===
this
.
variables
[
j
].
name
)
{
found
=
true
;
break
;
found
=
true
;
break
;
}
}
}
if
(
!
found
)
{
if
(
!
found
)
{
return
'
Variable dependency not found. Variable=
'
+
variable
.
name
+
'
, dependency=
'
+
depVar
.
name
;
return
'
Variable dependency not found. Variable=
'
+
variable
.
name
+
'
, dependency=
'
+
depVar
.
name
;
}
}
}
uniforms
[
depVar
.
name
]
=
{
value
:
null
};
uniforms
[
depVar
.
name
]
=
{
value
:
null
}
;
material
.
fragmentShader
=
'
\n
uniform sampler2D
'
+
depVar
.
name
+
'
;
\n
'
+
material
.
fragmentShader
;
material
.
fragmentShader
=
'
\n
uniform sampler2D
'
+
depVar
.
name
+
'
;
\n
'
+
material
.
fragmentShader
;
}
}
}
}
this
.
currentTextureIndex
=
0
;
this
.
currentTextureIndex
=
0
;
return
null
;
return
null
;
}
;
};
this
.
compute
=
function
()
{
this
.
compute
=
function
()
{
const
currentTextureIndex
=
this
.
currentTextureIndex
;
const
nextTextureIndex
=
this
.
currentTextureIndex
===
0
?
1
:
0
;
var
currentTextureIndex
=
this
.
currentTextureIndex
;
var
nextTextureIndex
=
this
.
currentTextureIndex
===
0
?
1
:
0
;
for
(
let
i
=
0
,
il
=
this
.
variables
.
length
;
i
<
il
;
i
++
)
{
for
(
var
i
=
0
,
il
=
this
.
variables
.
length
;
i
<
il
;
i
++
)
{
const
variable
=
this
.
variables
[
i
];
var
variable
=
this
.
variables
[
i
];
// Sets texture dependencies uniforms
if
(
variable
.
dependencies
!==
null
)
{
// Sets texture dependencies uniforms
if
(
variable
.
dependencies
!==
null
)
{
const
uniforms
=
variable
.
material
.
uniforms
;
var
uniforms
=
variable
.
material
.
uniforms
;
for
(
var
d
=
0
,
dl
=
variable
.
dependencies
.
length
;
d
<
dl
;
d
++
)
{
for
(
let
d
=
0
,
dl
=
variable
.
dependencies
.
length
;
d
<
dl
;
d
++
)
{
var
depVar
=
variable
.
dependencies
[
d
];
const
depVar
=
variable
.
dependencies
[
d
];
uniforms
[
depVar
.
name
].
value
=
depVar
.
renderTargets
[
currentTextureIndex
].
texture
;
uniforms
[
depVar
.
name
].
value
=
depVar
.
renderTargets
[
currentTextureIndex
].
texture
;
}
}
}
// Performs the computation for this variable
this
.
doRenderTarget
(
variable
.
material
,
variable
.
renderTargets
[
nextTextureIndex
]
);
// Performs the computation for this variable
this
.
doRenderTarget
(
variable
.
material
,
variable
.
renderTargets
[
nextTextureIndex
]
);
}
}
this
.
currentTextureIndex
=
nextTextureIndex
;
this
.
currentTextureIndex
=
nextTextureIndex
;
}
;
};
this
.
getCurrentRenderTarget
=
function
(
variable
)
{
this
.
getCurrentRenderTarget
=
function
(
variable
)
{
return
variable
.
renderTargets
[
this
.
currentTextureIndex
];
return
variable
.
renderTargets
[
this
.
currentTextureIndex
]
;
}
;
};
this
.
getAlternateRenderTarget
=
function
(
variable
)
{
this
.
getAlternateRenderTarget
=
function
(
variable
)
{
return
variable
.
renderTargets
[
this
.
currentTextureIndex
===
0
?
1
:
0
];
return
variable
.
renderTargets
[
this
.
currentTextureIndex
===
0
?
1
:
0
]
;
}
;
};
function
addResolutionDefine
(
materialShader
)
{
function
addResolutionDefine
(
materialShader
)
{
materialShader
.
defines
.
resolution
=
'
vec2(
'
+
sizeX
.
toFixed
(
1
)
+
'
,
'
+
sizeY
.
toFixed
(
1
)
+
'
)
'
;
materialShader
.
defines
.
resolution
=
'
vec2(
'
+
sizeX
.
toFixed
(
1
)
+
'
,
'
+
sizeY
.
toFixed
(
1
)
+
'
)
'
;
}
}
this
.
addResolutionDefine
=
addResolutionDefine
;
this
.
addResolutionDefine
=
addResolutionDefine
;
// The following functions can be used to compute things manually
// The following functions can be used to compute things manually
function
createShaderMaterial
(
computeFragmentShader
,
uniforms
)
{
function
createShaderMaterial
(
computeFragmentShader
,
uniforms
)
{
uniforms
=
uniforms
||
{};
uniforms
=
uniforms
||
{};
const
material
=
new
ShaderMaterial
(
{
uniforms
:
uniforms
,
vertexShader
:
getPassThroughVertexShader
(),
fragmentShader
:
computeFragmentShader
}
);
var
material
=
new
ShaderMaterial
(
{
uniforms
:
uniforms
,
vertexShader
:
getPassThroughVertexShader
(),
fragmentShader
:
computeFragmentShader
}
);
addResolutionDefine
(
material
);
addResolutionDefine
(
material
)
;
return
material
;
return
material
;
}
}
this
.
createShaderMaterial
=
createShaderMaterial
;
this
.
createShaderMaterial
=
createShaderMaterial
;
this
.
createRenderTarget
=
function
(
sizeXTexture
,
sizeYTexture
,
wrapS
,
wrapT
,
minFilter
,
magFilter
)
{
this
.
createRenderTarget
=
function
(
sizeXTexture
,
sizeYTexture
,
wrapS
,
wrapT
,
minFilter
,
magFilter
)
{
sizeXTexture
=
sizeXTexture
||
sizeX
;
sizeYTexture
=
sizeYTexture
||
sizeY
;
sizeXTexture
=
sizeXTexture
||
sizeX
;
sizeYTexture
=
sizeYTexture
||
sizeY
;
wrapS
=
wrapS
||
ClampToEdgeWrapping
;
wrapT
=
wrapT
||
ClampToEdgeWrapping
;
wrapS
=
wrapS
||
ClampToEdgeWrapping
;
wrapT
=
wrapT
||
ClampToEdgeWrapping
;
minFilter
=
minFilter
||
NearestFilter
;
magFilter
=
magFilter
||
NearestFilter
;
minFilter
=
minFilter
||
NearestFilter
;
magFilter
=
magFilter
||
NearestFilter
;
const
renderTarget
=
new
WebGLRenderTarget
(
sizeXTexture
,
sizeYTexture
,
{
wrapS
:
wrapS
,
wrapT
:
wrapT
,
minFilter
:
minFilter
,
magFilter
:
magFilter
,
format
:
RGBAFormat
,
type
:
dataType
,
depthBuffer
:
false
}
);
var
renderTarget
=
new
WebGLRenderTarget
(
sizeXTexture
,
sizeYTexture
,
{
wrapS
:
wrapS
,
wrapT
:
wrapT
,
minFilter
:
minFilter
,
magFilter
:
magFilter
,
format
:
RGBAFormat
,
type
:
dataType
,
depthBuffer
:
false
}
);
return
renderTarget
;
return
renderTarget
;
}
;
};
this
.
createTexture
=
function
()
{
this
.
createTexture
=
function
()
{
const
data
=
new
Float32Array
(
sizeX
*
sizeY
*
4
);
return
new
DataTexture
(
data
,
sizeX
,
sizeY
,
RGBAFormat
,
FloatType
);
var
data
=
new
Float32Array
(
sizeX
*
sizeY
*
4
);
return
new
DataTexture
(
data
,
sizeX
,
sizeY
,
RGBAFormat
,
FloatType
);
};
};
this
.
renderTexture
=
function
(
input
,
output
)
{
this
.
renderTexture
=
function
(
input
,
output
)
{
// Takes a texture, and render out in rendertarget
// input = Texture
// output = RenderTarget
// Takes a texture, and render out in rendertarget
// input = Texture
// output = RenderTarget
passThruUniforms
.
passThruTexture
.
value
=
input
;
passThruUniforms
.
passThruTexture
.
value
=
input
;
this
.
doRenderTarget
(
passThruShader
,
output
)
;
this
.
doRenderTarget
(
passThruShader
,
output
)
;
passThruUniforms
.
passThruTexture
.
value
=
null
;
passThruUniforms
.
passThruTexture
.
value
=
null
;
}
;
};
this
.
doRenderTarget
=
function
(
material
,
output
)
{
this
.
doRenderTarget
=
function
(
material
,
output
)
{
const
currentRenderTarget
=
renderer
.
getRenderTarget
();
var
currentRenderTarget
=
renderer
.
getRenderTarget
();
mesh
.
material
=
material
;
renderer
.
setRenderTarget
(
output
);
renderer
.
render
(
scene
,
camera
);
mesh
.
material
=
passThruShader
;
mesh
.
material
=
material
;
renderer
.
setRenderTarget
(
output
);
renderer
.
render
(
scene
,
camera
);
mesh
.
material
=
passThruShader
;
renderer
.
setRenderTarget
(
currentRenderTarget
);
renderer
.
setRenderTarget
(
currentRenderTarget
)
;
}
;
};
// Shaders
// Shaders
function
getPassThroughVertexShader
()
{
function
getPassThroughVertexShader
()
{
return
'
void main() {
\n
'
+
'
\n
'
+
'
gl_Position = vec4( position, 1.0 );
\n
'
+
'
\n
'
+
'
}
\n
'
;
return
'
void main() {
\n
'
+
'
\n
'
+
'
gl_Position = vec4( position, 1.0 );
\n
'
+
'
\n
'
+
'
}
\n
'
;
}
}
function
getPassThroughFragmentShader
()
{
function
getPassThroughFragmentShader
()
{
return
'
uniform sampler2D passThruTexture;
\n
'
+
'
\n
'
+
'
void main() {
\n
'
+
'
\n
'
+
'
vec2 uv = gl_FragCoord.xy / resolution.xy;
\n
'
+
'
\n
'
+
'
gl_FragColor = texture2D( passThruTexture, uv );
\n
'
+
'
\n
'
+
'
}
\n
'
;
return
'
uniform sampler2D passThruTexture;
\n
'
+
'
\n
'
+
'
void main() {
\n
'
+
'
\n
'
+
'
vec2 uv = gl_FragCoord.xy / resolution.xy;
\n
'
+
'
\n
'
+
'
gl_FragColor = texture2D( passThruTexture, uv );
\n
'
+
'
\n
'
+
'
}
\n
'
;
}
}
}
;
}
export
{
GPUComputationRenderer
};
examples/jsm/misc/Gyroscope.js
浏览文件 @
3452a4e3
...
...
@@ -4,26 +4,23 @@ import {
Vector3
}
from
'
../../../build/three.module.js
'
;
var
Gyroscope
=
function
()
{
const
_translationObject
=
new
Vector3
();
const
_quaternionObject
=
new
Quaternion
();
const
_scaleObject
=
new
Vector3
();
Object3D
.
call
(
this
);
const
_translationWorld
=
new
Vector3
();
const
_quaternionWorld
=
new
Quaternion
();
const
_scaleWorld
=
new
Vector3
();
};
class
Gyroscope
extends
Object3D
{
Gyroscope
.
prototype
=
Object
.
create
(
Object3D
.
prototype
);
Gyroscope
.
prototype
.
constructor
=
Gyroscope
;
constructor
()
{
Gyroscope
.
prototype
.
updateMatrixWorld
=
(
function
()
{
super
();
var
translationObject
=
new
Vector3
();
var
quaternionObject
=
new
Quaternion
();
var
scaleObject
=
new
Vector3
();
}
var
translationWorld
=
new
Vector3
();
var
quaternionWorld
=
new
Quaternion
();
var
scaleWorld
=
new
Vector3
();
return
function
updateMatrixWorld
(
force
)
{
updateMatrixWorld
(
force
)
{
this
.
matrixAutoUpdate
&&
this
.
updateMatrix
();
...
...
@@ -35,10 +32,10 @@ Gyroscope.prototype.updateMatrixWorld = ( function () {
this
.
matrixWorld
.
multiplyMatrices
(
this
.
parent
.
matrixWorld
,
this
.
matrix
);
this
.
matrixWorld
.
decompose
(
translationWorld
,
quaternionWorld
,
scaleWorld
);
this
.
matrix
.
decompose
(
translationObject
,
quaternionObject
,
scaleObject
);
this
.
matrixWorld
.
decompose
(
_translationWorld
,
_quaternionWorld
,
_
scaleWorld
);
this
.
matrix
.
decompose
(
_translationObject
,
_quaternionObject
,
_
scaleObject
);
this
.
matrixWorld
.
compose
(
translationWorld
,
quaternionObject
,
scaleWorld
);
this
.
matrixWorld
.
compose
(
_translationWorld
,
_quaternionObject
,
_
scaleWorld
);
}
else
{
...
...
@@ -56,14 +53,14 @@ Gyroscope.prototype.updateMatrixWorld = ( function () {
// update children
for
(
var
i
=
0
,
l
=
this
.
children
.
length
;
i
<
l
;
i
++
)
{
for
(
let
i
=
0
,
l
=
this
.
children
.
length
;
i
<
l
;
i
++
)
{
this
.
children
[
i
].
updateMatrixWorld
(
force
);
}
}
;
}
}
()
);
}
export
{
Gyroscope
};
examples/jsm/misc/MD2Character.js
浏览文件 @
3452a4e3
...
...
@@ -10,37 +10,89 @@ import {
}
from
'
../../../build/three.module.js
'
;
import
{
MD2Loader
}
from
'
../loaders/MD2Loader.js
'
;
var
MD2Character
=
function
()
{
class
MD2Character
{
var
scope
=
this
;
constructor
()
{
this
.
scale
=
1
;
this
.
animationFPS
=
6
;
this
.
scale
=
1
;
this
.
animationFPS
=
6
;
this
.
root
=
new
Object3D
();
this
.
root
=
new
Object3D
();
this
.
meshBody
=
null
;
this
.
meshWeapon
=
null
;
this
.
meshBody
=
null
;
this
.
meshWeapon
=
null
;
this
.
skinsBody
=
[];
this
.
skinsWeapon
=
[];
this
.
skinsBody
=
[];
this
.
skinsWeapon
=
[];
this
.
weapons
=
[];
this
.
weapons
=
[];
this
.
activeAnimation
=
null
;
this
.
activeAnimation
=
null
;
this
.
mixer
=
null
;
this
.
mixer
=
null
;
this
.
onLoadComplete
=
function
()
{};
this
.
onLoadComplete
=
function
()
{};
this
.
loadCounter
=
0
;
this
.
loadCounter
=
0
;
this
.
loadParts
=
function
(
config
)
{
}
loadParts
(
config
)
{
const
scope
=
this
;
function
createPart
(
geometry
,
skinMap
)
{
const
materialWireframe
=
new
MeshLambertMaterial
(
{
color
:
0xffaa00
,
wireframe
:
true
,
morphTargets
:
true
,
morphNormals
:
true
}
);
const
materialTexture
=
new
MeshLambertMaterial
(
{
color
:
0xffffff
,
wireframe
:
false
,
map
:
skinMap
,
morphTargets
:
true
,
morphNormals
:
true
}
);
//
const
mesh
=
new
Mesh
(
geometry
,
materialTexture
);
mesh
.
rotation
.
y
=
-
Math
.
PI
/
2
;
mesh
.
castShadow
=
true
;
mesh
.
receiveShadow
=
true
;
//
mesh
.
materialTexture
=
materialTexture
;
mesh
.
materialWireframe
=
materialWireframe
;
return
mesh
;
}
function
loadTextures
(
baseUrl
,
textureUrls
)
{
const
textureLoader
=
new
TextureLoader
();
const
textures
=
[];
for
(
let
i
=
0
;
i
<
textureUrls
.
length
;
i
++
)
{
textures
[
i
]
=
textureLoader
.
load
(
baseUrl
+
textureUrls
[
i
],
checkLoadingComplete
);
textures
[
i
].
mapping
=
UVMapping
;
textures
[
i
].
name
=
textureUrls
[
i
];
textures
[
i
].
encoding
=
sRGBEncoding
;
}
return
textures
;
}
function
checkLoadingComplete
()
{
scope
.
loadCounter
-=
1
;
if
(
scope
.
loadCounter
===
0
)
scope
.
onLoadComplete
();
}
this
.
loadCounter
=
config
.
weapons
.
length
*
2
+
config
.
skins
.
length
+
1
;
var
weaponsTextures
=
[];
for
(
var
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
weaponsTextures
[
i
]
=
config
.
weapons
[
i
][
1
];
const
weaponsTextures
=
[];
for
(
let
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
weaponsTextures
[
i
]
=
config
.
weapons
[
i
][
1
];
// SKINS
this
.
skinsBody
=
loadTextures
(
config
.
baseUrl
+
'
skins/
'
,
config
.
skins
);
...
...
@@ -48,16 +100,16 @@ var MD2Character = function () {
// BODY
var
loader
=
new
MD2Loader
();
const
loader
=
new
MD2Loader
();
loader
.
load
(
config
.
baseUrl
+
config
.
body
,
function
(
geo
)
{
var
boundingBox
=
new
Box3
();
const
boundingBox
=
new
Box3
();
boundingBox
.
setFromBufferAttribute
(
geo
.
attributes
.
position
);
scope
.
root
.
position
.
y
=
-
scope
.
scale
*
boundingBox
.
min
.
y
;
var
mesh
=
createPart
(
geo
,
scope
.
skinsBody
[
0
]
);
const
mesh
=
createPart
(
geo
,
scope
.
skinsBody
[
0
]
);
mesh
.
scale
.
set
(
scope
.
scale
,
scope
.
scale
,
scope
.
scale
);
scope
.
root
.
add
(
mesh
);
...
...
@@ -75,11 +127,11 @@ var MD2Character = function () {
// WEAPONS
var
generateCallback
=
function
(
index
,
name
)
{
const
generateCallback
=
function
(
index
,
name
)
{
return
function
(
geo
)
{
var
mesh
=
createPart
(
geo
,
scope
.
skinsWeapon
[
index
]
);
const
mesh
=
createPart
(
geo
,
scope
.
skinsWeapon
[
index
]
);
mesh
.
scale
.
set
(
scope
.
scale
,
scope
.
scale
,
scope
.
scale
);
mesh
.
visible
=
false
;
...
...
@@ -96,15 +148,15 @@ var MD2Character = function () {
};
for
(
var
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
{
loader
.
load
(
config
.
baseUrl
+
config
.
weapons
[
i
][
0
],
generateCallback
(
i
,
config
.
weapons
[
i
][
0
]
)
);
}
}
;
}
this
.
setPlaybackRate
=
function
(
rate
)
{
setPlaybackRate
(
rate
)
{
if
(
rate
!==
0
)
{
...
...
@@ -116,9 +168,9 @@ var MD2Character = function () {
}
}
;
}
this
.
setWireframe
=
function
(
wireframeEnabled
)
{
setWireframe
(
wireframeEnabled
)
{
if
(
wireframeEnabled
)
{
...
...
@@ -132,9 +184,9 @@ var MD2Character = function () {
}
}
;
}
this
.
setSkin
=
function
(
index
)
{
setSkin
(
index
)
{
if
(
this
.
meshBody
&&
this
.
meshBody
.
material
.
wireframe
===
false
)
{
...
...
@@ -142,26 +194,26 @@ var MD2Character = function () {
}
}
;
}
this
.
setWeapon
=
function
(
index
)
{
setWeapon
(
index
)
{
for
(
var
i
=
0
;
i
<
this
.
weapons
.
length
;
i
++
)
this
.
weapons
[
i
].
visible
=
false
;
for
(
let
i
=
0
;
i
<
this
.
weapons
.
length
;
i
++
)
this
.
weapons
[
i
].
visible
=
false
;
var
activeWeapon
=
this
.
weapons
[
index
];
const
activeWeapon
=
this
.
weapons
[
index
];
if
(
activeWeapon
)
{
activeWeapon
.
visible
=
true
;
this
.
meshWeapon
=
activeWeapon
;
scope
.
syncWeaponAnimation
();
this
.
syncWeaponAnimation
();
}
}
;
}
this
.
setAnimation
=
function
(
clipName
)
{
setAnimation
(
clipName
)
{
if
(
this
.
meshBody
)
{
...
...
@@ -172,7 +224,7 @@ var MD2Character = function () {
}
var
action
=
this
.
mixer
.
clipAction
(
clipName
,
this
.
meshBody
);
const
action
=
this
.
mixer
.
clipAction
(
clipName
,
this
.
meshBody
);
if
(
action
)
{
...
...
@@ -182,17 +234,17 @@ var MD2Character = function () {
}
scope
.
activeClipName
=
clipName
;
this
.
activeClipName
=
clipName
;
scope
.
syncWeaponAnimation
();
this
.
syncWeaponAnimation
();
}
;
}
this
.
syncWeaponAnimation
=
function
()
{
syncWeaponAnimation
()
{
var
clipName
=
scope
.
activeClipName
;
const
clipName
=
this
.
activeClipName
;
if
(
scope
.
meshWeapon
)
{
if
(
this
.
meshWeapon
)
{
if
(
this
.
meshWeapon
.
activeAction
)
{
...
...
@@ -201,7 +253,7 @@ var MD2Character = function () {
}
var
action
=
this
.
mixer
.
clipAction
(
clipName
,
this
.
meshWeapon
);
const
action
=
this
.
mixer
.
clipAction
(
clipName
,
this
.
meshWeapon
);
if
(
action
)
{
...
...
@@ -211,62 +263,14 @@ var MD2Character = function () {
}
};
this
.
update
=
function
(
delta
)
{
if
(
this
.
mixer
)
this
.
mixer
.
update
(
delta
);
};
function
loadTextures
(
baseUrl
,
textureUrls
)
{
var
textureLoader
=
new
TextureLoader
();
var
textures
=
[];
for
(
var
i
=
0
;
i
<
textureUrls
.
length
;
i
++
)
{
textures
[
i
]
=
textureLoader
.
load
(
baseUrl
+
textureUrls
[
i
],
checkLoadingComplete
);
textures
[
i
].
mapping
=
UVMapping
;
textures
[
i
].
name
=
textureUrls
[
i
];
textures
[
i
].
encoding
=
sRGBEncoding
;
}
return
textures
;
}
function
createPart
(
geometry
,
skinMap
)
{
var
materialWireframe
=
new
MeshLambertMaterial
(
{
color
:
0xffaa00
,
wireframe
:
true
,
morphTargets
:
true
,
morphNormals
:
true
}
);
var
materialTexture
=
new
MeshLambertMaterial
(
{
color
:
0xffffff
,
wireframe
:
false
,
map
:
skinMap
,
morphTargets
:
true
,
morphNormals
:
true
}
);
//
var
mesh
=
new
Mesh
(
geometry
,
materialTexture
);
mesh
.
rotation
.
y
=
-
Math
.
PI
/
2
;
mesh
.
castShadow
=
true
;
mesh
.
receiveShadow
=
true
;
//
mesh
.
materialTexture
=
materialTexture
;
mesh
.
materialWireframe
=
materialWireframe
;
return
mesh
;
}
function
checkLoadingComplete
()
{
scope
.
loadCounter
-=
1
;
update
(
delta
)
{
if
(
scope
.
loadCounter
===
0
)
scope
.
onLoadComplete
(
);
if
(
this
.
mixer
)
this
.
mixer
.
update
(
delta
);
}
}
;
}
export
{
MD2Character
};
examples/jsm/misc/MD2CharacterComplex.js
浏览文件 @
3452a4e3
...
...
@@ -10,97 +10,98 @@ import {
import
{
MD2Loader
}
from
'
../loaders/MD2Loader.js
'
;
import
{
MorphBlendMesh
}
from
'
../misc/MorphBlendMesh.js
'
;
var
MD2CharacterComplex
=
function
()
{
class
MD2CharacterComplex
{
var
scope
=
this
;
constructor
()
{
this
.
scale
=
1
;
this
.
scale
=
1
;
// animation parameters
// animation parameters
this
.
animationFPS
=
6
;
this
.
transitionFrames
=
15
;
this
.
animationFPS
=
6
;
this
.
transitionFrames
=
15
;
// movement model parameters
// movement model parameters
this
.
maxSpeed
=
275
;
this
.
maxReverseSpeed
=
-
275
;
this
.
maxSpeed
=
275
;
this
.
maxReverseSpeed
=
-
275
;
this
.
frontAcceleration
=
600
;
this
.
backAcceleration
=
600
;
this
.
frontAcceleration
=
600
;
this
.
backAcceleration
=
600
;
this
.
frontDecceleration
=
600
;
this
.
frontDecceleration
=
600
;
this
.
angularSpeed
=
2.5
;
this
.
angularSpeed
=
2.5
;
// rig
// rig
this
.
root
=
new
Object3D
();
this
.
root
=
new
Object3D
();
this
.
meshBody
=
null
;
this
.
meshWeapon
=
null
;
this
.
meshBody
=
null
;
this
.
meshWeapon
=
null
;
this
.
controls
=
null
;
this
.
controls
=
null
;
// skins
// skins
this
.
skinsBody
=
[];
this
.
skinsWeapon
=
[];
this
.
skinsBody
=
[];
this
.
skinsWeapon
=
[];
this
.
weapons
=
[];
this
.
weapons
=
[];
this
.
currentSkin
=
undefined
;
this
.
currentSkin
=
undefined
;
//
//
this
.
onLoadComplete
=
function
()
{};
this
.
onLoadComplete
=
function
()
{};
// internals
// internals
this
.
meshes
=
[];
this
.
animations
=
{};
this
.
meshes
=
[];
this
.
animations
=
{};
this
.
loadCounter
=
0
;
this
.
loadCounter
=
0
;
// internal movement control variables
// internal movement control variables
this
.
speed
=
0
;
this
.
bodyOrientation
=
0
;
this
.
speed
=
0
;
this
.
bodyOrientation
=
0
;
this
.
walkSpeed
=
this
.
maxSpeed
;
this
.
crouchSpeed
=
this
.
maxSpeed
*
0.5
;
this
.
walkSpeed
=
this
.
maxSpeed
;
this
.
crouchSpeed
=
this
.
maxSpeed
*
0.5
;
// internal animation parameters
// internal animation parameters
this
.
activeAnimation
=
null
;
this
.
oldAnimation
=
null
;
this
.
activeAnimation
=
null
;
this
.
oldAnimation
=
null
;
// API
// API
}
this
.
enableShadows
=
function
(
enable
)
{
enableShadows
(
enable
)
{
for
(
var
i
=
0
;
i
<
this
.
meshes
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
this
.
meshes
.
length
;
i
++
)
{
this
.
meshes
[
i
].
castShadow
=
enable
;
this
.
meshes
[
i
].
receiveShadow
=
enable
;
}
}
;
}
this
.
setVisible
=
function
(
enable
)
{
setVisible
(
enable
)
{
for
(
var
i
=
0
;
i
<
this
.
meshes
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
this
.
meshes
.
length
;
i
++
)
{
this
.
meshes
[
i
].
visible
=
enable
;
this
.
meshes
[
i
].
visible
=
enable
;
}
};
}
this
.
shareParts
=
function
(
original
)
{
shareParts
(
original
)
{
this
.
animations
=
original
.
animations
;
this
.
walkSpeed
=
original
.
walkSpeed
;
...
...
@@ -111,7 +112,7 @@ var MD2CharacterComplex = function () {
// BODY
var
mesh
=
createPart
(
original
.
meshBody
.
geometry
,
this
.
skinsBody
[
0
]
);
const
mesh
=
this
.
_
createPart
(
original
.
meshBody
.
geometry
,
this
.
skinsBody
[
0
]
);
mesh
.
scale
.
set
(
this
.
scale
,
this
.
scale
,
this
.
scale
);
this
.
root
.
position
.
y
=
original
.
root
.
position
.
y
;
...
...
@@ -123,9 +124,9 @@ var MD2CharacterComplex = function () {
// WEAPONS
for
(
var
i
=
0
;
i
<
original
.
weapons
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
original
.
weapons
.
length
;
i
++
)
{
var
meshWeapon
=
createPart
(
original
.
weapons
[
i
].
geometry
,
this
.
skinsWeapon
[
i
]
);
const
meshWeapon
=
this
.
_
createPart
(
original
.
weapons
[
i
].
geometry
,
this
.
skinsWeapon
[
i
]
);
meshWeapon
.
scale
.
set
(
this
.
scale
,
this
.
scale
,
this
.
scale
);
meshWeapon
.
visible
=
false
;
...
...
@@ -140,9 +141,36 @@ var MD2CharacterComplex = function () {
}
};
}
loadParts
(
config
)
{
const
scope
=
this
;
function
loadTextures
(
baseUrl
,
textureUrls
)
{
const
textureLoader
=
new
TextureLoader
();
const
textures
=
[];
for
(
let
i
=
0
;
i
<
textureUrls
.
length
;
i
++
)
{
textures
[
i
]
=
textureLoader
.
load
(
baseUrl
+
textureUrls
[
i
],
checkLoadingComplete
);
textures
[
i
].
mapping
=
UVMapping
;
textures
[
i
].
name
=
textureUrls
[
i
];
textures
[
i
].
encoding
=
sRGBEncoding
;
}
return
textures
;
}
function
checkLoadingComplete
()
{
this
.
loadParts
=
function
(
config
)
{
scope
.
loadCounter
-=
1
;
if
(
scope
.
loadCounter
===
0
)
scope
.
onLoadComplete
();
}
this
.
animations
=
config
.
animations
;
this
.
walkSpeed
=
config
.
walkSpeed
;
...
...
@@ -150,8 +178,8 @@ var MD2CharacterComplex = function () {
this
.
loadCounter
=
config
.
weapons
.
length
*
2
+
config
.
skins
.
length
+
1
;
var
weaponsTextures
=
[];
for
(
var
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
weaponsTextures
[
i
]
=
config
.
weapons
[
i
][
1
];
const
weaponsTextures
=
[];
for
(
let
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
weaponsTextures
[
i
]
=
config
.
weapons
[
i
][
1
];
// SKINS
...
...
@@ -160,16 +188,16 @@ var MD2CharacterComplex = function () {
// BODY
var
loader
=
new
MD2Loader
();
const
loader
=
new
MD2Loader
();
loader
.
load
(
config
.
baseUrl
+
config
.
body
,
function
(
geo
)
{
var
boundingBox
=
new
Box3
();
const
boundingBox
=
new
Box3
();
boundingBox
.
setFromBufferAttribute
(
geo
.
attributes
.
position
);
scope
.
root
.
position
.
y
=
-
scope
.
scale
*
boundingBox
.
min
.
y
;
var
mesh
=
createPart
(
geo
,
scope
.
skinsBody
[
0
]
);
const
mesh
=
scope
.
_
createPart
(
geo
,
scope
.
skinsBody
[
0
]
);
mesh
.
scale
.
set
(
scope
.
scale
,
scope
.
scale
,
scope
.
scale
);
scope
.
root
.
add
(
mesh
);
...
...
@@ -183,11 +211,11 @@ var MD2CharacterComplex = function () {
// WEAPONS
var
generateCallback
=
function
(
index
,
name
)
{
const
generateCallback
=
function
(
index
,
name
)
{
return
function
(
geo
)
{
var
mesh
=
createPart
(
geo
,
scope
.
skinsWeapon
[
index
]
);
const
mesh
=
scope
.
_
createPart
(
geo
,
scope
.
skinsWeapon
[
index
]
);
mesh
.
scale
.
set
(
scope
.
scale
,
scope
.
scale
,
scope
.
scale
);
mesh
.
visible
=
false
;
...
...
@@ -205,22 +233,22 @@ var MD2CharacterComplex = function () {
};
for
(
var
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
config
.
weapons
.
length
;
i
++
)
{
loader
.
load
(
config
.
baseUrl
+
config
.
weapons
[
i
][
0
],
generateCallback
(
i
,
config
.
weapons
[
i
][
0
]
)
);
}
}
;
}
this
.
setPlaybackRate
=
function
(
rate
)
{
setPlaybackRate
(
rate
)
{
if
(
this
.
meshBody
)
this
.
meshBody
.
duration
=
this
.
meshBody
.
baseDuration
/
rate
;
if
(
this
.
meshWeapon
)
this
.
meshWeapon
.
duration
=
this
.
meshWeapon
.
baseDuration
/
rate
;
}
;
}
this
.
setWireframe
=
function
(
wireframeEnabled
)
{
setWireframe
(
wireframeEnabled
)
{
if
(
wireframeEnabled
)
{
...
...
@@ -234,9 +262,9 @@ var MD2CharacterComplex = function () {
}
}
;
}
this
.
setSkin
=
function
(
index
)
{
setSkin
(
index
)
{
if
(
this
.
meshBody
&&
this
.
meshBody
.
material
.
wireframe
===
false
)
{
...
...
@@ -245,13 +273,13 @@ var MD2CharacterComplex = function () {
}
}
;
}
this
.
setWeapon
=
function
(
index
)
{
setWeapon
(
index
)
{
for
(
var
i
=
0
;
i
<
this
.
weapons
.
length
;
i
++
)
this
.
weapons
[
i
].
visible
=
false
;
for
(
let
i
=
0
;
i
<
this
.
weapons
.
length
;
i
++
)
this
.
weapons
[
i
].
visible
=
false
;
var
activeWeapon
=
this
.
weapons
[
index
];
const
activeWeapon
=
this
.
weapons
[
index
];
if
(
activeWeapon
)
{
...
...
@@ -267,9 +295,9 @@ var MD2CharacterComplex = function () {
}
}
;
}
this
.
setAnimation
=
function
(
animationName
)
{
setAnimation
(
animationName
)
{
if
(
animationName
===
this
.
activeAnimation
||
!
animationName
)
return
;
...
...
@@ -293,9 +321,9 @@ var MD2CharacterComplex = function () {
}
}
;
}
this
.
update
=
function
(
delta
)
{
update
(
delta
)
{
if
(
this
.
controls
)
this
.
updateMovementModel
(
delta
);
...
...
@@ -306,11 +334,11 @@ var MD2CharacterComplex = function () {
}
}
;
}
this
.
updateAnimations
=
function
(
delta
)
{
updateAnimations
(
delta
)
{
var
mix
=
1
;
let
mix
=
1
;
if
(
this
.
blendCounter
>
0
)
{
...
...
@@ -337,14 +365,14 @@ var MD2CharacterComplex = function () {
}
}
;
}
this
.
updateBehaviors
=
function
()
{
updateBehaviors
()
{
var
controls
=
this
.
controls
;
var
animations
=
this
.
animations
;
const
controls
=
this
.
controls
;
const
animations
=
this
.
animations
;
var
moveAnimation
,
idleAnimation
;
let
moveAnimation
,
idleAnimation
;
// crouch vs stand
...
...
@@ -446,11 +474,17 @@ var MD2CharacterComplex = function () {
}
}
;
}
this
.
updateMovementModel
=
function
(
delta
)
{
updateMovementModel
(
delta
)
{
var
controls
=
this
.
controls
;
function
exponentialEaseOut
(
k
)
{
return
k
===
1
?
1
:
-
Math
.
pow
(
2
,
-
10
*
k
)
+
1
;
}
const
controls
=
this
.
controls
;
// speed based on controls
...
...
@@ -465,7 +499,7 @@ var MD2CharacterComplex = function () {
// orientation based on controls
// (don't just stand while turning)
var
dir
=
1
;
const
dir
=
1
;
if
(
controls
.
moveLeft
)
{
...
...
@@ -487,12 +521,12 @@ var MD2CharacterComplex = function () {
if
(
this
.
speed
>
0
)
{
var
k
=
exponentialEaseOut
(
this
.
speed
/
this
.
maxSpeed
);
const
k
=
exponentialEaseOut
(
this
.
speed
/
this
.
maxSpeed
);
this
.
speed
=
MathUtils
.
clamp
(
this
.
speed
-
k
*
delta
*
this
.
frontDecceleration
,
0
,
this
.
maxSpeed
);
}
else
{
var
k
=
exponentialEaseOut
(
this
.
speed
/
this
.
maxReverseSpeed
);
const
k
=
exponentialEaseOut
(
this
.
speed
/
this
.
maxReverseSpeed
);
this
.
speed
=
MathUtils
.
clamp
(
this
.
speed
+
k
*
delta
*
this
.
backAcceleration
,
this
.
maxReverseSpeed
,
0
);
}
...
...
@@ -501,7 +535,7 @@ var MD2CharacterComplex = function () {
// displacement
var
forwardDelta
=
this
.
speed
*
delta
;
const
forwardDelta
=
this
.
speed
*
delta
;
this
.
root
.
position
.
x
+=
Math
.
sin
(
this
.
bodyOrientation
)
*
forwardDelta
;
this
.
root
.
position
.
z
+=
Math
.
cos
(
this
.
bodyOrientation
)
*
forwardDelta
;
...
...
@@ -510,36 +544,18 @@ var MD2CharacterComplex = function () {
this
.
root
.
rotation
.
y
=
this
.
bodyOrientation
;
};
// internal helpers
function
loadTextures
(
baseUrl
,
textureUrls
)
{
var
textureLoader
=
new
TextureLoader
();
var
textures
=
[];
for
(
var
i
=
0
;
i
<
textureUrls
.
length
;
i
++
)
{
textures
[
i
]
=
textureLoader
.
load
(
baseUrl
+
textureUrls
[
i
],
checkLoadingComplete
);
textures
[
i
].
mapping
=
UVMapping
;
textures
[
i
].
name
=
textureUrls
[
i
];
textures
[
i
].
encoding
=
sRGBEncoding
;
}
return
textures
;
}
function
createPart
(
geometry
,
skinMap
)
{
// internal
var
materialWireframe
=
new
MeshLambertMaterial
(
{
color
:
0xffaa00
,
wireframe
:
true
,
morphTargets
:
true
,
morphNormals
:
true
}
);
var
materialTexture
=
new
MeshLambertMaterial
(
{
color
:
0xffffff
,
wireframe
:
false
,
map
:
skinMap
,
morphTargets
:
true
,
morphNormals
:
true
}
);
_createPart
(
geometry
,
skinMap
)
{
const
materialWireframe
=
new
MeshLambertMaterial
(
{
color
:
0xffaa00
,
wireframe
:
true
,
morphTargets
:
true
,
morphNormals
:
true
}
);
const
materialTexture
=
new
MeshLambertMaterial
(
{
color
:
0xffffff
,
wireframe
:
false
,
map
:
skinMap
,
morphTargets
:
true
,
morphNormals
:
true
}
);
//
var
mesh
=
new
MorphBlendMesh
(
geometry
,
materialTexture
);
const
mesh
=
new
MorphBlendMesh
(
geometry
,
materialTexture
);
mesh
.
rotation
.
y
=
-
Math
.
PI
/
2
;
//
...
...
@@ -549,25 +565,12 @@ var MD2CharacterComplex = function () {
//
mesh
.
autoCreateAnimations
(
scope
.
animationFPS
);
mesh
.
autoCreateAnimations
(
this
.
animationFPS
);
return
mesh
;
}
function
checkLoadingComplete
()
{
scope
.
loadCounter
-=
1
;
if
(
scope
.
loadCounter
===
0
)
scope
.
onLoadComplete
();
}
function
exponentialEaseOut
(
k
)
{
return
k
===
1
?
1
:
-
Math
.
pow
(
2
,
-
10
*
k
)
+
1
;
}
};
}
export
{
MD2CharacterComplex
};
examples/jsm/misc/MorphAnimMesh.js
浏览文件 @
3452a4e3
...
...
@@ -4,71 +4,72 @@ import {
Mesh
}
from
'
../../../build/three.module.js
'
;
var
MorphAnimMesh
=
function
(
geometry
,
material
)
{
class
MorphAnimMesh
extends
Mesh
{
Mesh
.
call
(
this
,
geometry
,
material
);
constructor
(
geometry
,
material
)
{
this
.
type
=
'
MorphAnimMesh
'
;
super
(
geometry
,
material
)
;
this
.
mixer
=
new
AnimationMixer
(
this
);
this
.
activeAction
=
null
;
this
.
type
=
'
MorphAnimMesh
'
;
};
this
.
mixer
=
new
AnimationMixer
(
this
);
this
.
activeAction
=
null
;
MorphAnimMesh
.
prototype
=
Object
.
create
(
Mesh
.
prototype
);
MorphAnimMesh
.
prototype
.
constructor
=
MorphAnimMesh
;
}
MorphAnimMesh
.
prototype
.
setDirectionForward
=
function
()
{
setDirectionForward
()
{
this
.
mixer
.
timeScale
=
1.0
;
this
.
mixer
.
timeScale
=
1.0
;
};
}
MorphAnimMesh
.
prototype
.
setDirectionBackward
=
function
()
{
setDirectionBackward
()
{
this
.
mixer
.
timeScale
=
-
1.0
;
this
.
mixer
.
timeScale
=
-
1.0
;
};
}
MorphAnimMesh
.
prototype
.
playAnimation
=
function
(
label
,
fps
)
{
playAnimation
(
label
,
fps
)
{
if
(
this
.
activeAction
)
{
if
(
this
.
activeAction
)
{
this
.
activeAction
.
stop
();
this
.
activeAction
=
null
;
this
.
activeAction
.
stop
();
this
.
activeAction
=
null
;
}
}
const
clip
=
AnimationClip
.
findByName
(
this
,
label
);
var
clip
=
AnimationClip
.
findByName
(
this
,
label
);
if
(
clip
)
{
if
(
clip
)
{
const
action
=
this
.
mixer
.
clipAction
(
clip
);
action
.
timeScale
=
(
clip
.
tracks
.
length
*
fps
)
/
clip
.
duration
;
this
.
activeAction
=
action
.
play
();
var
action
=
this
.
mixer
.
clipAction
(
clip
);
action
.
timeScale
=
(
clip
.
tracks
.
length
*
fps
)
/
clip
.
duration
;
this
.
activeAction
=
action
.
play
();
}
else
{
}
else
{
throw
new
Error
(
'
THREE.MorphAnimMesh: animations[
'
+
label
+
'
] undefined in .playAnimation()
'
);
throw
new
Error
(
'
THREE.MorphAnimMesh: animations[
'
+
label
+
'
] undefined in .playAnimation()
'
);
}
}
};
updateAnimation
(
delta
)
{
MorphAnimMesh
.
prototype
.
updateAnimation
=
function
(
delta
)
{
this
.
mixer
.
update
(
delta
);
this
.
mixer
.
update
(
delta
);
}
};
copy
(
source
)
{
MorphAnimMesh
.
prototype
.
copy
=
function
(
source
)
{
super
.
copy
(
source
);
Mesh
.
prototype
.
copy
.
call
(
this
,
source
);
this
.
mixer
=
new
AnimationMixer
(
this
);
this
.
mixer
=
new
AnimationMixer
(
this
)
;
return
this
;
return
this
;
}
}
;
}
export
{
MorphAnimMesh
};
examples/jsm/misc/MorphBlendMesh.js
浏览文件 @
3452a4e3
此差异已折叠。
点击以展开。
examples/jsm/misc/RollerCoaster.js
浏览文件 @
3452a4e3
此差异已折叠。
点击以展开。
examples/webgl_loader_md2_control.html
浏览文件 @
3452a4e3
...
...
@@ -145,7 +145,6 @@
cameraControls
=
new
OrbitControls
(
camera
,
renderer
.
domElement
);
cameraControls
.
target
.
set
(
0
,
50
,
0
);
cameraControls
.
enableKeys
=
false
;
cameraControls
.
update
();
// CHARACTER
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录