Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Ablesons
three.js
提交
1f75413a
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,体验更适合开发者的 AI 搜索 >>
提交
1f75413a
编写于
2月 24, 2018
作者:
M
Mr.doob
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Updated to latest GLTFExporter.
上级
1375e4cf
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
142 addition
and
30 deletion
+142
-30
editor/js/Menubar.File.js
editor/js/Menubar.File.js
+3
-3
examples/js/exporters/GLTFExporter.js
examples/js/exporters/GLTFExporter.js
+139
-27
未找到文件。
editor/js/Menubar.File.js
浏览文件 @
1f75413a
...
...
@@ -197,9 +197,9 @@ Menubar.File = function ( editor ) {
saveArrayBuffer
(
result
,
'
scene.glb
'
);
// forceIndices: true
to allow compatibility with facebook
//
https://github.com/mrdoob/three.js/issues/13397
},
{
binary
:
true
,
forceIndices
:
true
}
);
// forceIndices: true
, forcePowerOfTwoTexture: true
//
to allow compatibility with facebook
},
{
binary
:
true
,
forceIndices
:
true
,
forcePowerOfTwoTexture
:
true
}
);
}
);
options
.
add
(
option
);
...
...
examples/js/exporters/GLTFExporter.js
浏览文件 @
1f75413a
...
...
@@ -69,7 +69,8 @@ THREE.GLTFExporter.prototype = {
truncateDrawRange
:
true
,
embedImages
:
true
,
animations
:
[],
forceIndices
:
false
forceIndices
:
false
,
forcePowerOfTwoTexture
:
false
};
options
=
Object
.
assign
(
{},
DEFAULT_OPTIONS
,
options
);
...
...
@@ -98,8 +99,8 @@ THREE.GLTFExporter.prototype = {
var
skins
=
[];
var
cachedData
=
{
image
s
:
{},
material
s
:
{}
material
s
:
{},
texture
s
:
{}
};
...
...
@@ -192,6 +193,19 @@ THREE.GLTFExporter.prototype = {
}
/**
* Checks if image size is POT.
*
* @param {Image} image The image to be checked.
* @returns {Boolean} Returns true if image size is POT.
*
*/
function
isPowerOfTwo
(
image
)
{
return
THREE
.
Math
.
isPowerOfTwo
(
image
.
width
)
&&
THREE
.
Math
.
isPowerOfTwo
(
image
.
height
);
}
/**
* Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
* https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
...
...
@@ -205,7 +219,7 @@ THREE.GLTFExporter.prototype = {
return
Math
.
ceil
(
bufferSize
/
4
)
*
4
;
}
/**
* Returns a buffer aligned to 4-byte boundary.
*
...
...
@@ -256,8 +270,8 @@ THREE.GLTFExporter.prototype = {
// Create a new dataview and dump the attribute's array into it
var
byteLength
=
count
*
attribute
.
itemSize
*
componentSize
;
// adjust required size of array buffer with padding
// adjust required size of array buffer with padding
// to satisfy gltf requirement that the length is divisible by 4
byteLength
=
getPaddedBufferSize
(
byteLength
);
...
...
@@ -448,11 +462,7 @@ THREE.GLTFExporter.prototype = {
*/
function
processImage
(
map
)
{
if
(
cachedData
.
images
[
map
.
uuid
]
!==
undefined
)
{
return
cachedData
.
images
[
map
.
uuid
];
}
// @TODO Cache
if
(
!
outputJSON
.
images
)
{
...
...
@@ -461,23 +471,34 @@ THREE.GLTFExporter.prototype = {
}
var
mimeType
=
map
.
format
===
THREE
.
RGBAFormat
?
'
image/png
'
:
'
image/jpeg
'
;
var
gltfImage
=
{
mimeType
:
mimeType
};
var
gltfImage
=
{
mimeType
:
mimeType
};
if
(
options
.
embedImages
)
{
var
canvas
=
cachedCanvas
=
cachedCanvas
||
document
.
createElement
(
'
canvas
'
);
canvas
.
width
=
map
.
image
.
width
;
canvas
.
height
=
map
.
image
.
height
;
if
(
options
.
forcePowerOfTwoTexture
&&
!
isPowerOfTwo
(
map
.
image
)
)
{
console
.
warn
(
'
GLTFExporter: Resized non-power-of-two image.
'
,
map
.
image
);
canvas
.
width
=
THREE
.
Math
.
floorPowerOfTwo
(
canvas
.
width
);
canvas
.
height
=
THREE
.
Math
.
floorPowerOfTwo
(
canvas
.
height
);
}
var
ctx
=
canvas
.
getContext
(
'
2d
'
);
if
(
map
.
flipY
===
true
)
{
ctx
.
translate
(
0
,
map
.
image
.
height
);
ctx
.
scale
(
1
,
-
1
);
ctx
.
translate
(
0
,
canvas
.
height
);
ctx
.
scale
(
1
,
-
1
);
}
ctx
.
drawImage
(
map
.
image
,
0
,
0
);
ctx
.
drawImage
(
map
.
image
,
0
,
0
,
canvas
.
width
,
canvas
.
height
);
// @TODO Embed in { bufferView } if options.binary set.
...
...
@@ -491,10 +512,7 @@ THREE.GLTFExporter.prototype = {
outputJSON
.
images
.
push
(
gltfImage
);
var
index
=
outputJSON
.
images
.
length
-
1
;
cachedData
.
images
[
map
.
uuid
]
=
index
;
return
index
;
return
outputJSON
.
images
.
length
-
1
;
}
...
...
@@ -533,6 +551,12 @@ THREE.GLTFExporter.prototype = {
*/
function
processTexture
(
map
)
{
if
(
cachedData
.
textures
[
map
.
uuid
]
!==
undefined
)
{
return
cachedData
.
textures
[
map
.
uuid
];
}
if
(
!
outputJSON
.
textures
)
{
outputJSON
.
textures
=
[];
...
...
@@ -548,7 +572,10 @@ THREE.GLTFExporter.prototype = {
outputJSON
.
textures
.
push
(
gltfTexture
);
return
outputJSON
.
textures
.
length
-
1
;
var
index
=
outputJSON
.
textures
.
length
-
1
;
cachedData
.
textures
[
map
.
uuid
]
=
index
;
return
index
;
}
...
...
@@ -876,28 +903,87 @@ THREE.GLTFExporter.prototype = {
if
(
mesh
.
morphTargetInfluences
!==
undefined
&&
mesh
.
morphTargetInfluences
.
length
>
0
)
{
var
weights
=
[];
var
targetNames
=
[];
var
reverseDictionary
=
{};
if
(
mesh
.
morphTargetDictionary
!==
undefined
)
{
for
(
var
key
in
mesh
.
morphTargetDictionary
)
{
reverseDictionary
[
mesh
.
morphTargetDictionary
[
key
]
]
=
key
;
}
}
gltfMesh
.
primitives
[
0
].
targets
=
[];
for
(
var
i
=
0
;
i
<
mesh
.
morphTargetInfluences
.
length
;
++
i
)
{
var
target
=
{};
var
warned
=
false
;
for
(
var
attributeName
in
geometry
.
morphAttributes
)
{
// glTF 2.0 morph supports only POSITION/NORMAL/TANGENT.
// Three.js doesn't support TANGENT yet.
if
(
attributeName
!==
'
position
'
&&
attributeName
!==
'
normal
'
)
{
if
(
!
warned
)
{
console
.
warn
(
'
GLTFExporter: Only POSITION and NORMAL morph are supported.
'
);
warned
=
true
;
}
continue
;
}
var
attribute
=
geometry
.
morphAttributes
[
attributeName
][
i
];
attributeName
=
nameConversion
[
attributeName
]
||
attributeName
.
toUpperCase
();
target
[
attributeName
]
=
processAccessor
(
attribute
,
geometry
);
// Three.js morph attribute has absolute values while the one of glTF has relative values.
//
// glTF 2.0 Specification:
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
var
baseAttribute
=
geometry
.
attributes
[
attributeName
];
// Clones attribute not to override
var
relativeAttribute
=
attribute
.
clone
();
for
(
var
j
=
0
,
jl
=
attribute
.
count
;
j
<
jl
;
j
++
)
{
relativeAttribute
.
setXYZ
(
j
,
attribute
.
getX
(
j
)
-
baseAttribute
.
getX
(
j
),
attribute
.
getY
(
j
)
-
baseAttribute
.
getY
(
j
),
attribute
.
getZ
(
j
)
-
baseAttribute
.
getZ
(
j
)
);
}
target
[
attributeName
.
toUpperCase
()
]
=
processAccessor
(
relativeAttribute
,
geometry
);
}
gltfMesh
.
primitives
[
0
].
targets
.
push
(
target
);
weights
.
push
(
mesh
.
morphTargetInfluences
[
i
]
);
if
(
mesh
.
morphTargetDictionary
!==
undefined
)
targetNames
.
push
(
reverseDictionary
[
i
]
);
}
gltfMesh
.
weights
=
weights
;
if
(
targetNames
.
length
>
0
)
{
gltfMesh
.
extras
=
{};
gltfMesh
.
extras
.
targetNames
=
targetNames
;
}
}
outputJSON
.
meshes
.
push
(
gltfMesh
);
...
...
@@ -968,13 +1054,12 @@ THREE.GLTFExporter.prototype = {
*
* Status:
* - Only properties listed in PATH_PROPERTIES may be animated.
* - Only LINEAR and STEP interpolation currently supported.
*
* @param {THREE.AnimationClip} clip
* @param {THREE.Object3D} root
* @return {number}
*/
function
processAnimation
(
clip
,
root
)
{
function
processAnimation
(
clip
,
root
)
{
if
(
!
outputJSON
.
animations
)
{
...
...
@@ -1022,11 +1107,37 @@ THREE.GLTFExporter.prototype = {
}
var
interpolation
;
// @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
// Detecting glTF cubic spline interpolant by checking factory method's special property
// GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return
// valid value from .getInterpolation().
if
(
track
.
createInterpolant
.
isInterpolantFactoryMethodGLTFCubicSpline
===
true
)
{
interpolation
=
'
CUBICSPLINE
'
;
// itemSize of CUBICSPLINE keyframe is 9
// (VEC3 * 3: inTangent, splineVertex, and outTangent)
// but needs to be stored as VEC3 so dividing by 3 here.
outputItemSize
/=
3
;
}
else
if
(
track
.
getInterpolation
()
===
THREE
.
InterpolateDiscrete
)
{
interpolation
=
'
STEP
'
;
}
else
{
interpolation
=
'
LINEAR
'
;
}
samplers
.
push
(
{
input
:
processAccessor
(
new
THREE
.
BufferAttribute
(
track
.
times
,
inputItemSize
)
),
output
:
processAccessor
(
new
THREE
.
BufferAttribute
(
track
.
values
,
outputItemSize
)
),
interpolation
:
track
.
getInterpolation
()
===
THREE
.
InterpolateDiscrete
?
'
STEP
'
:
'
LINEAR
'
interpolation
:
interpolation
}
);
...
...
@@ -1151,7 +1262,8 @@ THREE.GLTFExporter.prototype = {
}
if
(
object
.
name
)
{
// We don't export empty strings name because it represents no-name in Three.js.
if
(
object
.
name
!==
''
)
{
gltfNode
.
name
=
String
(
object
.
name
);
...
...
@@ -1434,4 +1546,4 @@ THREE.GLTFExporter.prototype = {
}
};
};
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录