Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Ablesons
three.js
提交
0d91aa4e
T
three.js
项目概览
Ablesons
/
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,发现更多精彩内容 >>
提交
0d91aa4e
编写于
2月 24, 2017
作者:
M
Mr.doob
提交者:
GitHub
2月 24, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #10876 from Mugen87/decal
New DecalGeometry
上级
c1c49bca
74db944a
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
423 addition
and
369 deletion
+423
-369
docs/api/geometries/DecalGeometry.html
docs/api/geometries/DecalGeometry.html
+42
-0
docs/list.js
docs/list.js
+1
-0
examples/js/geometries/DecalGeometry.js
examples/js/geometries/DecalGeometry.js
+0
-289
examples/webgl_decals.html
examples/webgl_decals.html
+32
-80
src/geometries/DecalGeometry.js
src/geometries/DecalGeometry.js
+347
-0
src/geometries/Geometries.js
src/geometries/Geometries.js
+1
-0
未找到文件。
docs/api/geometries/DecalGeometry.html
0 → 100644
浏览文件 @
0d91aa4e
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"utf-8"
/>
<base
href=
"../../"
/>
<script
src=
"list.js"
></script>
<script
src=
"page.js"
></script>
<link
type=
"text/css"
rel=
"stylesheet"
href=
"page.css"
/>
</head>
<body>
[page:BufferGeometry]
→
<h1>
[name]
</h1>
<div
class=
"desc"
>
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.
</div>
<h2>
Example
</h2>
[example:webgl_decals decals]
<code>
var geometry = new THREE.DecalGeometry( mesh, position, orientation, size );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var decal = new THREE.Mesh( geometry, material );
scene.add( decal );
</code>
<h2>
Constructor
</h2>
<h3>
[name]( [page:Mesh mesh], [page:Vector3 position], [page:Euler orientation], [page:Vector3 size] )
</h3>
<div>
mesh — Any mesh object.
<br
/>
position — Position of the decal projector.
<br
/>
orientation — Orientation of the decal projector.
<br
/>
size — Size of the decal projector.
<br
/>
</div>
<h2>
Source
</h2>
[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
</body>
</html>
docs/list.js
浏览文件 @
0d91aa4e
...
...
@@ -140,6 +140,7 @@ var list = {
[
"
ConeGeometry
"
,
"
api/geometries/ConeGeometry
"
],
[
"
CylinderBufferGeometry
"
,
"
api/geometries/CylinderBufferGeometry
"
],
[
"
CylinderGeometry
"
,
"
api/geometries/CylinderGeometry
"
],
[
"
DecalGeometry
"
,
"
api/geometries/DecalGeometry
"
],
[
"
DodecahedronBufferGeometry
"
,
"
api/geometries/DodecahedronBufferGeometry
"
],
[
"
DodecahedronGeometry
"
,
"
api/geometries/DodecahedronGeometry
"
],
[
"
EdgesGeometry
"
,
"
api/geometries/EdgesGeometry
"
],
...
...
examples/js/geometries/DecalGeometry.js
已删除
100644 → 0
浏览文件 @
c1c49bca
THREE
.
DecalVertex
=
function
(
v
,
n
)
{
this
.
vertex
=
v
;
this
.
normal
=
n
;
};
THREE
.
DecalVertex
.
prototype
.
clone
=
function
()
{
return
new
THREE
.
DecalVertex
(
this
.
vertex
.
clone
(),
this
.
normal
.
clone
()
);
};
THREE
.
DecalGeometry
=
function
(
mesh
,
position
,
rotation
,
dimensions
,
check
)
{
THREE
.
Geometry
.
call
(
this
);
if
(
check
===
undefined
)
check
=
null
;
check
=
check
||
new
THREE
.
Vector3
(
1
,
1
,
1
);
this
.
uvs
=
[];
this
.
cube
=
new
THREE
.
Mesh
(
new
THREE
.
BoxGeometry
(
dimensions
.
x
,
dimensions
.
y
,
dimensions
.
z
),
new
THREE
.
MeshBasicMaterial
()
);
this
.
cube
.
rotation
.
set
(
rotation
.
x
,
rotation
.
y
,
rotation
.
z
);
this
.
cube
.
position
.
copy
(
position
);
this
.
cube
.
scale
.
set
(
1
,
1
,
1
);
this
.
cube
.
updateMatrix
();
this
.
iCubeMatrix
=
(
new
THREE
.
Matrix4
()
).
getInverse
(
this
.
cube
.
matrix
);
this
.
faceIndices
=
[
'
a
'
,
'
b
'
,
'
c
'
,
'
d
'
];
this
.
clipFace
=
function
(
inVertices
,
plane
)
{
var
size
=
.
5
*
Math
.
abs
(
(
dimensions
.
clone
()
).
dot
(
plane
)
);
function
clip
(
v0
,
v1
,
p
)
{
var
d0
=
v0
.
vertex
.
dot
(
p
)
-
size
,
d1
=
v1
.
vertex
.
dot
(
p
)
-
size
;
var
s
=
d0
/
(
d0
-
d1
);
var
v
=
new
THREE
.
DecalVertex
(
new
THREE
.
Vector3
(
v0
.
vertex
.
x
+
s
*
(
v1
.
vertex
.
x
-
v0
.
vertex
.
x
),
v0
.
vertex
.
y
+
s
*
(
v1
.
vertex
.
y
-
v0
.
vertex
.
y
),
v0
.
vertex
.
z
+
s
*
(
v1
.
vertex
.
z
-
v0
.
vertex
.
z
)
),
new
THREE
.
Vector3
(
v0
.
normal
.
x
+
s
*
(
v1
.
normal
.
x
-
v0
.
normal
.
x
),
v0
.
normal
.
y
+
s
*
(
v1
.
normal
.
y
-
v0
.
normal
.
y
),
v0
.
normal
.
z
+
s
*
(
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
;
}
if
(
inVertices
.
length
===
0
)
return
[];
var
outVertices
=
[];
for
(
var
j
=
0
;
j
<
inVertices
.
length
;
j
+=
3
)
{
var
v1Out
,
v2Out
,
v3Out
,
total
=
0
;
var
d1
=
inVertices
[
j
+
0
].
vertex
.
dot
(
plane
)
-
size
,
d2
=
inVertices
[
j
+
1
].
vertex
.
dot
(
plane
)
-
size
,
d3
=
inVertices
[
j
+
2
].
vertex
.
dot
(
plane
)
-
size
;
v1Out
=
d1
>
0
;
v2Out
=
d2
>
0
;
v3Out
=
d3
>
0
;
total
=
(
v1Out
?
1
:
0
)
+
(
v2Out
?
1
:
0
)
+
(
v3Out
?
1
:
0
);
switch
(
total
)
{
case
0
:
{
outVertices
.
push
(
inVertices
[
j
]
);
outVertices
.
push
(
inVertices
[
j
+
1
]
);
outVertices
.
push
(
inVertices
[
j
+
2
]
);
break
;
}
case
1
:
{
var
nV1
,
nV2
,
nV3
,
nV4
;
if
(
v1Out
)
{
nV1
=
inVertices
[
j
+
1
];
nV2
=
inVertices
[
j
+
2
];
nV3
=
clip
(
inVertices
[
j
],
nV1
,
plane
);
nV4
=
clip
(
inVertices
[
j
],
nV2
,
plane
);
}
if
(
v2Out
)
{
nV1
=
inVertices
[
j
];
nV2
=
inVertices
[
j
+
2
];
nV3
=
clip
(
inVertices
[
j
+
1
],
nV1
,
plane
);
nV4
=
clip
(
inVertices
[
j
+
1
],
nV2
,
plane
);
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
[
j
];
nV2
=
inVertices
[
j
+
1
];
nV3
=
clip
(
inVertices
[
j
+
2
],
nV1
,
plane
);
nV4
=
clip
(
inVertices
[
j
+
2
],
nV2
,
plane
);
}
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
:
{
var
nV1
,
nV2
,
nV3
;
if
(
!
v1Out
)
{
nV1
=
inVertices
[
j
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
j
+
1
],
plane
);
nV3
=
clip
(
nV1
,
inVertices
[
j
+
2
],
plane
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
if
(
!
v2Out
)
{
nV1
=
inVertices
[
j
+
1
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
j
+
2
],
plane
);
nV3
=
clip
(
nV1
,
inVertices
[
j
],
plane
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
if
(
!
v3Out
)
{
nV1
=
inVertices
[
j
+
2
].
clone
();
nV2
=
clip
(
nV1
,
inVertices
[
j
],
plane
);
nV3
=
clip
(
nV1
,
inVertices
[
j
+
1
],
plane
);
outVertices
.
push
(
nV1
);
outVertices
.
push
(
nV2
);
outVertices
.
push
(
nV3
);
}
break
;
}
case
3
:
{
break
;
}
}
}
return
outVertices
;
};
this
.
pushVertex
=
function
(
vertices
,
id
,
n
)
{
var
v
=
mesh
.
geometry
.
vertices
[
id
].
clone
();
v
.
applyMatrix4
(
mesh
.
matrix
);
v
.
applyMatrix4
(
this
.
iCubeMatrix
);
vertices
.
push
(
new
THREE
.
DecalVertex
(
v
,
n
.
clone
()
)
);
};
this
.
computeDecal
=
function
()
{
var
finalVertices
=
[];
for
(
var
i
=
0
;
i
<
mesh
.
geometry
.
faces
.
length
;
i
++
)
{
var
f
=
mesh
.
geometry
.
faces
[
i
];
var
vertices
=
[];
this
.
pushVertex
(
vertices
,
f
[
this
.
faceIndices
[
0
]
],
f
.
vertexNormals
[
0
]
);
this
.
pushVertex
(
vertices
,
f
[
this
.
faceIndices
[
1
]
],
f
.
vertexNormals
[
1
]
);
this
.
pushVertex
(
vertices
,
f
[
this
.
faceIndices
[
2
]
],
f
.
vertexNormals
[
2
]
);
if
(
check
.
x
)
{
vertices
=
this
.
clipFace
(
vertices
,
new
THREE
.
Vector3
(
1
,
0
,
0
)
);
vertices
=
this
.
clipFace
(
vertices
,
new
THREE
.
Vector3
(
-
1
,
0
,
0
)
);
}
if
(
check
.
y
)
{
vertices
=
this
.
clipFace
(
vertices
,
new
THREE
.
Vector3
(
0
,
1
,
0
)
);
vertices
=
this
.
clipFace
(
vertices
,
new
THREE
.
Vector3
(
0
,
-
1
,
0
)
);
}
if
(
check
.
z
)
{
vertices
=
this
.
clipFace
(
vertices
,
new
THREE
.
Vector3
(
0
,
0
,
1
)
);
vertices
=
this
.
clipFace
(
vertices
,
new
THREE
.
Vector3
(
0
,
0
,
-
1
)
);
}
for
(
var
j
=
0
;
j
<
vertices
.
length
;
j
++
)
{
var
v
=
vertices
[
j
];
this
.
uvs
.
push
(
new
THREE
.
Vector2
(
.
5
+
(
v
.
vertex
.
x
/
dimensions
.
x
),
.
5
+
(
v
.
vertex
.
y
/
dimensions
.
y
)
)
);
vertices
[
j
].
vertex
.
applyMatrix4
(
this
.
cube
.
matrix
);
}
if
(
vertices
.
length
===
0
)
continue
;
finalVertices
=
finalVertices
.
concat
(
vertices
);
}
for
(
var
k
=
0
;
k
<
finalVertices
.
length
;
k
+=
3
)
{
this
.
vertices
.
push
(
finalVertices
[
k
].
vertex
,
finalVertices
[
k
+
1
].
vertex
,
finalVertices
[
k
+
2
].
vertex
);
var
f
=
new
THREE
.
Face3
(
k
,
k
+
1
,
k
+
2
);
f
.
vertexNormals
.
push
(
finalVertices
[
k
+
0
].
normal
);
f
.
vertexNormals
.
push
(
finalVertices
[
k
+
1
].
normal
);
f
.
vertexNormals
.
push
(
finalVertices
[
k
+
2
].
normal
);
this
.
faces
.
push
(
f
);
this
.
faceVertexUvs
[
0
].
push
(
[
this
.
uvs
[
k
],
this
.
uvs
[
k
+
1
],
this
.
uvs
[
k
+
2
]
]
);
}
this
.
verticesNeedUpdate
=
true
;
this
.
elementsNeedUpdate
=
true
;
this
.
morphTargetsNeedUpdate
=
true
;
this
.
uvsNeedUpdate
=
true
;
this
.
normalsNeedUpdate
=
true
;
this
.
colorsNeedUpdate
=
true
;
this
.
computeFaceNormals
();
};
this
.
computeDecal
();
};
THREE
.
DecalGeometry
.
prototype
=
Object
.
create
(
THREE
.
Geometry
.
prototype
);
THREE
.
DecalGeometry
.
prototype
.
constructor
=
THREE
.
DecalGeometry
;
examples/webgl_decals.html
浏览文件 @
0d91aa4e
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<title>
WebGL decals
</title>
<title>
three.js webgl - decals - Decal Splatter
</title>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
>
<style>
body
{
color
:
#fff
;
background
:
#777
;
padding
:
0
;
margin
:
0
;
font-weight
:
bold
;
overflow
:
hidden
;
}
#info
{
position
:
absolute
;
top
:
0px
;
width
:
100%
;
color
:
#ffffff
;
padding
:
5px
;
font-family
:
Monospace
;
font-size
:
13px
;
margin
:
0px
;
text-align
:
center
;
overflow
:
hidden
;
}
#info
{
position
:
absolute
;
width
:
100%
;
padding
:
5px
;
}
a
{
color
:
#ffffff
;
}
</style>
</head>
<body>
<div
id=
"container"
></div>
<div
id=
"info"
>
<p>
<strong>
Decal Splatter
</strong><br
/>
Click or tap to shoot.
</p>
</div>
<div
id=
"info"
><a
href=
"https://threejs.org"
target=
"_blank"
>
three.js
</a>
- decals - Decal Splatter (click or tap to shoot)
</div>
<script
src=
"../build/three.js"
></script>
<script
src=
"js/geometries/DecalGeometry.js"
></script>
<script
src=
"js/controls/OrbitControls.js"
></script>
<script
src=
"js/libs/dat.gui.min.js"
></script>
...
...
@@ -67,15 +74,13 @@
}
);
var
decals
=
[];
var
decalHelper
,
mouseHelper
;
var
p
=
new
THREE
.
Vector3
(
0
,
0
,
0
);
var
r
=
new
THREE
.
Vector3
(
0
,
0
,
0
);
var
s
=
new
THREE
.
Vector3
(
10
,
10
,
10
);
var
mouseHelper
;
var
p
osition
=
new
THREE
.
Vector3
(
);
var
orientation
=
new
THREE
.
Euler
(
);
var
s
ize
=
new
THREE
.
Vector3
(
10
,
10
,
10
);
var
up
=
new
THREE
.
Vector3
(
0
,
1
,
0
);
var
check
=
new
THREE
.
Vector3
(
1
,
1
,
1
);
var
params
=
{
projection
:
'
normal
'
,
minScale
:
10
,
maxScale
:
20
,
rotate
:
true
,
...
...
@@ -98,7 +103,7 @@
scene
=
new
THREE
.
Scene
();
camera
=
new
THREE
.
PerspectiveCamera
(
fov
,
window
.
innerWidth
/
window
.
innerHeight
,
1
,
1000
);
camera
.
position
.
z
=
1
0
0
;
camera
.
position
.
z
=
1
2
0
;
camera
.
target
=
new
THREE
.
Vector3
();
controls
=
new
THREE
.
OrbitControls
(
camera
,
renderer
.
domElement
);
...
...
@@ -148,7 +153,7 @@
window
.
addEventListener
(
'
mouseup
'
,
function
()
{
checkIntersection
();
if
(
!
moved
)
shoot
();
if
(
!
moved
&&
intersection
.
intersects
)
shoot
();
}
);
...
...
@@ -213,7 +218,6 @@
var
gui
=
new
dat
.
GUI
();
gui
.
add
(
params
,
'
projection
'
,
{
'
From cam to mesh
'
:
'
camera
'
,
'
Normal to mesh
'
:
'
normal
'
}
);
gui
.
add
(
params
,
'
minScale
'
,
1
,
30
);
gui
.
add
(
params
,
'
maxScale
'
,
1
,
30
);
gui
.
add
(
params
,
'
rotate
'
);
...
...
@@ -236,7 +240,6 @@
map
:
textureLoader
.
load
(
'
obj/leeperrysmith/Map-COL.jpg
'
),
specularMap
:
textureLoader
.
load
(
'
obj/leeperrysmith/Map-SPEC.jpg
'
),
normalMap
:
textureLoader
.
load
(
'
obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg
'
),
normalScale
:
new
THREE
.
Vector2
(
0.75
,
0.75
),
shininess
:
25
}
);
...
...
@@ -244,50 +247,25 @@
scene
.
add
(
mesh
);
mesh
.
scale
.
set
(
10
,
10
,
10
);
//scene.add( new THREE.FaceNormalsHelper( mesh, 1 ) );
//scene.add( new THREE.VertexNormalsHelper( mesh, 1 ) );
}
);
}
function
shoot
()
{
if
(
params
.
projection
==
'
camera
'
)
{
var
dir
=
camera
.
target
.
clone
();
dir
.
sub
(
camera
.
position
);
p
=
intersection
.
point
;
position
.
copy
(
intersection
.
point
);
orientation
.
copy
(
mouseHelper
.
rotation
);
var
m
=
new
THREE
.
Matrix4
();
var
c
=
dir
.
clone
();
c
.
negate
();
c
.
multiplyScalar
(
10
);
c
.
add
(
p
);
m
.
lookAt
(
p
,
c
,
up
);
m
=
m
.
extractRotation
(
m
);
dummy
=
new
THREE
.
Object3D
();
dummy
.
rotation
.
setFromRotationMatrix
(
m
);
r
.
set
(
dummy
.
rotation
.
x
,
dummy
.
rotation
.
y
,
dummy
.
rotation
.
z
);
}
else
{
p
=
intersection
.
point
;
r
.
copy
(
mouseHelper
.
rotation
);
}
if
(
params
.
rotate
)
orientation
.
z
=
Math
.
random
()
*
2
*
Math
.
PI
;
var
scale
=
params
.
minScale
+
Math
.
random
()
*
(
params
.
maxScale
-
params
.
minScale
);
s
.
set
(
scale
,
scale
,
scale
);
if
(
params
.
rotate
)
r
.
z
=
Math
.
random
()
*
2
*
Math
.
PI
;
size
.
set
(
scale
,
scale
,
scale
);
var
material
=
decalMaterial
.
clone
();
material
.
color
.
setHex
(
Math
.
random
()
*
0xffffff
);
var
m
=
new
THREE
.
Mesh
(
new
THREE
.
DecalGeometry
(
mesh
,
p
,
r
,
s
,
check
),
material
);
var
m
=
new
THREE
.
Mesh
(
new
THREE
.
DecalGeometry
(
mesh
,
position
,
orientation
,
size
),
material
);
decals
.
push
(
m
);
scene
.
add
(
m
);
...
...
@@ -298,36 +276,10 @@
decals
.
forEach
(
function
(
d
)
{
scene
.
remove
(
d
);
d
=
null
;
}
);
decals
=
[];
}
function
mergeDecals
()
{
var
merge
=
{};
decals
.
forEach
(
function
(
decal
)
{
var
uuid
=
decal
.
material
.
uuid
;
var
d
=
merge
[
uuid
]
=
merge
[
uuid
]
||
{};
d
.
material
=
d
.
material
||
decal
.
material
;
d
.
geometry
=
d
.
geometry
||
new
THREE
.
Geometry
();
d
.
geometry
.
merge
(
decal
.
geometry
,
decal
.
matrix
);
}
);
removeDecals
();
for
(
var
key
in
merge
)
{
var
d
=
merge
[
key
];
var
mesh
=
new
THREE
.
Mesh
(
d
.
geometry
,
d
.
material
);
scene
.
add
(
mesh
);
decals
.
push
(
mesh
);
}
decals
=
[];
}
...
...
src/geometries/DecalGeometry.js
0 → 100644
浏览文件 @
0d91aa4e
import
{
BufferGeometry
}
from
'
../core/BufferGeometry
'
;
import
{
Float32BufferAttribute
}
from
'
../core/BufferAttribute
'
;
import
{
Vector3
}
from
'
../math/Vector3
'
;
import
{
Matrix4
}
from
'
../math/Matrix4
'
;
/**
* @author Mugen87 / https://github.com/Mugen87
* @author spite / https://github.com/spite
*
* reference: http://blog.wolfire.com/2009/06/how-to-project-decals/
*
*/
function
DecalGeometry
(
mesh
,
position
,
orientation
,
size
)
{
BufferGeometry
.
call
(
this
);
this
.
type
=
'
DecalGeometry
'
;
// 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
,
j
;
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
[
i
]
);
normal
.
fromBufferAttribute
(
normalAttribute
,
index
[
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
.
matrix
);
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
;
function
DecalVertex
(
position
,
normal
)
{
this
.
position
=
position
;
this
.
normal
=
normal
;
}
DecalVertex
.
prototype
.
clone
=
function
()
{
return
new
DecalVertex
(
this
.
position
.
clone
(),
this
.
normal
.
clone
()
);
};
export
{
DecalGeometry
};
src/geometries/Geometries.js
浏览文件 @
0d91aa4e
...
...
@@ -20,3 +20,4 @@ export { ConeGeometry, ConeBufferGeometry } from './ConeGeometry.js';
export
{
CylinderGeometry
,
CylinderBufferGeometry
}
from
'
./CylinderGeometry.js
'
;
export
{
CircleGeometry
,
CircleBufferGeometry
}
from
'
./CircleGeometry.js
'
;
export
{
BoxGeometry
,
BoxBufferGeometry
}
from
'
./BoxGeometry.js
'
;
export
{
DecalGeometry
}
from
'
./DecalGeometry.js
'
;
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录