Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
39873e0f
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,发现更多精彩内容 >>
提交
39873e0f
编写于
5月 27, 2019
作者:
M
Mugen87
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
JSM: Added module and TS file for DecalGeometry.
上级
5a53bc40
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
577 addition
and
210 deletion
+577
-210
docs/manual/en/introduction/Import-via-modules.html
docs/manual/en/introduction/Import-via-modules.html
+1
-0
examples/js/geometries/DecalGeometry.js
examples/js/geometries/DecalGeometry.js
+202
-210
examples/jsm/geometries/DecalGeometry.d.ts
examples/jsm/geometries/DecalGeometry.d.ts
+15
-0
examples/jsm/geometries/DecalGeometry.js
examples/jsm/geometries/DecalGeometry.js
+358
-0
utils/modularize.js
utils/modularize.js
+1
-0
未找到文件。
docs/manual/en/introduction/Import-via-modules.html
浏览文件 @
39873e0f
...
...
@@ -127,6 +127,7 @@
<li>
geometries
<ul>
<li>
BoxLineGeometry
</li>
<li>
DecalGeometry
</li>
<li>
ParametricGeometries
</li>
<li>
TeapotBufferGeometry
</li>
</ul>
...
...
examples/js/geometries/DecalGeometry.js
浏览文件 @
39873e0f
...
...
@@ -16,342 +16,334 @@
*
*/
(
function
(
)
{
THREE
.
DecalGeometry
=
function
(
mesh
,
position
,
orientation
,
size
)
{
function
DecalGeometry
(
mesh
,
position
,
orientation
,
size
)
{
THREE
.
BufferGeometry
.
call
(
this
);
THREE
.
BufferGeometry
.
call
(
this
);
// buffers
// buffers
var
vertices
=
[];
var
normals
=
[];
var
uvs
=
[];
var
vertices
=
[];
var
normals
=
[];
var
uvs
=
[];
// helpers
// helpers
var
plane
=
new
THREE
.
Vector3
();
var
plane
=
new
THREE
.
Vector3
();
// this matrix represents the transformation of the decal projector
// this matrix represents the transformation of the decal projector
var
projectorMatrix
=
new
THREE
.
Matrix4
();
projectorMatrix
.
makeRotationFromEuler
(
orientation
);
projectorMatrix
.
setPosition
(
position
);
var
projectorMatrix
=
new
THREE
.
Matrix4
();
projectorMatrix
.
makeRotationFromEuler
(
orientation
);
projectorMatrix
.
setPosition
(
position
);
var
projectorMatrixInverse
=
new
THREE
.
Matrix4
().
getInverse
(
projectorMatrix
);
var
projectorMatrixInverse
=
new
THREE
.
Matrix4
().
getInverse
(
projectorMatrix
);
// generate buffers
// generate buffers
generate
();
generate
();
// build geometry
// build geometry
this
.
addAttribute
(
'
position
'
,
new
THREE
.
Float32BufferAttribute
(
vertices
,
3
)
);
this
.
addAttribute
(
'
normal
'
,
new
THREE
.
Float32BufferAttribute
(
normals
,
3
)
);
this
.
addAttribute
(
'
uv
'
,
new
THREE
.
Float32BufferAttribute
(
uvs
,
2
)
);
this
.
addAttribute
(
'
position
'
,
new
THREE
.
Float32BufferAttribute
(
vertices
,
3
)
);
this
.
addAttribute
(
'
normal
'
,
new
THREE
.
Float32BufferAttribute
(
normals
,
3
)
);
this
.
addAttribute
(
'
uv
'
,
new
THREE
.
Float32BufferAttribute
(
uvs
,
2
)
);
function
generate
()
{
function
generate
()
{
var
i
;
var
geometry
=
new
THREE
.
BufferGeometry
();
var
decalVertices
=
[];
var
i
;
var
geometry
=
new
THREE
.
BufferGeometry
();
var
decalVertices
=
[];
var
vertex
=
new
THREE
.
Vector3
();
var
normal
=
new
THREE
.
Vector3
();
var
vertex
=
new
THREE
.
Vector3
();
var
normal
=
new
THREE
.
Vector3
();
// handle different geometry types
// handle different geometry types
if
(
mesh
.
geometry
.
isGeometry
)
{
if
(
mesh
.
geometry
.
isGeometry
)
{
geometry
.
fromGeometry
(
mesh
.
geometry
);
geometry
.
fromGeometry
(
mesh
.
geometry
);
}
else
{
}
else
{
geometry
.
copy
(
mesh
.
geometry
);
geometry
.
copy
(
mesh
.
geometry
);
}
}
var
positionAttribute
=
geometry
.
attributes
.
position
;
var
normalAttribute
=
geometry
.
attributes
.
normal
;
var
positionAttribute
=
geometry
.
attributes
.
position
;
var
normalAttribute
=
geometry
.
attributes
.
normal
;
// first, create an array of 'DecalVertex' objects
// three consecutive 'DecalVertex' objects represent a single face
//
// this data structure will be later used to perform the clipping
// first, create an array of 'DecalVertex' objects
// three consecutive 'DecalVertex' objects represent a single face
//
// this data structure will be later used to perform the clipping
if
(
geometry
.
index
!==
null
)
{
if
(
geometry
.
index
!==
null
)
{
// indexed BufferGeometry
// indexed BufferGeometry
var
index
=
geometry
.
index
;
var
index
=
geometry
.
index
;
for
(
i
=
0
;
i
<
index
.
count
;
i
++
)
{
for
(
i
=
0
;
i
<
index
.
count
;
i
++
)
{
vertex
.
fromBufferAttribute
(
positionAttribute
,
index
.
getX
(
i
)
);
normal
.
fromBufferAttribute
(
normalAttribute
,
index
.
getX
(
i
)
);
vertex
.
fromBufferAttribute
(
positionAttribute
,
index
.
getX
(
i
)
);
normal
.
fromBufferAttribute
(
normalAttribute
,
index
.
getX
(
i
)
);
pushDecalVertex
(
decalVertices
,
vertex
,
normal
);
pushDecalVertex
(
decalVertices
,
vertex
,
normal
);
}
}
else
{
}
// non-indexed BufferGeometry
}
else
{
for
(
i
=
0
;
i
<
positionAttribute
.
count
;
i
++
)
{
// non-indexed BufferGeometry
vertex
.
fromBufferAttribute
(
positionAttribute
,
i
);
normal
.
fromBufferAttribute
(
normalAttribute
,
i
);
for
(
i
=
0
;
i
<
positionAttribute
.
count
;
i
++
)
{
pushDecalVertex
(
decalVertices
,
vertex
,
normal
);
vertex
.
fromBufferAttribute
(
positionAttribute
,
i
);
normal
.
fromBufferAttribute
(
normalAttribute
,
i
);
}
pushDecalVertex
(
decalVertices
,
vertex
,
normal
);
}
// second, clip the geometry so that it doesn't extend out from the projector
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
1
,
0
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
-
1
,
0
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
1
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
-
1
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
0
,
1
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
0
,
-
1
)
);
// third, generate final vertices, normals and uvs
for
(
i
=
0
;
i
<
decalVertices
.
length
;
i
++
)
{
var
decalVertex
=
decalVertices
[
i
];
// create texture coordinates (we are still in projector space)
}
uvs
.
push
(
0.5
+
(
decalVertex
.
position
.
x
/
size
.
x
),
0.5
+
(
decalVertex
.
position
.
y
/
size
.
y
)
);
// second, clip the geometry so that it doesn't extend out from the projector
// transform the vertex back to world space
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
1
,
0
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
-
1
,
0
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
1
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
-
1
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
0
,
1
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
0
,
-
1
)
);
decalVertex
.
position
.
applyMatrix4
(
projectorMatrix
);
// third, generate final vertices, normals and uvs
// now create vertex and normal buffer data
for
(
i
=
0
;
i
<
decalVertices
.
length
;
i
++
)
{
vertices
.
push
(
decalVertex
.
position
.
x
,
decalVertex
.
position
.
y
,
decalVertex
.
position
.
z
);
normals
.
push
(
decalVertex
.
normal
.
x
,
decalVertex
.
normal
.
y
,
decalVertex
.
normal
.
z
);
var
decalVertex
=
decalVertices
[
i
];
}
// create texture coordinates (we are still in projector space)
}
uvs
.
push
(
0.5
+
(
decalVertex
.
position
.
x
/
size
.
x
),
0.5
+
(
decalVertex
.
position
.
y
/
size
.
y
)
);
function
pushDecalVertex
(
decalVertices
,
vertex
,
normal
)
{
// transform the vertex back to world space
// transform the vertex to world space, then to projector space
decalVertex
.
position
.
applyMatrix4
(
projectorMatrix
);
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
vertex
.
applyMatrix4
(
projectorMatrixInverse
);
// now create vertex and normal buffer data
decalVertices
.
push
(
new
DecalVertex
(
vertex
.
clone
(),
normal
.
clone
()
)
);
vertices
.
push
(
decalVertex
.
position
.
x
,
decalVertex
.
position
.
y
,
decalVertex
.
position
.
z
);
normals
.
push
(
decalVertex
.
normal
.
x
,
decalVertex
.
normal
.
y
,
decalVertex
.
normal
.
z
);
}
function
clipGeometry
(
inVertices
,
plane
)
{
}
var
outVertices
=
[];
function
pushDecalVertex
(
decalVertices
,
vertex
,
normal
)
{
var
s
=
0.5
*
Math
.
abs
(
size
.
dot
(
plane
)
);
// transform the vertex to world space, then to projector space
// a single iteration clips one face,
// which consists of three consecutive 'DecalVertex' objects
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
vertex
.
applyMatrix4
(
projectorMatrixInverse
);
for
(
var
i
=
0
;
i
<
inVertices
.
length
;
i
+=
3
)
{
decalVertices
.
push
(
new
THREE
.
DecalVertex
(
vertex
.
clone
(),
normal
.
clone
()
)
);
var
v1Out
,
v2Out
,
v3Out
,
total
=
0
;
var
nV1
,
nV2
,
nV3
,
nV4
;
}
var
d1
=
inVertices
[
i
+
0
].
position
.
dot
(
plane
)
-
s
;
var
d2
=
inVertices
[
i
+
1
].
position
.
dot
(
plane
)
-
s
;
var
d3
=
inVertices
[
i
+
2
].
position
.
dot
(
plane
)
-
s
;
function
clipGeometry
(
inVertices
,
plane
)
{
v1Out
=
d1
>
0
;
v2Out
=
d2
>
0
;
v3Out
=
d3
>
0
;
var
outVertices
=
[];
// calculate, how many vertices of the face lie outside of the clipping plane
var
s
=
0.5
*
Math
.
abs
(
size
.
dot
(
plane
)
);
total
=
(
v1Out
?
1
:
0
)
+
(
v2Out
?
1
:
0
)
+
(
v3Out
?
1
:
0
);
// a single iteration clips one face,
// which consists of three consecutive 'DecalVertex' objects
switch
(
total
)
{
for
(
var
i
=
0
;
i
<
inVertices
.
length
;
i
+=
3
)
{
case
0
:
{
var
v1Out
,
v2Out
,
v3Out
,
total
=
0
;
var
nV1
,
nV2
,
nV3
,
nV4
;
// the entire face lies inside of the plane, no clipping needed
var
d1
=
inVertices
[
i
+
0
].
position
.
dot
(
plane
)
-
s
;
var
d2
=
inVertices
[
i
+
1
].
position
.
dot
(
plane
)
-
s
;
var
d3
=
inVertices
[
i
+
2
].
position
.
dot
(
plane
)
-
s
;
outVertices
.
push
(
inVertices
[
i
]
);
outVertices
.
push
(
inVertices
[
i
+
1
]
);
outVertices
.
push
(
inVertices
[
i
+
2
]
);
break
;
v1Out
=
d1
>
0
;
v2Out
=
d2
>
0
;
v3Out
=
d3
>
0
;
}
// calculate, how many vertices of the face lie outside of the clipping plane
case
1
:
{
total
=
(
v1Out
?
1
:
0
)
+
(
v2Out
?
1
:
0
)
+
(
v3Out
?
1
:
0
);
// one vertex lies outside of the plane, perform clipping
switch
(
total
)
{
if
(
v1Out
)
{
case
0
:
{
nV1
=
inVertices
[
i
+
1
];
nV2
=
inVertices
[
i
+
2
];
nV3
=
clip
(
inVertices
[
i
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
],
nV2
,
plane
,
s
);
// the entire face lies inside of the plane, no clipping needed
}
outVertices
.
push
(
inVertices
[
i
]
);
outVertices
.
push
(
inVertices
[
i
+
1
]
);
outVertices
.
push
(
inVertices
[
i
+
2
]
);
break
;
if
(
v2Out
)
{
}
nV1
=
inVertices
[
i
];
nV2
=
inVertices
[
i
+
2
];
nV3
=
clip
(
inVertices
[
i
+
1
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
+
1
],
nV2
,
plane
,
s
);
case
1
:
{
outVertices
.
push
(
nV3
);
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV1
.
clone
()
);
// one vertex lies outside of the plane, perform clipping
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV3
.
clone
()
);
outVertices
.
push
(
nV4
);
break
;
if
(
v1Out
)
{
}
nV1
=
inVertices
[
i
+
1
];
nV2
=
inVertices
[
i
+
2
];
nV3
=
clip
(
inVertices
[
i
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
],
nV2
,
plane
,
s
);
if
(
v3Out
)
{
}
nV1
=
inVertices
[
i
];
nV2
=
inVertices
[
i
+
1
];
nV3
=
clip
(
inVertices
[
i
+
2
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
+
2
],
nV2
,
plane
,
s
);
if
(
v2Out
)
{
}
nV1
=
inVertices
[
i
];
nV2
=
inVertices
[
i
+
2
];
nV3
=
clip
(
inVertices
[
i
+
1
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
+
1
],
nV2
,
plane
,
s
);
outVertices
.
push
(
nV1
.
clone
()
);
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV3
);
outVertices
.
push
(
nV4
);
outVertices
.
push
(
nV3
.
clone
()
);
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV1
.
clone
()
);
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV3
.
clone
()
);
outVertices
.
push
(
nV4
);
break
;
}
case
2
:
{
if
(
v3Out
)
{
// two vertices lies outside of the plane, perform clipping
nV1
=
inVertices
[
i
];
nV2
=
inVertices
[
i
+
1
];
nV3
=
clip
(
inVertices
[
i
+
2
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
+
2
],
nV2
,
plane
,
s
);
if
(
!
v1Out
)
{
nV1
=
inVertices
[
i
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
+
1
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
+
2
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
}
outVertices
.
push
(
nV1
.
clone
()
);
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV3
);
if
(
!
v2Out
)
{
outVertices
.
push
(
nV4
);
outVertices
.
push
(
nV3
.
clone
()
);
outVertices
.
push
(
nV2
.
clone
()
);
nV1
=
inVertices
[
i
+
1
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
+
2
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
break
;
}
}
if
(
!
v3Out
)
{
case
2
:
{
nV1
=
inVertices
[
i
+
2
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
+
1
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
// two vertices lies outside of the plane, perform clipping
}
if
(
!
v1Out
)
{
break
;
nV1
=
inVertices
[
i
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
+
1
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
+
2
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
case
3
:
{
if
(
!
v2Out
)
{
// the entire face lies outside of the plane, so let's discard the corresponding vertices
break
;
nV1
=
inVertices
[
i
+
1
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
+
2
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
}
if
(
!
v3Out
)
{
}
nV1
=
inVertices
[
i
+
2
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
+
1
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
return
outVertices
;
}
}
break
;
function
clip
(
v0
,
v1
,
p
,
s
)
{
}
var
d0
=
v0
.
position
.
dot
(
p
)
-
s
;
var
d1
=
v1
.
position
.
dot
(
p
)
-
s
;
case
3
:
{
var
s0
=
d0
/
(
d0
-
d1
);
// the entire face lies outside of the plane, so let's discard the corresponding vertices
var
v
=
new
DecalVertex
(
new
THREE
.
Vector3
(
v0
.
position
.
x
+
s0
*
(
v1
.
position
.
x
-
v0
.
position
.
x
),
v0
.
position
.
y
+
s0
*
(
v1
.
position
.
y
-
v0
.
position
.
y
),
v0
.
position
.
z
+
s0
*
(
v1
.
position
.
z
-
v0
.
position
.
z
)
),
new
THREE
.
Vector3
(
v0
.
normal
.
x
+
s0
*
(
v1
.
normal
.
x
-
v0
.
normal
.
x
),
v0
.
normal
.
y
+
s0
*
(
v1
.
normal
.
y
-
v0
.
normal
.
y
),
v0
.
normal
.
z
+
s0
*
(
v1
.
normal
.
z
-
v0
.
normal
.
z
)
)
);
break
;
// need to clip more values (texture coordinates)? do it this way:
// intersectpoint.value = a.value + s * ( b.value - a.value );
}
return
v
;
}
}
return
outVertices
;
}
DecalGeometry
.
prototype
=
Object
.
create
(
THREE
.
BufferGeometry
.
prototype
);
DecalGeometry
.
prototype
.
constructor
=
DecalGeometry
;
function
clip
(
v0
,
v1
,
p
,
s
)
{
var
d0
=
v0
.
position
.
dot
(
p
)
-
s
;
var
d1
=
v1
.
position
.
dot
(
p
)
-
s
;
var
s0
=
d0
/
(
d0
-
d1
);
// helper
var
v
=
new
THREE
.
DecalVertex
(
new
THREE
.
Vector3
(
v0
.
position
.
x
+
s0
*
(
v1
.
position
.
x
-
v0
.
position
.
x
),
v0
.
position
.
y
+
s0
*
(
v1
.
position
.
y
-
v0
.
position
.
y
),
v0
.
position
.
z
+
s0
*
(
v1
.
position
.
z
-
v0
.
position
.
z
)
),
new
THREE
.
Vector3
(
v0
.
normal
.
x
+
s0
*
(
v1
.
normal
.
x
-
v0
.
normal
.
x
),
v0
.
normal
.
y
+
s0
*
(
v1
.
normal
.
y
-
v0
.
normal
.
y
),
v0
.
normal
.
z
+
s0
*
(
v1
.
normal
.
z
-
v0
.
normal
.
z
)
)
);
function
DecalVertex
(
position
,
normal
)
{
// need to clip more values (texture coordinates)? do it this way:
// intersectpoint.value = a.value + s * ( b.value - a.value );
this
.
position
=
position
;
this
.
normal
=
normal
;
return
v
;
}
DecalVertex
.
prototype
.
clone
=
function
()
{
};
THREE
.
DecalGeometry
.
prototype
=
Object
.
create
(
THREE
.
BufferGeometry
.
prototype
);
THREE
.
DecalGeometry
.
prototype
.
constructor
=
THREE
.
DecalGeometry
;
// helper
THREE
.
DecalVertex
=
function
(
position
,
normal
)
{
return
new
DecalVertex
(
this
.
position
.
clone
(),
this
.
normal
.
clone
()
);
this
.
position
=
position
;
this
.
normal
=
normal
;
};
};
// export
THREE
.
DecalVertex
.
prototype
.
clone
=
function
()
{
THREE
.
DecalGeometry
=
DecalGeometry
;
return
new
this
.
constructor
(
this
.
position
.
clone
(),
this
.
normal
.
clone
()
)
;
}
)()
;
};
examples/jsm/geometries/DecalGeometry.d.ts
0 → 100644
浏览文件 @
39873e0f
import
{
BufferGeometry
,
Euler
,
Mesh
,
Vector3
}
from
'
../../../src/Three
'
;
export
class
DecalGeometry
extends
BufferGeometry
{
constructor
(
mesh
:
Mesh
,
position
:
Vector3
,
orientation
:
Euler
,
size
:
Vector3
);
}
export
class
DecalVertex
{
constructor
(
position
:
Vector3
,
normal
:
Vector3
);
clone
():
DecalVertex
;
}
examples/jsm/geometries/DecalGeometry.js
0 → 100644
浏览文件 @
39873e0f
/**
* @author Mugen87 / https://github.com/Mugen87
* @author spite / https://github.com/spite
*
* You can use this geometry to create a decal mesh, that serves different kinds of purposes.
* e.g. adding unique details to models, performing dynamic visual environmental changes or covering seams.
*
* Constructor parameter:
*
* mesh — Any mesh object
* position — Position of the decal projector
* orientation — Orientation of the decal projector
* size — Size of the decal projector
*
* reference: http://blog.wolfire.com/2009/06/how-to-project-decals/
*
*/
import
{
BufferGeometry
,
Float32BufferAttribute
,
Matrix4
,
Vector3
}
from
"
../../../build/three.module.js
"
;
var
DecalGeometry
=
function
(
mesh
,
position
,
orientation
,
size
)
{
BufferGeometry
.
call
(
this
);
// buffers
var
vertices
=
[];
var
normals
=
[];
var
uvs
=
[];
// helpers
var
plane
=
new
Vector3
();
// this matrix represents the transformation of the decal projector
var
projectorMatrix
=
new
Matrix4
();
projectorMatrix
.
makeRotationFromEuler
(
orientation
);
projectorMatrix
.
setPosition
(
position
);
var
projectorMatrixInverse
=
new
Matrix4
().
getInverse
(
projectorMatrix
);
// generate buffers
generate
();
// build geometry
this
.
addAttribute
(
'
position
'
,
new
Float32BufferAttribute
(
vertices
,
3
)
);
this
.
addAttribute
(
'
normal
'
,
new
Float32BufferAttribute
(
normals
,
3
)
);
this
.
addAttribute
(
'
uv
'
,
new
Float32BufferAttribute
(
uvs
,
2
)
);
function
generate
()
{
var
i
;
var
geometry
=
new
BufferGeometry
();
var
decalVertices
=
[];
var
vertex
=
new
Vector3
();
var
normal
=
new
Vector3
();
// handle different geometry types
if
(
mesh
.
geometry
.
isGeometry
)
{
geometry
.
fromGeometry
(
mesh
.
geometry
);
}
else
{
geometry
.
copy
(
mesh
.
geometry
);
}
var
positionAttribute
=
geometry
.
attributes
.
position
;
var
normalAttribute
=
geometry
.
attributes
.
normal
;
// first, create an array of 'DecalVertex' objects
// three consecutive 'DecalVertex' objects represent a single face
//
// this data structure will be later used to perform the clipping
if
(
geometry
.
index
!==
null
)
{
// indexed BufferGeometry
var
index
=
geometry
.
index
;
for
(
i
=
0
;
i
<
index
.
count
;
i
++
)
{
vertex
.
fromBufferAttribute
(
positionAttribute
,
index
.
getX
(
i
)
);
normal
.
fromBufferAttribute
(
normalAttribute
,
index
.
getX
(
i
)
);
pushDecalVertex
(
decalVertices
,
vertex
,
normal
);
}
}
else
{
// non-indexed BufferGeometry
for
(
i
=
0
;
i
<
positionAttribute
.
count
;
i
++
)
{
vertex
.
fromBufferAttribute
(
positionAttribute
,
i
);
normal
.
fromBufferAttribute
(
normalAttribute
,
i
);
pushDecalVertex
(
decalVertices
,
vertex
,
normal
);
}
}
// second, clip the geometry so that it doesn't extend out from the projector
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
1
,
0
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
-
1
,
0
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
1
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
-
1
,
0
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
0
,
1
)
);
decalVertices
=
clipGeometry
(
decalVertices
,
plane
.
set
(
0
,
0
,
-
1
)
);
// third, generate final vertices, normals and uvs
for
(
i
=
0
;
i
<
decalVertices
.
length
;
i
++
)
{
var
decalVertex
=
decalVertices
[
i
];
// create texture coordinates (we are still in projector space)
uvs
.
push
(
0.5
+
(
decalVertex
.
position
.
x
/
size
.
x
),
0.5
+
(
decalVertex
.
position
.
y
/
size
.
y
)
);
// transform the vertex back to world space
decalVertex
.
position
.
applyMatrix4
(
projectorMatrix
);
// now create vertex and normal buffer data
vertices
.
push
(
decalVertex
.
position
.
x
,
decalVertex
.
position
.
y
,
decalVertex
.
position
.
z
);
normals
.
push
(
decalVertex
.
normal
.
x
,
decalVertex
.
normal
.
y
,
decalVertex
.
normal
.
z
);
}
}
function
pushDecalVertex
(
decalVertices
,
vertex
,
normal
)
{
// transform the vertex to world space, then to projector space
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
vertex
.
applyMatrix4
(
projectorMatrixInverse
);
decalVertices
.
push
(
new
DecalVertex
(
vertex
.
clone
(),
normal
.
clone
()
)
);
}
function
clipGeometry
(
inVertices
,
plane
)
{
var
outVertices
=
[];
var
s
=
0.5
*
Math
.
abs
(
size
.
dot
(
plane
)
);
// a single iteration clips one face,
// which consists of three consecutive 'DecalVertex' objects
for
(
var
i
=
0
;
i
<
inVertices
.
length
;
i
+=
3
)
{
var
v1Out
,
v2Out
,
v3Out
,
total
=
0
;
var
nV1
,
nV2
,
nV3
,
nV4
;
var
d1
=
inVertices
[
i
+
0
].
position
.
dot
(
plane
)
-
s
;
var
d2
=
inVertices
[
i
+
1
].
position
.
dot
(
plane
)
-
s
;
var
d3
=
inVertices
[
i
+
2
].
position
.
dot
(
plane
)
-
s
;
v1Out
=
d1
>
0
;
v2Out
=
d2
>
0
;
v3Out
=
d3
>
0
;
// calculate, how many vertices of the face lie outside of the clipping plane
total
=
(
v1Out
?
1
:
0
)
+
(
v2Out
?
1
:
0
)
+
(
v3Out
?
1
:
0
);
switch
(
total
)
{
case
0
:
{
// the entire face lies inside of the plane, no clipping needed
outVertices
.
push
(
inVertices
[
i
]
);
outVertices
.
push
(
inVertices
[
i
+
1
]
);
outVertices
.
push
(
inVertices
[
i
+
2
]
);
break
;
}
case
1
:
{
// one vertex lies outside of the plane, perform clipping
if
(
v1Out
)
{
nV1
=
inVertices
[
i
+
1
];
nV2
=
inVertices
[
i
+
2
];
nV3
=
clip
(
inVertices
[
i
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
],
nV2
,
plane
,
s
);
}
if
(
v2Out
)
{
nV1
=
inVertices
[
i
];
nV2
=
inVertices
[
i
+
2
];
nV3
=
clip
(
inVertices
[
i
+
1
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
+
1
],
nV2
,
plane
,
s
);
outVertices
.
push
(
nV3
);
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV1
.
clone
()
);
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV3
.
clone
()
);
outVertices
.
push
(
nV4
);
break
;
}
if
(
v3Out
)
{
nV1
=
inVertices
[
i
];
nV2
=
inVertices
[
i
+
1
];
nV3
=
clip
(
inVertices
[
i
+
2
],
nV1
,
plane
,
s
);
nV4
=
clip
(
inVertices
[
i
+
2
],
nV2
,
plane
,
s
);
}
outVertices
.
push
(
nV1
.
clone
()
);
outVertices
.
push
(
nV2
.
clone
()
);
outVertices
.
push
(
nV3
);
outVertices
.
push
(
nV4
);
outVertices
.
push
(
nV3
.
clone
()
);
outVertices
.
push
(
nV2
.
clone
()
);
break
;
}
case
2
:
{
// two vertices lies outside of the plane, perform clipping
if
(
!
v1Out
)
{
nV1
=
inVertices
[
i
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
+
1
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
+
2
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
if
(
!
v2Out
)
{
nV1
=
inVertices
[
i
+
1
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
+
2
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
if
(
!
v3Out
)
{
nV1
=
inVertices
[
i
+
2
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
i
],
plane
,
s
);
nV3
=
clip
(
nV1
,
inVertices
[
i
+
1
],
plane
,
s
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
break
;
}
case
3
:
{
// the entire face lies outside of the plane, so let's discard the corresponding vertices
break
;
}
}
}
return
outVertices
;
}
function
clip
(
v0
,
v1
,
p
,
s
)
{
var
d0
=
v0
.
position
.
dot
(
p
)
-
s
;
var
d1
=
v1
.
position
.
dot
(
p
)
-
s
;
var
s0
=
d0
/
(
d0
-
d1
);
var
v
=
new
DecalVertex
(
new
Vector3
(
v0
.
position
.
x
+
s0
*
(
v1
.
position
.
x
-
v0
.
position
.
x
),
v0
.
position
.
y
+
s0
*
(
v1
.
position
.
y
-
v0
.
position
.
y
),
v0
.
position
.
z
+
s0
*
(
v1
.
position
.
z
-
v0
.
position
.
z
)
),
new
Vector3
(
v0
.
normal
.
x
+
s0
*
(
v1
.
normal
.
x
-
v0
.
normal
.
x
),
v0
.
normal
.
y
+
s0
*
(
v1
.
normal
.
y
-
v0
.
normal
.
y
),
v0
.
normal
.
z
+
s0
*
(
v1
.
normal
.
z
-
v0
.
normal
.
z
)
)
);
// need to clip more values (texture coordinates)? do it this way:
// intersectpoint.value = a.value + s * ( b.value - a.value );
return
v
;
}
};
DecalGeometry
.
prototype
=
Object
.
create
(
BufferGeometry
.
prototype
);
DecalGeometry
.
prototype
.
constructor
=
DecalGeometry
;
// helper
var
DecalVertex
=
function
(
position
,
normal
)
{
this
.
position
=
position
;
this
.
normal
=
normal
;
};
DecalVertex
.
prototype
.
clone
=
function
()
{
return
new
this
.
constructor
(
this
.
position
.
clone
(),
this
.
normal
.
clone
()
);
};
export
{
DecalGeometry
,
DecalVertex
};
utils/modularize.js
浏览文件 @
39873e0f
...
...
@@ -43,6 +43,7 @@ var files = [
{
path
:
'
exporters/TypedGeometryExporter.js
'
,
dependencies
:
[],
ignoreList
:
[]
},
{
path
:
'
geometries/BoxLineGeometry.js
'
,
dependencies
:
[],
ignoreList
:
[]
},
{
path
:
'
geometries/DecalGeometry.js
'
,
dependencies
:
[],
ignoreList
:
[]
},
{
path
:
'
geometries/ParametricGeometries.js
'
,
dependencies
:
[],
ignoreList
:
[]
},
{
path
:
'
geometries/TeapotBufferGeometry.js
'
,
dependencies
:
[],
ignoreList
:
[]
},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录