Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Ablesons
three.js
提交
d7fd8412
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,发现更多精彩内容 >>
未验证
提交
d7fd8412
编写于
3月 15, 2019
作者:
M
Mr.doob
提交者:
GitHub
3月 15, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #15592 from donmccurdy/feat-jsm-exporters
JSM: Exporters: Create ES modules.
上级
a185fa19
5922b735
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
1973 addition
and
39 deletion
+1973
-39
examples/jsm/exporters/ColladaExporter.js
examples/jsm/exporters/ColladaExporter.js
+635
-0
examples/jsm/exporters/GLTFExporter.js
examples/jsm/exporters/GLTFExporter.js
+18
-28
examples/jsm/exporters/MMDExporter.js
examples/jsm/exporters/MMDExporter.js
+218
-0
examples/jsm/exporters/OBJExporter.js
examples/jsm/exporters/OBJExporter.js
+274
-0
examples/jsm/exporters/PLYExporter.js
examples/jsm/exporters/PLYExporter.js
+557
-0
examples/jsm/exporters/STLExporter.js
examples/jsm/exporters/STLExporter.js
+174
-0
examples/jsm/exporters/TypedGeometryExporter.js
examples/jsm/exporters/TypedGeometryExporter.js
+59
-0
examples/jsm/loaders/GLTFLoader.js
examples/jsm/loaders/GLTFLoader.js
+2
-2
utils/modularize.js
utils/modularize.js
+36
-9
未找到文件。
examples/jsm/exporters/ColladaExporter.js
0 → 100644
浏览文件 @
d7fd8412
/**
* @author Garrett Johnson / http://gkjohnson.github.io/
* https://github.com/gkjohnson/collada-exporter-js
*
* Usage:
* var exporter = new ColladaExporter();
*
* var data = exporter.parse(mesh);
*
* Format Definition:
* https://www.khronos.org/collada/
*/
import
{
BufferGeometry
,
Color
,
DoubleSide
,
Geometry
,
Matrix4
,
Mesh
,
MeshBasicMaterial
,
MeshLambertMaterial
}
from
"
../../../build/three.module.js
"
;
var
ColladaExporter
=
function
()
{};
ColladaExporter
.
prototype
=
{
constructor
:
ColladaExporter
,
parse
:
function
(
object
,
onDone
,
options
=
{}
)
{
options
=
Object
.
assign
(
{
version
:
'
1.4.1
'
,
author
:
null
,
textureDirectory
:
''
,
},
options
);
if
(
options
.
textureDirectory
!==
''
)
{
options
.
textureDirectory
=
`
${
options
.
textureDirectory
}
/`
.
replace
(
/
\\
/g
,
'
/
'
)
.
replace
(
/
\/
+/g
,
'
/
'
);
}
var
version
=
options
.
version
;
if
(
version
!==
'
1.4.1
'
&&
version
!==
'
1.5.0
'
)
{
console
.
warn
(
`ColladaExporter : Version
${
version
}
not supported for export. Only 1.4.1 and 1.5.0.`
);
return
null
;
}
// Convert the urdf xml into a well-formatted, indented format
function
format
(
urdf
)
{
var
IS_END_TAG
=
/^<
\/
/
;
var
IS_SELF_CLOSING
=
/
(\?
>$
)
|
(\/
>$
)
/
;
var
HAS_TEXT
=
/<
[^
>
]
+>
[^
<
]
*<
\/[^
<
]
+>/
;
var
pad
=
(
ch
,
num
)
=>
(
num
>
0
?
ch
+
pad
(
ch
,
num
-
1
)
:
''
);
var
tagnum
=
0
;
return
urdf
.
match
(
/
(
<
[^
>
]
+>
[^
<
]
+<
\/[^
<
]
+>
)
|
(
<
[^
>
]
+>
)
/g
)
.
map
(
tag
=>
{
if
(
!
HAS_TEXT
.
test
(
tag
)
&&
!
IS_SELF_CLOSING
.
test
(
tag
)
&&
IS_END_TAG
.
test
(
tag
)
)
{
tagnum
--
;
}
var
res
=
`
${
pad
(
'
'
,
tagnum
)
}${
tag
}
`
;
if
(
!
HAS_TEXT
.
test
(
tag
)
&&
!
IS_SELF_CLOSING
.
test
(
tag
)
&&
!
IS_END_TAG
.
test
(
tag
)
)
{
tagnum
++
;
}
return
res
;
}
)
.
join
(
'
\n
'
);
}
// Convert an image into a png format for saving
function
base64ToBuffer
(
str
)
{
var
b
=
atob
(
str
);
var
buf
=
new
Uint8Array
(
b
.
length
);
for
(
var
i
=
0
,
l
=
buf
.
length
;
i
<
l
;
i
++
)
{
buf
[
i
]
=
b
.
charCodeAt
(
i
);
}
return
buf
;
}
var
canvas
,
ctx
;
function
imageToData
(
image
,
ext
)
{
canvas
=
canvas
||
document
.
createElement
(
'
canvas
'
);
ctx
=
ctx
||
canvas
.
getContext
(
'
2d
'
);
canvas
.
width
=
image
.
naturalWidth
;
canvas
.
height
=
image
.
naturalHeight
;
ctx
.
drawImage
(
image
,
0
,
0
);
// Get the base64 encoded data
var
base64data
=
canvas
.
toDataURL
(
`image/
${
ext
}
`
,
1
)
.
replace
(
/^data:image
\/(
png|jpg
)
;base64,/
,
''
);
// Convert to a uint8 array
return
base64ToBuffer
(
base64data
);
}
// gets the attribute array. Generate a new array if the attribute is interleaved
var
getFuncs
=
[
'
getX
'
,
'
getY
'
,
'
getZ
'
,
'
getW
'
];
function
attrBufferToArray
(
attr
)
{
if
(
attr
.
isInterleavedBufferAttribute
)
{
// use the typed array constructor to save on memory
var
arr
=
new
attr
.
array
.
constructor
(
attr
.
count
*
attr
.
itemSize
);
var
size
=
attr
.
itemSize
;
for
(
var
i
=
0
,
l
=
attr
.
count
;
i
<
l
;
i
++
)
{
for
(
var
j
=
0
;
j
<
size
;
j
++
)
{
arr
[
i
*
size
+
j
]
=
attr
[
getFuncs
[
j
]
](
i
);
}
}
return
arr
;
}
else
{
return
attr
.
array
;
}
}
// Returns an array of the same type starting at the `st` index,
// and `ct` length
function
subArray
(
arr
,
st
,
ct
)
{
if
(
Array
.
isArray
(
arr
)
)
return
arr
.
slice
(
st
,
st
+
ct
);
else
return
new
arr
.
constructor
(
arr
.
buffer
,
st
*
arr
.
BYTES_PER_ELEMENT
,
ct
);
}
// Returns the string for a geometry's attribute
function
getAttribute
(
attr
,
name
,
params
,
type
)
{
var
array
=
attrBufferToArray
(
attr
);
var
res
=
`<source id="
${
name
}
">`
+
`<float_array id="
${
name
}
-array" count="
${
array
.
length
}
">`
+
array
.
join
(
'
'
)
+
'
</float_array>
'
+
'
<technique_common>
'
+
`<accessor source="#
${
name
}
-array" count="
${
Math
.
floor
(
array
.
length
/
attr
.
itemSize
)
}
" stride="
${
attr
.
itemSize
}
">`
+
params
.
map
(
n
=>
`<param name="
${
n
}
" type="
${
type
}
" />`
).
join
(
''
)
+
'
</accessor>
'
+
'
</technique_common>
'
+
'
</source>
'
;
return
res
;
}
// Returns the string for a node's transform information
var
transMat
;
function
getTransform
(
o
)
{
// ensure the object's matrix is up to date
// before saving the transform
o
.
updateMatrix
();
transMat
=
transMat
||
new
Matrix4
();
transMat
.
copy
(
o
.
matrix
);
transMat
.
transpose
();
return
`<matrix>
${
transMat
.
toArray
().
join
(
'
'
)
}
</matrix>`
;
}
// Process the given piece of geometry into the geometry library
// Returns the mesh id
function
processGeometry
(
g
)
{
var
info
=
geometryInfo
.
get
(
g
);
if
(
!
info
)
{
// convert the geometry to bufferGeometry if it isn't already
var
bufferGeometry
=
g
;
if
(
bufferGeometry
instanceof
Geometry
)
{
bufferGeometry
=
(
new
BufferGeometry
()
).
fromGeometry
(
bufferGeometry
);
}
var
meshid
=
`Mesh
${
libraryGeometries
.
length
+
1
}
`
;
var
indexCount
=
bufferGeometry
.
index
?
bufferGeometry
.
index
.
count
*
bufferGeometry
.
index
.
itemSize
:
bufferGeometry
.
attributes
.
position
.
count
;
var
groups
=
bufferGeometry
.
groups
!=
null
&&
bufferGeometry
.
groups
.
length
!==
0
?
bufferGeometry
.
groups
:
[
{
start
:
0
,
count
:
indexCount
,
materialIndex
:
0
}
];
var
gnode
=
`<geometry id="
${
meshid
}
" name="
${
g
.
name
}
"><mesh>`
;
// define the geometry node and the vertices for the geometry
var
posName
=
`
${
meshid
}
-position`
;
var
vertName
=
`
${
meshid
}
-vertices`
;
gnode
+=
getAttribute
(
bufferGeometry
.
attributes
.
position
,
posName
,
[
'
X
'
,
'
Y
'
,
'
Z
'
],
'
float
'
);
gnode
+=
`<vertices id="
${
vertName
}
"><input semantic="POSITION" source="#
${
posName
}
" /></vertices>`
;
// NOTE: We're not optimizing the attribute arrays here, so they're all the same length and
// can therefore share the same triangle indices. However, MeshLab seems to have trouble opening
// models with attributes that share an offset.
// MeshLab Bug#424: https://sourceforge.net/p/meshlab/bugs/424/
// serialize normals
var
triangleInputs
=
`<input semantic="VERTEX" source="#
${
vertName
}
" offset="0" />`
;
if
(
'
normal
'
in
bufferGeometry
.
attributes
)
{
var
normName
=
`
${
meshid
}
-normal`
;
gnode
+=
getAttribute
(
bufferGeometry
.
attributes
.
normal
,
normName
,
[
'
X
'
,
'
Y
'
,
'
Z
'
],
'
float
'
);
triangleInputs
+=
`<input semantic="NORMAL" source="#
${
normName
}
" offset="0" />`
;
}
// serialize uvs
if
(
'
uv
'
in
bufferGeometry
.
attributes
)
{
var
uvName
=
`
${
meshid
}
-texcoord`
;
gnode
+=
getAttribute
(
bufferGeometry
.
attributes
.
uv
,
uvName
,
[
'
S
'
,
'
T
'
],
'
float
'
);
triangleInputs
+=
`<input semantic="TEXCOORD" source="#
${
uvName
}
" offset="0" set="0" />`
;
}
// serialize colors
if
(
'
color
'
in
bufferGeometry
.
attributes
)
{
var
colName
=
`
${
meshid
}
-color`
;
gnode
+=
getAttribute
(
bufferGeometry
.
attributes
.
color
,
colName
,
[
'
X
'
,
'
Y
'
,
'
Z
'
],
'
uint8
'
);
triangleInputs
+=
`<input semantic="COLOR" source="#
${
colName
}
" offset="0" />`
;
}
var
indexArray
=
null
;
if
(
bufferGeometry
.
index
)
{
indexArray
=
attrBufferToArray
(
bufferGeometry
.
index
);
}
else
{
indexArray
=
new
Array
(
indexCount
);
for
(
var
i
=
0
,
l
=
indexArray
.
length
;
i
<
l
;
i
++
)
indexArray
[
i
]
=
i
;
}
for
(
var
i
=
0
,
l
=
groups
.
length
;
i
<
l
;
i
++
)
{
var
group
=
groups
[
i
];
var
subarr
=
subArray
(
indexArray
,
group
.
start
,
group
.
count
);
var
polycount
=
subarr
.
length
/
3
;
gnode
+=
`<triangles material="MESH_MATERIAL_
${
group
.
materialIndex
}
" count="
${
polycount
}
">`
;
gnode
+=
triangleInputs
;
gnode
+=
`<p>
${
subarr
.
join
(
'
'
)
}
</p>`
;
gnode
+=
'
</triangles>
'
;
}
gnode
+=
`</mesh></geometry>`
;
libraryGeometries
.
push
(
gnode
);
info
=
{
meshid
:
meshid
,
bufferGeometry
:
bufferGeometry
};
geometryInfo
.
set
(
g
,
info
);
}
return
info
;
}
// Process the given texture into the image library
// Returns the image library
function
processTexture
(
tex
)
{
var
texid
=
imageMap
.
get
(
tex
);
if
(
texid
==
null
)
{
texid
=
`image-
${
libraryImages
.
length
+
1
}
`
;
var
ext
=
'
png
'
;
var
name
=
tex
.
name
||
texid
;
var
imageNode
=
`<image id="
${
texid
}
" name="
${
name
}
">`
;
if
(
version
===
'
1.5.0
'
)
{
imageNode
+=
`<init_from><ref>
${
options
.
textureDirectory
}${
name
}
.
${
ext
}
</ref></init_from>`
;
}
else
{
// version image node 1.4.1
imageNode
+=
`<init_from>
${
options
.
textureDirectory
}${
name
}
.
${
ext
}
</init_from>`
;
}
imageNode
+=
'
</image>
'
;
libraryImages
.
push
(
imageNode
);
imageMap
.
set
(
tex
,
texid
);
textures
.
push
(
{
directory
:
options
.
textureDirectory
,
name
,
ext
,
data
:
imageToData
(
tex
.
image
,
ext
),
original
:
tex
}
);
}
return
texid
;
}
// Process the given material into the material and effect libraries
// Returns the material id
function
processMaterial
(
m
)
{
var
matid
=
materialMap
.
get
(
m
);
if
(
matid
==
null
)
{
matid
=
`Mat
${
libraryEffects
.
length
+
1
}
`
;
var
type
=
'
phong
'
;
if
(
m
instanceof
MeshLambertMaterial
)
{
type
=
'
lambert
'
;
}
else
if
(
m
instanceof
MeshBasicMaterial
)
{
type
=
'
constant
'
;
if
(
m
.
map
!==
null
)
{
// The Collada spec does not support diffuse texture maps with the
// constant shader type.
// mrdoob/three.js#15469
console
.
warn
(
'
ColladaExporter: Texture maps not supported with MeshBasicMaterial.
'
);
}
}
var
emissive
=
m
.
emissive
?
m
.
emissive
:
new
Color
(
0
,
0
,
0
);
var
diffuse
=
m
.
color
?
m
.
color
:
new
Color
(
0
,
0
,
0
);
var
specular
=
m
.
specular
?
m
.
specular
:
new
Color
(
1
,
1
,
1
);
var
shininess
=
m
.
shininess
||
0
;
var
reflectivity
=
m
.
reflectivity
||
0
;
// Do not export and alpha map for the reasons mentioned in issue (#13792)
// in THREE.js alpha maps are black and white, but collada expects the alpha
// channel to specify the transparency
var
transparencyNode
=
''
;
if
(
m
.
transparent
===
true
)
{
transparencyNode
+=
`<transparent>`
+
(
m
.
map
?
`<texture texture="diffuse-sampler"></texture>`
:
'
<float>1</float>
'
)
+
'
</transparent>
'
;
if
(
m
.
opacity
<
1
)
{
transparencyNode
+=
`<transparency><float>
${
m
.
opacity
}
</float></transparency>`
;
}
}
var
techniqueNode
=
`<technique sid="common"><
${
type
}
>`
+
'
<emission>
'
+
(
m
.
emissiveMap
?
'
<texture texture="emissive-sampler" texcoord="TEXCOORD" />
'
:
`<color sid="emission">
${
emissive
.
r
}
${
emissive
.
g
}
${
emissive
.
b
}
1</color>`
)
+
'
</emission>
'
+
(
type
!==
'
constant
'
?
'
<diffuse>
'
+
(
m
.
map
?
'
<texture texture="diffuse-sampler" texcoord="TEXCOORD" />
'
:
`<color sid="diffuse">
${
diffuse
.
r
}
${
diffuse
.
g
}
${
diffuse
.
b
}
1</color>`
)
+
'
</diffuse>
'
:
''
)
+
(
type
===
'
phong
'
?
`<specular><color sid="specular">
${
specular
.
r
}
${
specular
.
g
}
${
specular
.
b
}
1</color></specular>`
+
'
<shininess>
'
+
(
m
.
specularMap
?
'
<texture texture="specular-sampler" texcoord="TEXCOORD" />
'
:
`<float sid="shininess">
${
shininess
}
</float>`
)
+
'
</shininess>
'
:
''
)
+
`<reflective><color>
${
diffuse
.
r
}
${
diffuse
.
g
}
${
diffuse
.
b
}
1</color></reflective>`
+
`<reflectivity><float>
${
reflectivity
}
</float></reflectivity>`
+
transparencyNode
+
`</
${
type
}
></technique>`
;
var
effectnode
=
`<effect id="
${
matid
}
-effect">`
+
'
<profile_COMMON>
'
+
(
m
.
map
?
'
<newparam sid="diffuse-surface"><surface type="2D">
'
+
`<init_from>
${
processTexture
(
m
.
map
)
}
</init_from>`
+
'
</surface></newparam>
'
+
'
<newparam sid="diffuse-sampler"><sampler2D><source>diffuse-surface</source></sampler2D></newparam>
'
:
''
)
+
(
m
.
specularMap
?
'
<newparam sid="specular-surface"><surface type="2D">
'
+
`<init_from>
${
processTexture
(
m
.
specularMap
)
}
</init_from>`
+
'
</surface></newparam>
'
+
'
<newparam sid="specular-sampler"><sampler2D><source>specular-surface</source></sampler2D></newparam>
'
:
''
)
+
(
m
.
emissiveMap
?
'
<newparam sid="emissive-surface"><surface type="2D">
'
+
`<init_from>
${
processTexture
(
m
.
emissiveMap
)
}
</init_from>`
+
'
</surface></newparam>
'
+
'
<newparam sid="emissive-sampler"><sampler2D><source>emissive-surface</source></sampler2D></newparam>
'
:
''
)
+
techniqueNode
+
(
m
.
side
===
DoubleSide
?
`<extra><technique><double_sided sid="double_sided" type="int">1</double_sided></technique></extra>`
:
''
)
+
'
</profile_COMMON>
'
+
'
</effect>
'
;
libraryMaterials
.
push
(
`<material id="
${
matid
}
" name="
${
m
.
name
}
"><instance_effect url="#
${
matid
}
-effect" /></material>`
);
libraryEffects
.
push
(
effectnode
);
materialMap
.
set
(
m
,
matid
);
}
return
matid
;
}
// Recursively process the object into a scene
function
processObject
(
o
)
{
var
node
=
`<node name="
${
o
.
name
}
">`
;
node
+=
getTransform
(
o
);
if
(
o
instanceof
Mesh
&&
o
.
geometry
!=
null
)
{
// function returns the id associated with the mesh and a "BufferGeometry" version
// of the geometry in case it's not a geometry.
var
geomInfo
=
processGeometry
(
o
.
geometry
);
var
meshid
=
geomInfo
.
meshid
;
var
geometry
=
geomInfo
.
bufferGeometry
;
// ids of the materials to bind to the geometry
var
matids
=
null
;
var
matidsArray
=
[];
// get a list of materials to bind to the sub groups of the geometry.
// If the amount of subgroups is greater than the materials, than reuse
// the materials.
var
mat
=
o
.
material
||
new
MeshBasicMaterial
();
var
materials
=
Array
.
isArray
(
mat
)
?
mat
:
[
mat
];
if
(
geometry
.
groups
.
length
>
materials
.
length
)
{
matidsArray
=
new
Array
(
geometry
.
groups
.
length
);
}
else
{
matidsArray
=
new
Array
(
materials
.
length
)
}
matids
=
matidsArray
.
fill
()
.
map
(
(
v
,
i
)
=>
processMaterial
(
materials
[
i
%
materials
.
length
]
)
);
node
+=
`<instance_geometry url="#
${
meshid
}
">`
+
(
matids
!=
null
?
'
<bind_material><technique_common>
'
+
matids
.
map
(
(
id
,
i
)
=>
`<instance_material symbol="MESH_MATERIAL_
${
i
}
" target="#
${
id
}
" >`
+
'
<bind_vertex_input semantic="TEXCOORD" input_semantic="TEXCOORD" input_set="0" />
'
+
'
</instance_material>
'
).
join
(
''
)
+
'
</technique_common></bind_material>
'
:
''
)
+
'
</instance_geometry>
'
;
}
o
.
children
.
forEach
(
c
=>
node
+=
processObject
(
c
)
);
node
+=
'
</node>
'
;
return
node
;
}
var
geometryInfo
=
new
WeakMap
();
var
materialMap
=
new
WeakMap
();
var
imageMap
=
new
WeakMap
();
var
textures
=
[];
var
libraryImages
=
[];
var
libraryGeometries
=
[];
var
libraryEffects
=
[];
var
libraryMaterials
=
[];
var
libraryVisualScenes
=
processObject
(
object
);
var
specLink
=
version
===
'
1.4.1
'
?
'
http://www.collada.org/2005/11/COLLADASchema
'
:
'
https://www.khronos.org/collada/
'
;
var
dae
=
'
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
'
+
`<COLLADA xmlns="
${
specLink
}
" version="
${
version
}
">`
+
'
<asset>
'
+
(
'
<contributor>
'
+
'
<authoring_tool>THREE.js Collada Exporter</authoring_tool>
'
+
(
options
.
author
!==
null
?
`<author>
${
options
.
author
}
</author>`
:
''
)
+
'
</contributor>
'
+
`<created>
${
(
new
Date
()
).
toISOString
()
}
</created>`
+
`<modified>
${
(
new
Date
()
).
toISOString
()
}
</modified>`
+
'
<up_axis>Y_UP</up_axis>
'
)
+
'
</asset>
'
;
dae
+=
`<library_images>
${
libraryImages
.
join
(
''
)
}
</library_images>`
;
dae
+=
`<library_effects>
${
libraryEffects
.
join
(
''
)
}
</library_effects>`
;
dae
+=
`<library_materials>
${
libraryMaterials
.
join
(
''
)
}
</library_materials>`
;
dae
+=
`<library_geometries>
${
libraryGeometries
.
join
(
''
)
}
</library_geometries>`
;
dae
+=
`<library_visual_scenes><visual_scene id="Scene" name="scene">
${
libraryVisualScenes
}
</visual_scene></library_visual_scenes>`
;
dae
+=
'
<scene><instance_visual_scene url="#Scene"/></scene>
'
;
dae
+=
'
</COLLADA>
'
;
var
res
=
{
data
:
format
(
dae
),
textures
};
if
(
typeof
onDone
===
'
function
'
)
{
requestAnimationFrame
(
()
=>
onDone
(
res
)
);
}
return
res
;
}
};
export
{
ColladaExporter
};
examples/jsm/exporters/GLTFExporter.js
浏览文件 @
d7fd8412
...
...
@@ -59,36 +59,26 @@ var PATH_PROPERTIES = {
// GLTF Exporter
//------------------------------------------------------------------------------
import
{
AnimationClip
,
BufferAttribute
,
BufferGeometry
,
Camera
,
ClampToEdgeWrapping
,
DoubleSide
,
Geometry
,
InterpolateDiscrete
,
LinearFilter
,
LinearMipMapLinearFilter
,
LinearMipMapNearestFilter
,
Material
,
Math
,
Mesh
,
Math
as
_Math
,
MirroredRepeatWrapping
,
NearestFilter
,
NearestMipMapLinearFilter
,
NearestMipMapNearestFilter
,
Object3D
,
PropertyBinding
,
RGBAFormat
,
RGBFormat
,
RepeatWrapping
,
Scene
,
Scenes
,
ShaderMaterial
,
TriangleFanDrawMode
,
TriangleStripDrawMode
,
Vector3
,
VertexColors
Vector3
}
from
"
../../../build/three.module.js
"
;
var
GLTFExporter
=
function
()
{};
...
...
@@ -99,7 +89,7 @@ GLTFExporter.prototype = {
/**
* Parse scenes and generate GLTF output
* @param {Scene or [
Scenes]} input Scene or Array of
Scenes
* @param {Scene or [
THREE.Scenes]} input Scene or Array of THREE.
Scenes
* @param {Function} onDone Callback on completed
* @param {Object} options options
*/
...
...
@@ -244,7 +234,7 @@ GLTFExporter.prototype = {
*/
function
isPowerOfTwo
(
image
)
{
return
Math
.
isPowerOfTwo
(
image
.
width
)
&&
Math
.
isPowerOfTwo
(
image
.
height
);
return
_Math
.
isPowerOfTwo
(
image
.
width
)
&&
_
Math
.
isPowerOfTwo
(
image
.
height
);
}
...
...
@@ -373,7 +363,7 @@ GLTFExporter.prototype = {
/**
* Serializes a userData.
*
* @param {
Object3D|
Material} object
* @param {
THREE.Object3D|THREE.
Material} object
* @param {Object} gltfProperty
*/
function
serializeUserData
(
object
,
gltfProperty
)
{
...
...
@@ -736,7 +726,7 @@ GLTFExporter.prototype = {
/**
* Process image
* @param {Image} image to process
* @param {Integer} format of the image (e.g. RGBFormat, RGBAFormat etc)
* @param {Integer} format of the image (e.g.
THREE.
RGBFormat, RGBAFormat etc)
* @param {Boolean} flipY before writing out the image
* @return {Integer} Index of the processed texture in the "images" array
*/
...
...
@@ -777,8 +767,8 @@ GLTFExporter.prototype = {
console
.
warn
(
'
GLTFExporter: Resized non-power-of-two image.
'
,
image
);
canvas
.
width
=
Math
.
floorPowerOfTwo
(
canvas
.
width
);
canvas
.
height
=
Math
.
floorPowerOfTwo
(
canvas
.
height
);
canvas
.
width
=
_
Math
.
floorPowerOfTwo
(
canvas
.
width
);
canvas
.
height
=
_
Math
.
floorPowerOfTwo
(
canvas
.
height
);
}
...
...
@@ -897,7 +887,7 @@ GLTFExporter.prototype = {
/**
* Process material
* @param {Material} material Material to process
* @param {
THREE.
Material} material Material to process
* @return {Integer} Index of the processed material in the "materials" array
*/
function
processMaterial
(
material
)
{
...
...
@@ -916,7 +906,7 @@ GLTFExporter.prototype = {
if
(
material
.
isShaderMaterial
)
{
console
.
warn
(
'
GLTFExporter: ShaderMaterial not supported.
'
);
console
.
warn
(
'
GLTFExporter:
THREE.
ShaderMaterial not supported.
'
);
return
null
;
}
...
...
@@ -1101,7 +1091,7 @@ GLTFExporter.prototype = {
/**
* Process mesh
* @param {Mesh} mesh Mesh to process
* @param {
THREE.
Mesh} mesh Mesh to process
* @return {Integer} Index of the processed mesh in the "meshes" array
*/
function
processMesh
(
mesh
)
{
...
...
@@ -1138,7 +1128,7 @@ GLTFExporter.prototype = {
if
(
!
geometry
.
isBufferGeometry
)
{
console
.
warn
(
'
GLTFExporter: Exporting Geometry will increase file size. Use BufferGeometry instead.
'
);
console
.
warn
(
'
GLTFExporter: Exporting
THREE.
Geometry will increase file size. Use BufferGeometry instead.
'
);
var
geometryTemp
=
new
BufferGeometry
();
geometryTemp
.
fromGeometry
(
geometry
);
...
...
@@ -1190,7 +1180,7 @@ GLTFExporter.prototype = {
}
// @QUESTION Detect if .vertexColors = VertexColors?
// @QUESTION Detect if .vertexColors =
THREE.
VertexColors?
// For every attribute create an accessor
var
modifiedAttribute
=
null
;
for
(
var
attributeName
in
geometry
.
attributes
)
{
...
...
@@ -1432,7 +1422,7 @@ GLTFExporter.prototype = {
/**
* Process camera
* @param {Camera} camera Camera to process
* @param {
THREE.
Camera} camera Camera to process
* @return {Integer} Index of the processed mesh in the "camera" array
*/
function
processCamera
(
camera
)
{
...
...
@@ -1467,7 +1457,7 @@ GLTFExporter.prototype = {
gltfCamera
.
perspective
=
{
aspectRatio
:
camera
.
aspect
,
yfov
:
Math
.
degToRad
(
camera
.
fov
),
yfov
:
_
Math
.
degToRad
(
camera
.
fov
),
zfar
:
camera
.
far
<=
0
?
0.001
:
camera
.
far
,
znear
:
camera
.
near
<
0
?
0
:
camera
.
near
...
...
@@ -1493,8 +1483,8 @@ GLTFExporter.prototype = {
* Status:
* - Only properties listed in PATH_PROPERTIES may be animated.
*
* @param {AnimationClip} clip
* @param {Object3D} root
* @param {
THREE.
AnimationClip} clip
* @param {
THREE.
Object3D} root
* @return {number}
*/
function
processAnimation
(
clip
,
root
)
{
...
...
@@ -1701,7 +1691,7 @@ GLTFExporter.prototype = {
/**
* Process Object3D node
* @param {Object3D} node Object3D to processNode
* @param {
THREE.
Object3D} node Object3D to processNode
* @return {Integer} Index of the node in the nodes list
*/
function
processNode
(
object
)
{
...
...
examples/jsm/exporters/MMDExporter.js
0 → 100644
浏览文件 @
d7fd8412
/**
* @author takahiro / http://github.com/takahirox
*
* Dependencies
* - mmd-parser https://github.com/takahirox/mmd-parser
*/
import
{
Matrix4
,
Quaternion
,
Vector3
}
from
"
../../../build/three.module.js
"
;
var
MMDExporter
=
function
()
{
// Unicode to Shift_JIS table
var
u2sTable
;
function
unicodeToShiftjis
(
str
)
{
if
(
u2sTable
===
undefined
)
{
var
encoder
=
new
MMDParser
.
CharsetEncoder
();
var
table
=
encoder
.
s2uTable
;
u2sTable
=
{};
var
keys
=
Object
.
keys
(
table
);
for
(
var
i
=
0
,
il
=
keys
.
length
;
i
<
il
;
i
++
)
{
var
key
=
keys
[
i
];
var
value
=
table
[
key
];
key
=
parseInt
(
key
);
u2sTable
[
value
]
=
key
;
}
}
var
array
=
[];
for
(
var
i
=
0
,
il
=
str
.
length
;
i
<
il
;
i
++
)
{
var
code
=
str
.
charCodeAt
(
i
);
var
value
=
u2sTable
[
code
];
if
(
value
===
undefined
)
{
throw
'
cannot convert charcode 0x
'
+
code
.
toString
(
16
);
}
else
if
(
value
>
0xff
)
{
array
.
push
(
(
value
>>
8
)
&
0xff
);
array
.
push
(
value
&
0xff
);
}
else
{
array
.
push
(
value
&
0xff
);
}
}
return
new
Uint8Array
(
array
);
}
function
getBindBones
(
skin
)
{
// any more efficient ways?
var
poseSkin
=
skin
.
clone
();
poseSkin
.
pose
();
return
poseSkin
.
skeleton
.
bones
;
}
/* TODO: implement
// mesh -> pmd
this.parsePmd = function ( object ) {
};
*/
/* TODO: implement
// mesh -> pmx
this.parsePmx = function ( object ) {
};
*/
/*
* skeleton -> vpd
* Returns Shift_JIS encoded Uint8Array. Otherwise return strings.
*/
this
.
parseVpd
=
function
(
skin
,
outputShiftJis
,
useOriginalBones
)
{
if
(
skin
.
isSkinnedMesh
!==
true
)
{
console
.
warn
(
'
THREE.MMDExporter: parseVpd() requires SkinnedMesh instance.
'
);
return
null
;
}
function
toStringsFromNumber
(
num
)
{
if
(
Math
.
abs
(
num
)
<
1
e
-
6
)
num
=
0
;
var
a
=
num
.
toString
();
if
(
a
.
indexOf
(
'
.
'
)
===
-
1
)
{
a
+=
'
.
'
;
}
a
+=
'
000000
'
;
var
index
=
a
.
indexOf
(
'
.
'
);
var
d
=
a
.
slice
(
0
,
index
);
var
p
=
a
.
slice
(
index
+
1
,
index
+
7
);
return
d
+
'
.
'
+
p
;
}
function
toStringsFromArray
(
array
)
{
var
a
=
[];
for
(
var
i
=
0
,
il
=
array
.
length
;
i
<
il
;
i
++
)
{
a
.
push
(
toStringsFromNumber
(
array
[
i
]
)
);
}
return
a
.
join
(
'
,
'
);
}
skin
.
updateMatrixWorld
(
true
);
var
bones
=
skin
.
skeleton
.
bones
;
var
bones2
=
getBindBones
(
skin
);
var
position
=
new
Vector3
();
var
quaternion
=
new
Quaternion
();
var
quaternion2
=
new
Quaternion
();
var
matrix
=
new
Matrix4
();
var
array
=
[];
array
.
push
(
'
Vocaloid Pose Data file
'
);
array
.
push
(
''
);
array
.
push
(
(
skin
.
name
!==
''
?
skin
.
name
.
replace
(
/
\s
/g
,
'
_
'
)
:
'
skin
'
)
+
'
.osm;
'
);
array
.
push
(
bones
.
length
+
'
;
'
);
array
.
push
(
''
);
for
(
var
i
=
0
,
il
=
bones
.
length
;
i
<
il
;
i
++
)
{
var
bone
=
bones
[
i
];
var
bone2
=
bones2
[
i
];
/*
* use the bone matrix saved before solving IK.
* see CCDIKSolver for the detail.
*/
if
(
useOriginalBones
===
true
&&
bone
.
userData
.
ik
!==
undefined
&&
bone
.
userData
.
ik
.
originalMatrix
!==
undefined
)
{
matrix
.
fromArray
(
bone
.
userData
.
ik
.
originalMatrix
);
}
else
{
matrix
.
copy
(
bone
.
matrix
);
}
position
.
setFromMatrixPosition
(
matrix
);
quaternion
.
setFromRotationMatrix
(
matrix
);
var
pArray
=
position
.
sub
(
bone2
.
position
).
toArray
();
var
qArray
=
quaternion2
.
copy
(
bone2
.
quaternion
).
conjugate
().
multiply
(
quaternion
).
toArray
();
// right to left
pArray
[
2
]
=
-
pArray
[
2
];
qArray
[
0
]
=
-
qArray
[
0
];
qArray
[
1
]
=
-
qArray
[
1
];
array
.
push
(
'
Bone
'
+
i
+
'
{
'
+
bone
.
name
);
array
.
push
(
'
'
+
toStringsFromArray
(
pArray
)
+
'
;
'
);
array
.
push
(
'
'
+
toStringsFromArray
(
qArray
)
+
'
;
'
);
array
.
push
(
'
}
'
);
array
.
push
(
''
);
}
array
.
push
(
''
);
var
lines
=
array
.
join
(
'
\n
'
);
return
(
outputShiftJis
===
true
)
?
unicodeToShiftjis
(
lines
)
:
lines
;
};
/* TODO: implement
// animation + skeleton -> vmd
this.parseVmd = function ( object ) {
};
*/
};
export
{
MMDExporter
};
examples/jsm/exporters/OBJExporter.js
0 → 100644
浏览文件 @
d7fd8412
/**
* @author mrdoob / http://mrdoob.com/
*/
import
{
BufferGeometry
,
Geometry
,
Line
,
Matrix3
,
Mesh
,
Vector2
,
Vector3
}
from
"
../../../build/three.module.js
"
;
var
OBJExporter
=
function
()
{};
OBJExporter
.
prototype
=
{
constructor
:
OBJExporter
,
parse
:
function
(
object
)
{
var
output
=
''
;
var
indexVertex
=
0
;
var
indexVertexUvs
=
0
;
var
indexNormals
=
0
;
var
vertex
=
new
Vector3
();
var
normal
=
new
Vector3
();
var
uv
=
new
Vector2
();
var
i
,
j
,
k
,
l
,
m
,
face
=
[];
var
parseMesh
=
function
(
mesh
)
{
var
nbVertex
=
0
;
var
nbNormals
=
0
;
var
nbVertexUvs
=
0
;
var
geometry
=
mesh
.
geometry
;
var
normalMatrixWorld
=
new
Matrix3
();
if
(
geometry
instanceof
Geometry
)
{
geometry
=
new
BufferGeometry
().
setFromObject
(
mesh
);
}
if
(
geometry
instanceof
BufferGeometry
)
{
// shortcuts
var
vertices
=
geometry
.
getAttribute
(
'
position
'
);
var
normals
=
geometry
.
getAttribute
(
'
normal
'
);
var
uvs
=
geometry
.
getAttribute
(
'
uv
'
);
var
indices
=
geometry
.
getIndex
();
// name of the mesh object
output
+=
'
o
'
+
mesh
.
name
+
'
\n
'
;
// name of the mesh material
if
(
mesh
.
material
&&
mesh
.
material
.
name
)
{
output
+=
'
usemtl
'
+
mesh
.
material
.
name
+
'
\n
'
;
}
// vertices
if
(
vertices
!==
undefined
)
{
for
(
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
++
,
nbVertex
++
)
{
vertex
.
x
=
vertices
.
getX
(
i
);
vertex
.
y
=
vertices
.
getY
(
i
);
vertex
.
z
=
vertices
.
getZ
(
i
);
// transfrom the vertex to world space
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
// transform the vertex to export format
output
+=
'
v
'
+
vertex
.
x
+
'
'
+
vertex
.
y
+
'
'
+
vertex
.
z
+
'
\n
'
;
}
}
// uvs
if
(
uvs
!==
undefined
)
{
for
(
i
=
0
,
l
=
uvs
.
count
;
i
<
l
;
i
++
,
nbVertexUvs
++
)
{
uv
.
x
=
uvs
.
getX
(
i
);
uv
.
y
=
uvs
.
getY
(
i
);
// transform the uv to export format
output
+=
'
vt
'
+
uv
.
x
+
'
'
+
uv
.
y
+
'
\n
'
;
}
}
// normals
if
(
normals
!==
undefined
)
{
normalMatrixWorld
.
getNormalMatrix
(
mesh
.
matrixWorld
);
for
(
i
=
0
,
l
=
normals
.
count
;
i
<
l
;
i
++
,
nbNormals
++
)
{
normal
.
x
=
normals
.
getX
(
i
);
normal
.
y
=
normals
.
getY
(
i
);
normal
.
z
=
normals
.
getZ
(
i
);
// transfrom the normal to world space
normal
.
applyMatrix3
(
normalMatrixWorld
);
// transform the normal to export format
output
+=
'
vn
'
+
normal
.
x
+
'
'
+
normal
.
y
+
'
'
+
normal
.
z
+
'
\n
'
;
}
}
// faces
if
(
indices
!==
null
)
{
for
(
i
=
0
,
l
=
indices
.
count
;
i
<
l
;
i
+=
3
)
{
for
(
m
=
0
;
m
<
3
;
m
++
)
{
j
=
indices
.
getX
(
i
+
m
)
+
1
;
face
[
m
]
=
(
indexVertex
+
j
)
+
(
normals
||
uvs
?
'
/
'
+
(
uvs
?
(
indexVertexUvs
+
j
)
:
''
)
+
(
normals
?
'
/
'
+
(
indexNormals
+
j
)
:
''
)
:
''
);
}
// transform the face to export format
output
+=
'
f
'
+
face
.
join
(
'
'
)
+
"
\n
"
;
}
}
else
{
for
(
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
+=
3
)
{
for
(
m
=
0
;
m
<
3
;
m
++
)
{
j
=
i
+
m
+
1
;
face
[
m
]
=
(
indexVertex
+
j
)
+
(
normals
||
uvs
?
'
/
'
+
(
uvs
?
(
indexVertexUvs
+
j
)
:
''
)
+
(
normals
?
'
/
'
+
(
indexNormals
+
j
)
:
''
)
:
''
);
}
// transform the face to export format
output
+=
'
f
'
+
face
.
join
(
'
'
)
+
"
\n
"
;
}
}
}
else
{
console
.
warn
(
'
THREE.OBJExporter.parseMesh(): geometry type unsupported
'
,
geometry
);
}
// update index
indexVertex
+=
nbVertex
;
indexVertexUvs
+=
nbVertexUvs
;
indexNormals
+=
nbNormals
;
};
var
parseLine
=
function
(
line
)
{
var
nbVertex
=
0
;
var
geometry
=
line
.
geometry
;
var
type
=
line
.
type
;
if
(
geometry
instanceof
Geometry
)
{
geometry
=
new
BufferGeometry
().
setFromObject
(
line
);
}
if
(
geometry
instanceof
BufferGeometry
)
{
// shortcuts
var
vertices
=
geometry
.
getAttribute
(
'
position
'
);
// name of the line object
output
+=
'
o
'
+
line
.
name
+
'
\n
'
;
if
(
vertices
!==
undefined
)
{
for
(
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
++
,
nbVertex
++
)
{
vertex
.
x
=
vertices
.
getX
(
i
);
vertex
.
y
=
vertices
.
getY
(
i
);
vertex
.
z
=
vertices
.
getZ
(
i
);
// transfrom the vertex to world space
vertex
.
applyMatrix4
(
line
.
matrixWorld
);
// transform the vertex to export format
output
+=
'
v
'
+
vertex
.
x
+
'
'
+
vertex
.
y
+
'
'
+
vertex
.
z
+
'
\n
'
;
}
}
if
(
type
===
'
Line
'
)
{
output
+=
'
l
'
;
for
(
j
=
1
,
l
=
vertices
.
count
;
j
<=
l
;
j
++
)
{
output
+=
(
indexVertex
+
j
)
+
'
'
;
}
output
+=
'
\n
'
;
}
if
(
type
===
'
LineSegments
'
)
{
for
(
j
=
1
,
k
=
j
+
1
,
l
=
vertices
.
count
;
j
<
l
;
j
+=
2
,
k
=
j
+
1
)
{
output
+=
'
l
'
+
(
indexVertex
+
j
)
+
'
'
+
(
indexVertex
+
k
)
+
'
\n
'
;
}
}
}
else
{
console
.
warn
(
'
THREE.OBJExporter.parseLine(): geometry type unsupported
'
,
geometry
);
}
// update index
indexVertex
+=
nbVertex
;
};
object
.
traverse
(
function
(
child
)
{
if
(
child
instanceof
Mesh
)
{
parseMesh
(
child
);
}
if
(
child
instanceof
Line
)
{
parseLine
(
child
);
}
}
);
return
output
;
}
};
export
{
OBJExporter
};
examples/jsm/exporters/PLYExporter.js
0 → 100644
浏览文件 @
d7fd8412
/**
* @author Garrett Johnson / http://gkjohnson.github.io/
* https://github.com/gkjohnson/ply-exporter-js
*
* Usage:
* var exporter = new PLYExporter();
*
* // second argument is a list of options
* exporter.parse(mesh, data => console.log(data), { binary: true, excludeAttributes: [ 'color' ] });
*
* Format Definition:
* http://paulbourke.net/dataformats/ply/
*/
import
{
BufferGeometry
,
Matrix3
,
Vector3
}
from
"
../../../build/three.module.js
"
;
var
PLYExporter
=
function
()
{};
PLYExporter
.
prototype
=
{
constructor
:
PLYExporter
,
parse
:
function
(
object
,
onDone
,
options
)
{
if
(
onDone
&&
typeof
onDone
===
'
object
'
)
{
console
.
warn
(
'
THREE.PLYExporter: The options parameter is now the third argument to the "parse" function. See the documentation for the new API.
'
);
options
=
onDone
;
onDone
=
undefined
;
}
// Iterate over the valid meshes in the object
function
traverseMeshes
(
cb
)
{
object
.
traverse
(
function
(
child
)
{
if
(
child
.
isMesh
===
true
)
{
var
mesh
=
child
;
var
geometry
=
mesh
.
geometry
;
if
(
geometry
.
isGeometry
===
true
)
{
geometry
=
geomToBufferGeom
.
get
(
geometry
);
}
if
(
geometry
.
isBufferGeometry
===
true
)
{
if
(
geometry
.
getAttribute
(
'
position
'
)
!==
undefined
)
{
cb
(
mesh
,
geometry
);
}
}
}
}
);
}
// Default options
var
defaultOptions
=
{
binary
:
false
,
excludeAttributes
:
[]
// normal, uv, color, index
};
options
=
Object
.
assign
(
defaultOptions
,
options
);
var
excludeAttributes
=
options
.
excludeAttributes
;
var
geomToBufferGeom
=
new
WeakMap
();
var
includeNormals
=
false
;
var
includeColors
=
false
;
var
includeUVs
=
false
;
// count the vertices, check which properties are used,
// and cache the BufferGeometry
var
vertexCount
=
0
;
var
faceCount
=
0
;
object
.
traverse
(
function
(
child
)
{
if
(
child
.
isMesh
===
true
)
{
var
mesh
=
child
;
var
geometry
=
mesh
.
geometry
;
if
(
geometry
.
isGeometry
===
true
)
{
var
bufferGeometry
=
geomToBufferGeom
.
get
(
geometry
)
||
new
BufferGeometry
().
setFromObject
(
mesh
);
geomToBufferGeom
.
set
(
geometry
,
bufferGeometry
);
geometry
=
bufferGeometry
;
}
if
(
geometry
.
isBufferGeometry
===
true
)
{
var
vertices
=
geometry
.
getAttribute
(
'
position
'
);
var
normals
=
geometry
.
getAttribute
(
'
normal
'
);
var
uvs
=
geometry
.
getAttribute
(
'
uv
'
);
var
colors
=
geometry
.
getAttribute
(
'
color
'
);
var
indices
=
geometry
.
getIndex
();
if
(
vertices
===
undefined
)
{
return
;
}
vertexCount
+=
vertices
.
count
;
faceCount
+=
indices
?
indices
.
count
/
3
:
vertices
.
count
/
3
;
if
(
normals
!==
undefined
)
includeNormals
=
true
;
if
(
uvs
!==
undefined
)
includeUVs
=
true
;
if
(
colors
!==
undefined
)
includeColors
=
true
;
}
}
}
);
var
includeIndices
=
excludeAttributes
.
indexOf
(
'
index
'
)
===
-
1
;
includeNormals
=
includeNormals
&&
excludeAttributes
.
indexOf
(
'
normal
'
)
===
-
1
;
includeColors
=
includeColors
&&
excludeAttributes
.
indexOf
(
'
color
'
)
===
-
1
;
includeUVs
=
includeUVs
&&
excludeAttributes
.
indexOf
(
'
uv
'
)
===
-
1
;
if
(
includeIndices
&&
faceCount
!==
Math
.
floor
(
faceCount
)
)
{
// point cloud meshes will not have an index array and may not have a
// number of vertices that is divisble by 3 (and therefore representable
// as triangles)
console
.
error
(
'
PLYExporter: Failed to generate a valid PLY file with triangle indices because the
'
+
'
number of indices is not divisible by 3.
'
);
return
null
;
}
// get how many bytes will be needed to save out the faces
// so we can use a minimal amount of memory / data
var
indexByteCount
=
1
;
if
(
vertexCount
>
256
)
{
// 2^8 bits
indexByteCount
=
2
;
}
if
(
vertexCount
>
65536
)
{
// 2^16 bits
indexByteCount
=
4
;
}
var
header
=
'
ply
\n
'
+
`format
${
options
.
binary
?
'
binary_big_endian
'
:
'
ascii
'
}
1.0\n`
+
`element vertex
${
vertexCount
}
\n`
+
// position
'
property float x
\n
'
+
'
property float y
\n
'
+
'
property float z
\n
'
;
if
(
includeNormals
===
true
)
{
// normal
header
+=
'
property float nx
\n
'
+
'
property float ny
\n
'
+
'
property float nz
\n
'
;
}
if
(
includeUVs
===
true
)
{
// uvs
header
+=
'
property float s
\n
'
+
'
property float t
\n
'
;
}
if
(
includeColors
===
true
)
{
// colors
header
+=
'
property uchar red
\n
'
+
'
property uchar green
\n
'
+
'
property uchar blue
\n
'
;
}
if
(
includeIndices
===
true
)
{
// faces
header
+=
`element face
${
faceCount
}
\n`
+
`property list uchar uint
${
indexByteCount
*
8
}
vertex_index\n`
;
}
header
+=
'
end_header
\n
'
;
// Generate attribute data
var
vertex
=
new
Vector3
();
var
normalMatrixWorld
=
new
Matrix3
();
var
result
=
null
;
if
(
options
.
binary
===
true
)
{
// Binary File Generation
var
headerBin
=
new
TextEncoder
().
encode
(
header
);
// 3 position values at 4 bytes
// 3 normal values at 4 bytes
// 3 color channels with 1 byte
// 2 uv values at 4 bytes
var
vertexListLength
=
vertexCount
*
(
4
*
3
+
(
includeNormals
?
4
*
3
:
0
)
+
(
includeColors
?
3
:
0
)
+
(
includeUVs
?
4
*
2
:
0
)
);
// 1 byte shape desciptor
// 3 vertex indices at ${indexByteCount} bytes
var
faceListLength
=
includeIndices
?
faceCount
*
(
indexByteCount
*
3
+
1
)
:
0
;
var
output
=
new
DataView
(
new
ArrayBuffer
(
headerBin
.
length
+
vertexListLength
+
faceListLength
)
);
new
Uint8Array
(
output
.
buffer
).
set
(
headerBin
,
0
);
var
vOffset
=
headerBin
.
length
;
var
fOffset
=
headerBin
.
length
+
vertexListLength
;
var
writtenVertices
=
0
;
traverseMeshes
(
function
(
mesh
,
geometry
)
{
var
vertices
=
geometry
.
getAttribute
(
'
position
'
);
var
normals
=
geometry
.
getAttribute
(
'
normal
'
);
var
uvs
=
geometry
.
getAttribute
(
'
uv
'
);
var
colors
=
geometry
.
getAttribute
(
'
color
'
);
var
indices
=
geometry
.
getIndex
();
normalMatrixWorld
.
getNormalMatrix
(
mesh
.
matrixWorld
);
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
++
)
{
vertex
.
x
=
vertices
.
getX
(
i
);
vertex
.
y
=
vertices
.
getY
(
i
);
vertex
.
z
=
vertices
.
getZ
(
i
);
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
// Position information
output
.
setFloat32
(
vOffset
,
vertex
.
x
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
vertex
.
y
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
vertex
.
z
);
vOffset
+=
4
;
// Normal information
if
(
includeNormals
===
true
)
{
if
(
normals
!=
null
)
{
vertex
.
x
=
normals
.
getX
(
i
);
vertex
.
y
=
normals
.
getY
(
i
);
vertex
.
z
=
normals
.
getZ
(
i
);
vertex
.
applyMatrix3
(
normalMatrixWorld
);
output
.
setFloat32
(
vOffset
,
vertex
.
x
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
vertex
.
y
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
vertex
.
z
);
vOffset
+=
4
;
}
else
{
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
}
}
// UV information
if
(
includeUVs
===
true
)
{
if
(
uvs
!=
null
)
{
output
.
setFloat32
(
vOffset
,
uvs
.
getX
(
i
)
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
uvs
.
getY
(
i
)
);
vOffset
+=
4
;
}
else
if
(
includeUVs
!==
false
)
{
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
}
}
// Color information
if
(
includeColors
===
true
)
{
if
(
colors
!=
null
)
{
output
.
setUint8
(
vOffset
,
Math
.
floor
(
colors
.
getX
(
i
)
*
255
)
);
vOffset
+=
1
;
output
.
setUint8
(
vOffset
,
Math
.
floor
(
colors
.
getY
(
i
)
*
255
)
);
vOffset
+=
1
;
output
.
setUint8
(
vOffset
,
Math
.
floor
(
colors
.
getZ
(
i
)
*
255
)
);
vOffset
+=
1
;
}
else
{
output
.
setUint8
(
vOffset
,
255
);
vOffset
+=
1
;
output
.
setUint8
(
vOffset
,
255
);
vOffset
+=
1
;
output
.
setUint8
(
vOffset
,
255
);
vOffset
+=
1
;
}
}
}
if
(
includeIndices
===
true
)
{
// Create the face list
var
faceIndexFunc
=
`setUint
${
indexByteCount
*
8
}
`
;
if
(
indices
!==
null
)
{
for
(
var
i
=
0
,
l
=
indices
.
count
;
i
<
l
;
i
+=
3
)
{
output
.
setUint8
(
fOffset
,
3
);
fOffset
+=
1
;
output
[
faceIndexFunc
](
fOffset
,
indices
.
getX
(
i
+
0
)
+
writtenVertices
);
fOffset
+=
indexByteCount
;
output
[
faceIndexFunc
](
fOffset
,
indices
.
getX
(
i
+
1
)
+
writtenVertices
);
fOffset
+=
indexByteCount
;
output
[
faceIndexFunc
](
fOffset
,
indices
.
getX
(
i
+
2
)
+
writtenVertices
);
fOffset
+=
indexByteCount
;
}
}
else
{
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
+=
3
)
{
output
.
setUint8
(
fOffset
,
3
);
fOffset
+=
1
;
output
[
faceIndexFunc
](
fOffset
,
writtenVertices
+
i
);
fOffset
+=
indexByteCount
;
output
[
faceIndexFunc
](
fOffset
,
writtenVertices
+
i
+
1
);
fOffset
+=
indexByteCount
;
output
[
faceIndexFunc
](
fOffset
,
writtenVertices
+
i
+
2
);
fOffset
+=
indexByteCount
;
}
}
}
// Save the amount of verts we've already written so we can offset
// the face index on the next mesh
writtenVertices
+=
vertices
.
count
;
}
);
result
=
output
.
buffer
;
}
else
{
// Ascii File Generation
// count the number of vertices
var
writtenVertices
=
0
;
var
vertexList
=
''
;
var
faceList
=
''
;
traverseMeshes
(
function
(
mesh
,
geometry
)
{
var
vertices
=
geometry
.
getAttribute
(
'
position
'
);
var
normals
=
geometry
.
getAttribute
(
'
normal
'
);
var
uvs
=
geometry
.
getAttribute
(
'
uv
'
);
var
colors
=
geometry
.
getAttribute
(
'
color
'
);
var
indices
=
geometry
.
getIndex
();
normalMatrixWorld
.
getNormalMatrix
(
mesh
.
matrixWorld
);
// form each line
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
++
)
{
vertex
.
x
=
vertices
.
getX
(
i
);
vertex
.
y
=
vertices
.
getY
(
i
);
vertex
.
z
=
vertices
.
getZ
(
i
);
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
// Position information
var
line
=
vertex
.
x
+
'
'
+
vertex
.
y
+
'
'
+
vertex
.
z
;
// Normal information
if
(
includeNormals
===
true
)
{
if
(
normals
!=
null
)
{
vertex
.
x
=
normals
.
getX
(
i
);
vertex
.
y
=
normals
.
getY
(
i
);
vertex
.
z
=
normals
.
getZ
(
i
);
vertex
.
applyMatrix3
(
normalMatrixWorld
);
line
+=
'
'
+
vertex
.
x
+
'
'
+
vertex
.
y
+
'
'
+
vertex
.
z
;
}
else
{
line
+=
'
0 0 0
'
;
}
}
// UV information
if
(
includeUVs
===
true
)
{
if
(
uvs
!=
null
)
{
line
+=
'
'
+
uvs
.
getX
(
i
)
+
'
'
+
uvs
.
getY
(
i
);
}
else
if
(
includeUVs
!==
false
)
{
line
+=
'
0 0
'
;
}
}
// Color information
if
(
includeColors
===
true
)
{
if
(
colors
!=
null
)
{
line
+=
'
'
+
Math
.
floor
(
colors
.
getX
(
i
)
*
255
)
+
'
'
+
Math
.
floor
(
colors
.
getY
(
i
)
*
255
)
+
'
'
+
Math
.
floor
(
colors
.
getZ
(
i
)
*
255
);
}
else
{
line
+=
'
255 255 255
'
;
}
}
vertexList
+=
line
+
'
\n
'
;
}
// Create the face list
if
(
includeIndices
===
true
)
{
if
(
indices
!==
null
)
{
for
(
var
i
=
0
,
l
=
indices
.
count
;
i
<
l
;
i
+=
3
)
{
faceList
+=
`3
${
indices
.
getX
(
i
+
0
)
+
writtenVertices
}
`
;
faceList
+=
`
${
indices
.
getX
(
i
+
1
)
+
writtenVertices
}
`
;
faceList
+=
`
${
indices
.
getX
(
i
+
2
)
+
writtenVertices
}
\n`
;
}
}
else
{
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
+=
3
)
{
faceList
+=
`3
${
writtenVertices
+
i
}
${
writtenVertices
+
i
+
1
}
${
writtenVertices
+
i
+
2
}
\n`
;
}
}
faceCount
+=
indices
?
indices
.
count
/
3
:
vertices
.
count
/
3
;
}
writtenVertices
+=
vertices
.
count
;
}
);
result
=
`
${
header
}${
vertexList
}
\n
${
includeIndices
?
`
${
faceList
}
\n`
:
''
}
`
;
}
if
(
typeof
onDone
===
'
function
'
)
requestAnimationFrame
(
()
=>
onDone
(
result
)
);
return
result
;
}
};
export
{
PLYExporter
};
examples/jsm/exporters/STLExporter.js
0 → 100644
浏览文件 @
d7fd8412
/**
* @author kovacsv / http://kovacsv.hu/
* @author mrdoob / http://mrdoob.com/
* @author mudcube / http://mudcu.be/
* @author Mugen87 / https://github.com/Mugen87
*
* Usage:
* var exporter = new STLExporter();
*
* // second argument is a list of options
* var data = exporter.parse( mesh, { binary: true } );
*
*/
import
{
Geometry
,
Matrix3
,
Vector3
}
from
"
../../../build/three.module.js
"
;
var
STLExporter
=
function
()
{};
STLExporter
.
prototype
=
{
constructor
:
STLExporter
,
parse
:
(
function
()
{
var
vector
=
new
Vector3
();
var
normalMatrixWorld
=
new
Matrix3
();
return
function
parse
(
scene
,
options
)
{
if
(
options
===
undefined
)
options
=
{};
var
binary
=
options
.
binary
!==
undefined
?
options
.
binary
:
false
;
//
var
objects
=
[];
var
triangles
=
0
;
scene
.
traverse
(
function
(
object
)
{
if
(
object
.
isMesh
)
{
var
geometry
=
object
.
geometry
;
if
(
geometry
.
isBufferGeometry
)
{
geometry
=
new
Geometry
().
fromBufferGeometry
(
geometry
);
}
if
(
geometry
.
isGeometry
)
{
triangles
+=
geometry
.
faces
.
length
;
objects
.
push
(
{
geometry
:
geometry
,
matrixWorld
:
object
.
matrixWorld
}
);
}
}
}
);
if
(
binary
)
{
var
offset
=
80
;
// skip header
var
bufferLength
=
triangles
*
2
+
triangles
*
3
*
4
*
4
+
80
+
4
;
var
arrayBuffer
=
new
ArrayBuffer
(
bufferLength
);
var
output
=
new
DataView
(
arrayBuffer
);
output
.
setUint32
(
offset
,
triangles
,
true
);
offset
+=
4
;
for
(
var
i
=
0
,
il
=
objects
.
length
;
i
<
il
;
i
++
)
{
var
object
=
objects
[
i
];
var
vertices
=
object
.
geometry
.
vertices
;
var
faces
=
object
.
geometry
.
faces
;
var
matrixWorld
=
object
.
matrixWorld
;
normalMatrixWorld
.
getNormalMatrix
(
matrixWorld
);
for
(
var
j
=
0
,
jl
=
faces
.
length
;
j
<
jl
;
j
++
)
{
var
face
=
faces
[
j
];
vector
.
copy
(
face
.
normal
).
applyMatrix3
(
normalMatrixWorld
).
normalize
();
output
.
setFloat32
(
offset
,
vector
.
x
,
true
);
offset
+=
4
;
// normal
output
.
setFloat32
(
offset
,
vector
.
y
,
true
);
offset
+=
4
;
output
.
setFloat32
(
offset
,
vector
.
z
,
true
);
offset
+=
4
;
var
indices
=
[
face
.
a
,
face
.
b
,
face
.
c
];
for
(
var
k
=
0
;
k
<
3
;
k
++
)
{
vector
.
copy
(
vertices
[
indices
[
k
]
]
).
applyMatrix4
(
matrixWorld
);
output
.
setFloat32
(
offset
,
vector
.
x
,
true
);
offset
+=
4
;
// vertices
output
.
setFloat32
(
offset
,
vector
.
y
,
true
);
offset
+=
4
;
output
.
setFloat32
(
offset
,
vector
.
z
,
true
);
offset
+=
4
;
}
output
.
setUint16
(
offset
,
0
,
true
);
offset
+=
2
;
// attribute byte count
}
}
return
output
;
}
else
{
var
output
=
''
;
output
+=
'
solid exported
\n
'
;
for
(
var
i
=
0
,
il
=
objects
.
length
;
i
<
il
;
i
++
)
{
var
object
=
objects
[
i
];
var
vertices
=
object
.
geometry
.
vertices
;
var
faces
=
object
.
geometry
.
faces
;
var
matrixWorld
=
object
.
matrixWorld
;
normalMatrixWorld
.
getNormalMatrix
(
matrixWorld
);
for
(
var
j
=
0
,
jl
=
faces
.
length
;
j
<
jl
;
j
++
)
{
var
face
=
faces
[
j
];
vector
.
copy
(
face
.
normal
).
applyMatrix3
(
normalMatrixWorld
).
normalize
();
output
+=
'
\t
facet normal
'
+
vector
.
x
+
'
'
+
vector
.
y
+
'
'
+
vector
.
z
+
'
\n
'
;
output
+=
'
\t\t
outer loop
\n
'
;
var
indices
=
[
face
.
a
,
face
.
b
,
face
.
c
];
for
(
var
k
=
0
;
k
<
3
;
k
++
)
{
vector
.
copy
(
vertices
[
indices
[
k
]
]
).
applyMatrix4
(
matrixWorld
);
output
+=
'
\t\t\t
vertex
'
+
vector
.
x
+
'
'
+
vector
.
y
+
'
'
+
vector
.
z
+
'
\n
'
;
}
output
+=
'
\t\t
endloop
\n
'
;
output
+=
'
\t
endfacet
\n
'
;
}
}
output
+=
'
endsolid exported
\n
'
;
return
output
;
}
};
}()
)
};
export
{
STLExporter
};
examples/jsm/exporters/TypedGeometryExporter.js
0 → 100644
浏览文件 @
d7fd8412
/**
* @author mrdoob / http://mrdoob.com/
*/
var
TypedGeometryExporter
=
function
()
{};
TypedGeometryExporter
.
prototype
=
{
constructor
:
TypedGeometryExporter
,
parse
:
function
(
geometry
)
{
var
output
=
{
metadata
:
{
version
:
4.0
,
type
:
'
TypedGeometry
'
,
generator
:
'
TypedGeometryExporter
'
}
};
var
attributes
=
[
'
vertices
'
,
'
normals
'
,
'
uvs
'
];
for
(
var
key
in
attributes
)
{
var
attribute
=
attributes
[
key
];
var
typedArray
=
geometry
[
attribute
];
var
array
=
[];
for
(
var
i
=
0
,
l
=
typedArray
.
length
;
i
<
l
;
i
++
)
{
array
[
i
]
=
typedArray
[
i
];
}
output
[
attribute
]
=
array
;
}
var
boundingSphere
=
geometry
.
boundingSphere
;
if
(
boundingSphere
!==
null
)
{
output
.
boundingSphere
=
{
center
:
boundingSphere
.
center
.
toArray
(),
radius
:
boundingSphere
.
radius
};
}
return
output
;
}
};
export
{
TypedGeometryExporter
};
examples/jsm/loaders/GLTFLoader.js
浏览文件 @
d7fd8412
...
...
@@ -44,7 +44,7 @@ import {
Loader
,
LoaderUtils
,
Material
,
Math
,
Math
as
_Math
,
Matrix3
,
Matrix4
,
Mesh
,
...
...
@@ -2793,7 +2793,7 @@ var GLTFLoader = ( function () {
if
(
cameraDef
.
type
===
'
perspective
'
)
{
camera
=
new
PerspectiveCamera
(
Math
.
radToDeg
(
params
.
yfov
),
params
.
aspectRatio
||
1
,
params
.
znear
||
1
,
params
.
zfar
||
2
e6
);
camera
=
new
PerspectiveCamera
(
_
Math
.
radToDeg
(
params
.
yfov
),
params
.
aspectRatio
||
1
,
params
.
znear
||
1
,
params
.
zfar
||
2
e6
);
}
else
if
(
cameraDef
.
type
===
'
orthographic
'
)
{
...
...
utils/modularize.js
浏览文件 @
d7fd8412
...
...
@@ -12,7 +12,12 @@ var files = [
{
path
:
'
controls/MapControls.js
'
,
ignoreList
:
[]
},
{
path
:
'
controls/TrackballControls.js
'
,
ignoreList
:
[]
},
// { path: 'controls/TransformControls.js', ignoreList: [] },
{
path
:
'
exporters/GLTFExporter.js
'
,
ignoreList
:
[]
},
{
path
:
'
exporters/GLTFExporter.js
'
,
ignoreList
:
[
'
AnimationClip
'
,
'
Camera
'
,
'
Geometry
'
,
'
Material
'
,
'
Mesh
'
,
'
Object3D
'
,
'
RGBFormat
'
,
'
Scenes
'
,
'
ShaderMaterial
'
,
'
VertexColors
'
]
},
{
path
:
'
exporters/MMDExporter.js
'
,
ignoreList
:
[]
},
{
path
:
'
exporters/OBJExporter.js
'
,
ignoreList
:
[]
},
{
path
:
'
exporters/PLYExporter.js
'
,
ignoreList
:
[]
},
{
path
:
'
exporters/STLExporter.js
'
,
ignoreList
:
[]
},
{
path
:
'
exporters/TypedGeometryExporter.js
'
,
ignoreList
:
[]
},
{
path
:
'
loaders/GLTFLoader.js
'
,
ignoreList
:
[
'
NoSide
'
,
'
Matrix2
'
,
'
DDSLoader
'
]
},
{
path
:
'
loaders/OBJLoader.js
'
,
ignoreList
:
[]
},
{
path
:
'
loaders/MTLLoader.js
'
,
ignoreList
:
[]
}
...
...
@@ -51,6 +56,14 @@ function convert( path, ignoreList ) {
if
(
p1
===
'
\'
'
)
return
match
;
// Inside a string
if
(
p2
===
className
)
return
`
${
p2
}${
p3
}
`
;
if
(
p1
===
'
Math
'
)
{
dependencies
[
'
_Math
'
]
=
true
;
return
'
_Math.
'
;
}
return
match
;
}
);
...
...
@@ -69,26 +82,40 @@ function convert( path, ignoreList ) {
// constants
contents
=
contents
.
replace
(
/
THREE
\.([
a-zA-Z0-9
]
+
)
/g
,
function
(
match
,
p1
)
{
contents
=
contents
.
replace
(
/
(\'?)
THREE
\.([
a-zA-Z0-9
]
+
)
/g
,
function
(
match
,
p1
,
p2
)
{
if
(
ignoreList
.
includes
(
p1
)
)
return
match
;
if
(
p1
===
className
)
return
match
;
if
(
ignoreList
.
includes
(
p2
)
)
return
match
;
if
(
p1
===
'
\'
'
)
return
match
;
// Inside a string
if
(
p2
===
className
)
return
p2
;
dependencies
[
p1
]
=
true
;
if
(
p2
===
'
Math
'
||
p2
===
'
_Math
'
)
{
dependencies
[
'
_Math
'
]
=
true
;
return
'
_Math
'
;
}
dependencies
[
p2
]
=
true
;
// console.log( match, p
1
);
// console.log( match, p
2
);
return
`
${
p
1
}
`
;
return
`
${
p
2
}
`
;
}
);
//
var
keys
=
Object
.
keys
(
dependencies
).
sort
().
map
(
value
=>
'
\n\t
'
+
value
).
toString
();
var
keys
=
Object
.
keys
(
dependencies
)
.
filter
(
value
=>
value
!==
className
)
.
map
(
value
=>
value
===
'
_Math
'
?
'
Math as _Math
'
:
value
)
.
map
(
value
=>
'
\n\t
'
+
value
)
.
sort
()
.
toString
();
var
imports
=
`import {
${
keys
}
\n} from "../../../build/three.module.js";`
;
var
exports
=
`export {
${
className
}
};\n`
;
var
output
=
contents
.
replace
(
'
_IMPORTS_
'
,
imports
)
+
'
\n
'
+
exports
;
var
output
=
contents
.
replace
(
'
_IMPORTS_
'
,
keys
?
imports
:
''
)
+
'
\n
'
+
exports
;
// console.log( output );
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录