Merge pull request #1 from Skycatch/feature/fork-update
Feature/fork update
12
.editorconfig
Normal file
@ -0,0 +1,12 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
3
.eslintignore
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules/**
|
||||
coverage/**
|
||||
doc/**
|
3
.eslintrc.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "cesium/node"
|
||||
}
|
5
.gitignore
vendored
@ -7,5 +7,8 @@ npm-debug.log
|
||||
.idea/tasks.xml
|
||||
|
||||
# Generate data
|
||||
test
|
||||
.eslintcache
|
||||
coverage
|
||||
doc
|
||||
*.tgz
|
||||
.nyc_output
|
||||
|
@ -1,6 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="JSHint" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
@ -1,9 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<file url="file://$PROJECT_DIR$" libraries="{node_modules}" />
|
||||
<file url="PROJECT" libraries="{TypeScriptDefinitions, node_modules}" />
|
||||
<includedPredefinedLibrary name="Node.js Core" />
|
||||
<excludedPredefinedLibrary name="HTML" />
|
||||
</component>
|
||||
</project>
|
@ -1,83 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JSHintConfiguration" version="2.8.0" use-config-file="true">
|
||||
<option asi="false" />
|
||||
<option bitwise="true" />
|
||||
<option boss="false" />
|
||||
<option browser="true" />
|
||||
<option browserify="false" />
|
||||
<option camelcase="false" />
|
||||
<option couch="false" />
|
||||
<option curly="true" />
|
||||
<option debug="false" />
|
||||
<option devel="false" />
|
||||
<option dojo="false" />
|
||||
<option elision="false" />
|
||||
<option enforceall="false" />
|
||||
<option eqeqeq="true" />
|
||||
<option eqnull="false" />
|
||||
<option es3="false" />
|
||||
<option es5="false" />
|
||||
<option esnext="false" />
|
||||
<option evil="false" />
|
||||
<option expr="false" />
|
||||
<option forin="true" />
|
||||
<option freeze="false" />
|
||||
<option funcscope="false" />
|
||||
<option futurehostile="false" />
|
||||
<option gcl="false" />
|
||||
<option globalstrict="false" />
|
||||
<option immed="false" />
|
||||
<option iterator="false" />
|
||||
<option jasmine="false" />
|
||||
<option jquery="false" />
|
||||
<option lastsemic="false" />
|
||||
<option latedef="false" />
|
||||
<option laxbreak="false" />
|
||||
<option laxcomma="false" />
|
||||
<option loopfunc="false" />
|
||||
<option maxerr="50" />
|
||||
<option mocha="false" />
|
||||
<option mootools="false" />
|
||||
<option moz="false" />
|
||||
<option multistr="false" />
|
||||
<option newcap="false" />
|
||||
<option noarg="true" />
|
||||
<option nocomma="false" />
|
||||
<option node="false" />
|
||||
<option noempty="true" />
|
||||
<option nomen="false" />
|
||||
<option nonbsp="false" />
|
||||
<option nonew="true" />
|
||||
<option nonstandard="false" />
|
||||
<option notypeof="false" />
|
||||
<option noyield="false" />
|
||||
<option onevar="false" />
|
||||
<option passfail="false" />
|
||||
<option phantom="false" />
|
||||
<option plusplus="false" />
|
||||
<option proto="false" />
|
||||
<option prototypejs="false" />
|
||||
<option qunit="false" />
|
||||
<option quotmark="false" />
|
||||
<option rhino="false" />
|
||||
<option scripturl="false" />
|
||||
<option shadow="false" />
|
||||
<option shelljs="false" />
|
||||
<option singleGroups="false" />
|
||||
<option smarttabs="false" />
|
||||
<option strict="true" />
|
||||
<option sub="false" />
|
||||
<option supernew="false" />
|
||||
<option trailing="false" />
|
||||
<option typed="false" />
|
||||
<option undef="true" />
|
||||
<option unused="false" />
|
||||
<option validthis="false" />
|
||||
<option white="false" />
|
||||
<option withstmt="false" />
|
||||
<option worker="false" />
|
||||
<option wsh="false" />
|
||||
<option yui="false" />
|
||||
</component>
|
||||
</project>
|
@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="TypeScriptDefinitions" type="javaScript">
|
||||
<properties>
|
||||
<sourceFilesUrls>
|
||||
<item url="file://$PROJECT_DIR$/TypeScriptDefinitions" />
|
||||
</sourceFilesUrls>
|
||||
</properties>
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/TypeScriptDefinitions" />
|
||||
</CLASSES>
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
@ -1,12 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="node_modules" type="javaScript">
|
||||
<properties>
|
||||
<option name="frameworkName" value="node_modules" />
|
||||
</properties>
|
||||
<CLASSES>
|
||||
<root url="file://$USER_HOME$/node_modules" />
|
||||
<root url="file://$PROJECT_DIR$/node_modules" />
|
||||
</CLASSES>
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
@ -3,14 +3,4 @@
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES5" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
</project>
|
@ -2,7 +2,7 @@
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/OBJ2GLTF.iml" filepath="$PROJECT_DIR$/.idea/OBJ2GLTF.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/obj2gltf.iml" filepath="$PROJECT_DIR$/.idea/obj2gltf.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -7,7 +7,5 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="node_modules" level="project" />
|
||||
<orderEntry type="library" name="TypeScriptDefinitions" level="project" />
|
||||
</component>
|
||||
</module>
|
60
.jshintrc
@ -1,60 +0,0 @@
|
||||
{
|
||||
"bitwise": false,
|
||||
"camelcase": false,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"forin": true,
|
||||
"freeze": true,
|
||||
"immed": true,
|
||||
"latedef": "nofunc",
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"nonbsp": true,
|
||||
"nonew": true,
|
||||
"plusplus": false,
|
||||
"quotmark": false,
|
||||
"undef": true,
|
||||
"unused": "strict",
|
||||
"strict": true,
|
||||
"asi": false,
|
||||
"boss": false,
|
||||
"debug": false,
|
||||
"eqnull": false,
|
||||
"moz": false,
|
||||
"evil": false,
|
||||
"expr": false,
|
||||
"funcscope": false,
|
||||
"globalstrict": false,
|
||||
"iterator": false,
|
||||
"lastsemic": false,
|
||||
"laxbreak": false,
|
||||
"laxcomma": false,
|
||||
"loopfunc": false,
|
||||
"multistr": true,
|
||||
"noyield": false,
|
||||
"notypeof": false,
|
||||
"proto": false,
|
||||
"scripturl": false,
|
||||
"shadow": false,
|
||||
"sub": false,
|
||||
"supernew": false,
|
||||
"validthis": false,
|
||||
"browser": false,
|
||||
"browserify": false,
|
||||
"couch": false,
|
||||
"devel": true,
|
||||
"dojo": false,
|
||||
"jasmine": false,
|
||||
"jquery": false,
|
||||
"mocha": true,
|
||||
"mootools": false,
|
||||
"node": true,
|
||||
"nonstandard": false,
|
||||
"prototypejs": false,
|
||||
"qunit": false,
|
||||
"rhino": false,
|
||||
"shelljs": false,
|
||||
"worker": false,
|
||||
"wsh": false,
|
||||
"yui": false
|
||||
}
|
12
.npmignore
@ -1,9 +1,13 @@
|
||||
/.idea
|
||||
/specs
|
||||
/test
|
||||
/TypeScriptDefinitions
|
||||
/coverage
|
||||
.jshintrc
|
||||
/doc
|
||||
/specs
|
||||
.editorconfig
|
||||
.eslintcache
|
||||
.eslintignore
|
||||
.eslintrc.json
|
||||
.nyc_output
|
||||
.npmignore
|
||||
.travis.yml
|
||||
gulpfile.js
|
||||
*.tgz
|
||||
|
10
.travis.yml
@ -1,6 +1,12 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 4
|
||||
- "4"
|
||||
- "6"
|
||||
script:
|
||||
- npm run jsHint -- --failTaskOnError
|
||||
- npm run eslint
|
||||
- npm run test -- --failTaskOnError --suppressPassed
|
||||
|
||||
after_success:
|
||||
## We only need to run coveralls for one node version (doesn't matter which one).
|
||||
## We also ignore publishing failures, since restarting an existing travis build would otherwise break.
|
||||
- if node --version | grep -q ^v6 ; npm run coverage && npm run coveralls; fi
|
||||
|
35
CHANGES.md
@ -1,6 +1,41 @@
|
||||
Change Log
|
||||
==========
|
||||
|
||||
### Next release
|
||||
|
||||
* Change texture sampling to use NEAREST_MIPMAP_LINEAR by default [#83](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/83).
|
||||
* Fixed normal generation.
|
||||
|
||||
### 1.1.1 2017-04-25
|
||||
|
||||
* Fixed `CHANGES.md` formatting.
|
||||
|
||||
### 1.1.0 2017-04-25
|
||||
|
||||
* Added ability to convert the up-axis of the obj model. [#68](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/68)
|
||||
* Fixed issues with an extra .bin file being saved when using `--separate`. [#62](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/62)
|
||||
* Fixed issue where an ambient color of `[1, 1, 1]` overly brightens the converted model. [#70](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/70)
|
||||
|
||||
### 1.0.0 2017-04-13
|
||||
|
||||
* Breaking changes
|
||||
* To use `obj2gltf` as a library, call `require('obj2gltf')(input, output, options)`. The previous calling code was `require('obj2gltf').convert(input, output, options)`.
|
||||
* Many library options and command-line parameters have been renamed.
|
||||
* Project cleanup. [#49](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/49)
|
||||
* Speed improvements, especially for larger models.
|
||||
* Preserves the objects and groups in the obj.
|
||||
* Added documentation and tests.
|
||||
* Material fixes.
|
||||
|
||||
### 0.1.7 2017-01-06
|
||||
|
||||
* Update gltf-pipeline to 0.1.0-alpha9
|
||||
* Added command to generate documentation (npm run jsdoc)
|
||||
|
||||
### 0.1.6 2016-09-07
|
||||
|
||||
* Changed obj2gltf.js line endings from CRLF to LF in npm package.
|
||||
|
||||
### 0.1.5 2016-08-26
|
||||
|
||||
* Fixed incorrect parameter to the gltf-pipeline.
|
||||
|
346
LICENSE.md
@ -1,63 +1,236 @@
|
||||
Copyright 2016 Analytical Graphics, Inc.
|
||||
Copyright 2016-2017 Analytical Graphics, Inc. and Contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2016-2017 Analytical Graphics, Inc. and Contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
Third-Party Code
|
||||
================
|
||||
|
||||
obj2gltf includes the following third-party code.
|
||||
|
||||
### async
|
||||
### bluebird
|
||||
|
||||
https://www.npmjs.com/package/async
|
||||
|
||||
> Copyright (c) 2010-2016 Caolan McMahon
|
||||
> The MIT License (MIT)
|
||||
>
|
||||
> Copyright (c) 2013-2015 Petka Antonov
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
> all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
### byline
|
||||
|
||||
https://www.npmjs.com/package/byline
|
||||
|
||||
> node-byline (C) 2011-2015 John Hewson
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
> THE SOFTWARE.
|
||||
|
||||
### Cesium
|
||||
|
||||
@ -82,16 +255,16 @@ https://www.npmjs.com/package/fs-extra
|
||||
> Copyright (c) 2011-2016 JP Richardson
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
|
||||
(the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
|
||||
> (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
|
||||
> merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
> WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
> OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
> ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
### gltf-pipeline
|
||||
|
||||
@ -105,6 +278,55 @@ https://www.npmjs.com/package/gltf-pipeline
|
||||
>
|
||||
> Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
### mime
|
||||
|
||||
https://www.npmjs.com/package/mime
|
||||
|
||||
> Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
> all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
> THE SOFTWARE.
|
||||
|
||||
### pngjs
|
||||
|
||||
https://www.npmjs.com/package/pngjs
|
||||
|
||||
> pngjs2 original work Copyright (c) 2015 Luke Page & Original Contributors
|
||||
> pngjs derived work Copyright (c) 2012 Kuba Niegowski
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
> all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
> THE SOFTWARE.
|
||||
|
||||
### yargs
|
||||
|
||||
https://www.npmjs.com/package/yargs
|
||||
@ -112,24 +334,24 @@ https://www.npmjs.com/package/yargs
|
||||
The command-line tool uses yargs.
|
||||
|
||||
> Copyright 2010 James Halliday (mail@substack.net)
|
||||
Modified work Copyright 2014 Contributors (ben@npmjs.com)
|
||||
> Modified work Copyright 2014 Contributors (ben@npmjs.com)
|
||||
>
|
||||
> This project is free software released under the MIT/X11 license:
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
> all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
> THE SOFTWARE.
|
||||
|
77
README.md
@ -11,39 +11,82 @@ npm install --save obj2gltf
|
||||
Using obj2gltf as a library:
|
||||
```javascript
|
||||
var obj2gltf = require('obj2gltf');
|
||||
var convert = obj2gltf.convert;
|
||||
var options = {
|
||||
embedImage : false // Don't embed image in the converted glTF
|
||||
separateTextures : true // Don't embed textures in the converted glTF
|
||||
}
|
||||
convert('model.obj', 'model.gltf', options)
|
||||
obj2gltf('model.obj', 'model.gltf', options)
|
||||
.then(function() {
|
||||
console.log('Converted model');
|
||||
});
|
||||
```
|
||||
Using obj2gltf as a command-line tool:
|
||||
|
||||
`node bin/obj2gltf.js model.obj`
|
||||
|
||||
`node bin/obj2gltf.js model.obj model.gltf`
|
||||
`node bin/obj2gltf.js -i model.obj`
|
||||
|
||||
`node bin/obj2gltf.js -i model.obj -o model.gltf`
|
||||
|
||||
`node bin/obj2gltf.js -i model.obj -o model.gltf -s`
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
###Command line flags:
|
||||
### Command line flags:
|
||||
|
||||
|Flag|Description|Required|
|
||||
|----|-----------|--------|
|
||||
|`-i`|Path to the input OBJ file.| :white_check_mark: Yes|
|
||||
|`-o`|Directory or filename for the exported glTF file.|No|
|
||||
|`-b`|Output binary glTF.|No, default `false`|
|
||||
|`-s`|Writes out separate geometry/animation data files, shader files, and textures instead of embedding them in the glTF file.|No, default `false`|
|
||||
|`-t`|Write out separate textures only.|No, default `false`|
|
||||
|`-h`, `--help`|Display help.|No|
|
||||
|`-i`, `--input`|Path to the obj file.| :white_check_mark: Yes|
|
||||
|`-o`, `--output`|Path of the converted glTF file.|No|
|
||||
|`-b`, `--binary`|Save as binary glTF.|No, default `false`|
|
||||
|`-s`, `--separate`|Writes out separate geometry data files, shader files, and textures instead of embedding them in the glTF file.|No, default `false`|
|
||||
|`-t`, `--separateTextures`|Write out separate textures only.|No, default `false`|
|
||||
|`-c`, `--compress`|Quantize positions, compress texture coordinates, and oct-encode normals.|No, default `false`|
|
||||
|`-z`, `--optimize`|Use the optimization stages in the glTF pipeline.|No, default `false`|
|
||||
|`-n`, `--generateNormals`|Generate normals if they are missing.|No, default `false`|
|
||||
|`--optimizeForCesium`|Optimize the glTF for Cesium by using the sun as a default light source.|No, default `false`|
|
||||
|`--ao`|Apply ambient occlusion to the converted model.|No, default `false`|
|
||||
|`-h`|Display help|No|
|
||||
|`--kmc`|Output glTF with the KHR_materials_common extension.|No, default `false`|
|
||||
|`--bypassPipeline`|Bypass the gltf-pipeline for debugging purposes. This option overrides many of the options above and will save the glTF with the KHR_materials_common extension.|No, default `false`|
|
||||
|`--checkTransparency`|Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel. By default textures are considered to be opaque.|No, default `false`|
|
||||
|`--secure`|Prevent the converter from reading image or mtl files outside of the input obj directory.|No, default `false`|
|
||||
|`--inputUpAxis`|Up axis of the obj. Choices are 'X', 'Y', and 'Z'.|No, default `Y`|
|
||||
|`--outputUpAxis`|Up axis of the converted glTF. Choices are 'X', 'Y', and 'Z'.|No, default `Y`|
|
||||
|
||||
## Build Instructions
|
||||
|
||||
Run the tests:
|
||||
```
|
||||
npm run test
|
||||
```
|
||||
To run ESLint on the entire codebase, run:
|
||||
```
|
||||
npm run eslint
|
||||
```
|
||||
To run ESLint automatically when a file is saved, run the following and leave it open in a console window:
|
||||
```
|
||||
npm run eslint-watch
|
||||
```
|
||||
|
||||
## Running Test Coverage
|
||||
|
||||
Coverage uses [nyc](https://github.com/istanbuljs/nyc). Run:
|
||||
```
|
||||
npm run coverage
|
||||
```
|
||||
For complete coverage details, open `coverage/lcov-report/index.html`.
|
||||
|
||||
The tests and coverage covers the Node.js module; it does not cover the command-line interface, which is tiny.
|
||||
|
||||
## Generating Documentation
|
||||
|
||||
To generate the documentation:
|
||||
```
|
||||
npm run jsdoc
|
||||
```
|
||||
|
||||
The documentation will be placed in the `doc` folder.
|
||||
|
||||
## Debugging
|
||||
|
||||
* To debug the tests in Webstorm, open the Gulp tab, right click the `test` task, and click `Debug 'test'`.
|
||||
* To run a single test, change the test function from `it` to `fit`.
|
||||
|
||||
## Contributions
|
||||
|
||||
@ -53,5 +96,5 @@ Pull requests are appreciated. Please use the same [Contributor License Agreeme
|
||||
|
||||
Developed by the Cesium team.
|
||||
<p align="center">
|
||||
<a href="http://cesiumjs.org/"><img src="doc/cesium.png" /></a>
|
||||
<a href="http://cesiumjs.org/"><img src="doc/cesium.png" onerror="this.src='cesium.png'"/></a>
|
||||
</p>
|
||||
|
165
TypeScriptDefinitions/async.d.ts
vendored
@ -1,165 +0,0 @@
|
||||
// Type definitions for Async 1.4.2
|
||||
// Project: https://github.com/caolan/async
|
||||
// Definitions by: Boris Yankov <https://github.com/borisyankov/>, Arseniy Maximov <https://github.com/kern0>, Joe Herman <https://github.com/Penryn>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
interface Dictionary<T> { [key: string]: T; }
|
||||
|
||||
interface ErrorCallback { (err?: Error): void; }
|
||||
interface AsyncResultCallback<T> { (err: Error, result: T): void; }
|
||||
interface AsyncResultArrayCallback<T> { (err: Error, results: T[]): void; }
|
||||
interface AsyncResultObjectCallback<T> { (err: Error, results: Dictionary<T>): void; }
|
||||
|
||||
interface AsyncFunction<T> { (callback: (err?: Error, result?: T) => void): void; }
|
||||
interface AsyncIterator<T> { (item: T, callback: ErrorCallback): void; }
|
||||
interface AsyncForEachOfIterator<T> { (item: T, key: number|string, callback: ErrorCallback): void; }
|
||||
interface AsyncResultIterator<T, R> { (item: T, callback: AsyncResultCallback<R>): void; }
|
||||
interface AsyncMemoIterator<T, R> { (memo: R, item: T, callback: AsyncResultCallback<R>): void; }
|
||||
interface AsyncBooleanIterator<T> { (item: T, callback: (err: string, truthValue: boolean) => void): void; }
|
||||
|
||||
interface AsyncWorker<T> { (task: T, callback: ErrorCallback): void; }
|
||||
interface AsyncVoidFunction { (callback: ErrorCallback): void; }
|
||||
|
||||
interface AsyncQueue<T> {
|
||||
length(): number;
|
||||
started: boolean;
|
||||
running(): number;
|
||||
idle(): boolean;
|
||||
concurrency: number;
|
||||
push(task: T, callback?: ErrorCallback): void;
|
||||
push(task: T[], callback?: ErrorCallback): void;
|
||||
unshift(task: T, callback?: ErrorCallback): void;
|
||||
unshift(task: T[], callback?: ErrorCallback): void;
|
||||
saturated: () => any;
|
||||
empty: () => any;
|
||||
drain: () => any;
|
||||
paused: boolean;
|
||||
pause(): void
|
||||
resume(): void;
|
||||
kill(): void;
|
||||
}
|
||||
|
||||
interface AsyncPriorityQueue<T> {
|
||||
length(): number;
|
||||
concurrency: number;
|
||||
started: boolean;
|
||||
paused: boolean;
|
||||
push(task: T, priority: number, callback?: AsyncResultArrayCallback<T>): void;
|
||||
push(task: T[], priority: number, callback?: AsyncResultArrayCallback<T>): void;
|
||||
saturated: () => any;
|
||||
empty: () => any;
|
||||
drain: () => any;
|
||||
running(): number;
|
||||
idle(): boolean;
|
||||
pause(): void;
|
||||
resume(): void;
|
||||
kill(): void;
|
||||
}
|
||||
|
||||
interface AsyncCargo {
|
||||
length(): number;
|
||||
payload: number;
|
||||
push(task: any, callback? : Function): void;
|
||||
push(task: any[], callback? : Function): void;
|
||||
saturated(): void;
|
||||
empty(): void;
|
||||
drain(): void;
|
||||
idle(): boolean;
|
||||
pause(): void;
|
||||
resume(): void;
|
||||
kill(): void;
|
||||
}
|
||||
|
||||
interface Async {
|
||||
|
||||
// Collections
|
||||
each<T>(arr: T[], iterator: AsyncIterator<T>, callback?: ErrorCallback): void;
|
||||
eachSeries<T>(arr: T[], iterator: AsyncIterator<T>, callback?: ErrorCallback): void;
|
||||
eachLimit<T>(arr: T[], limit: number, iterator: AsyncIterator<T>, callback?: ErrorCallback): void;
|
||||
forEachOf(obj: any, iterator: (item: any, key: string|number, callback?: ErrorCallback) => void, callback: ErrorCallback): void;
|
||||
forEachOf<T>(obj: T[], iterator: AsyncForEachOfIterator<T>, callback?: ErrorCallback): void;
|
||||
forEachOfSeries(obj: any, iterator: (item: any, key: string|number, callback?: ErrorCallback) => void, callback: ErrorCallback): void;
|
||||
forEachOfSeries<T>(obj: T[], iterator: AsyncForEachOfIterator<T>, callback?: ErrorCallback): void;
|
||||
forEachOfLimit(obj: any, limit: number, iterator: (item: any, key: string|number, callback?: ErrorCallback) => void, callback: ErrorCallback): void;
|
||||
forEachOfLimit<T>(obj: T[], limit: number, iterator: AsyncForEachOfIterator<T>, callback?: ErrorCallback): void;
|
||||
map<T, R>(arr: T[], iterator: AsyncResultIterator<T, R>, callback?: AsyncResultArrayCallback<R>): any;
|
||||
mapSeries<T, R>(arr: T[], iterator: AsyncResultIterator<T, R>, callback?: AsyncResultArrayCallback<R>): any;
|
||||
mapLimit<T, R>(arr: T[], limit: number, iterator: AsyncResultIterator<T, R>, callback?: AsyncResultArrayCallback<R>): any;
|
||||
filter<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
select<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
filterSeries<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
selectSeries<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
filterLimit<T>(arr: T[], limit: number, iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
selectLimit<T>(arr: T[], limit: number, iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
reject<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
rejectSeries<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
rejectLimit<T>(arr: T[], limit: number, iterator: AsyncBooleanIterator<T>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
reduce<T, R>(arr: T[], memo: R, iterator: AsyncMemoIterator<T, R>, callback?: AsyncResultCallback<R>): any;
|
||||
inject<T, R>(arr: T[], memo: R, iterator: AsyncMemoIterator<T, R>, callback?: AsyncResultCallback<R>): any;
|
||||
foldl<T, R>(arr: T[], memo: R, iterator: AsyncMemoIterator<T, R>, callback?: AsyncResultCallback<R>): any;
|
||||
reduceRight<T, R>(arr: T[], memo: R, iterator: AsyncMemoIterator<T, R>, callback: AsyncResultCallback<R>): any;
|
||||
foldr<T, R>(arr: T[], memo: R, iterator: AsyncMemoIterator<T, R>, callback: AsyncResultCallback<R>): any;
|
||||
detect<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: AsyncResultCallback<T>): any;
|
||||
detectSeries<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: AsyncResultCallback<T>): any;
|
||||
detectLimit<T>(arr: T[], limit: number, iterator: AsyncBooleanIterator<T>, callback?: AsyncResultCallback<T>): any;
|
||||
sortBy<T, V>(arr: T[], iterator: AsyncResultIterator<T, V>, callback?: AsyncResultArrayCallback<T>): any;
|
||||
some<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: (result: boolean) => void): any;
|
||||
someLimit<T>(arr: T[], limit: number, iterator: AsyncBooleanIterator<T>, callback?: (result: boolean) => void): any;
|
||||
any<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: (result: boolean) => void): any;
|
||||
every<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: (result: boolean) => any): any;
|
||||
everyLimit<T>(arr: T[], limit: number, iterator: AsyncBooleanIterator<T>, callback?: (result: boolean) => any): any;
|
||||
all<T>(arr: T[], iterator: AsyncBooleanIterator<T>, callback?: (result: boolean) => any): any;
|
||||
concat<T, R>(arr: T[], iterator: AsyncResultIterator<T, R[]>, callback?: AsyncResultArrayCallback<R>): any;
|
||||
concatSeries<T, R>(arr: T[], iterator: AsyncResultIterator<T, R[]>, callback?: AsyncResultArrayCallback<R>): any;
|
||||
|
||||
// Control Flow
|
||||
series<T>(tasks: AsyncFunction<T>[], callback?: AsyncResultArrayCallback<T>): void;
|
||||
series<T>(tasks: Dictionary<AsyncFunction<T>>, callback?: AsyncResultObjectCallback<T>): void;
|
||||
parallel<T>(tasks: Array<AsyncFunction<T>>, callback?: AsyncResultArrayCallback<T>): void;
|
||||
parallel<T>(tasks: Dictionary<AsyncFunction<T>>, callback?: AsyncResultObjectCallback<T>): void;
|
||||
parallelLimit<T>(tasks: Array<AsyncFunction<T>>, limit: number, callback?: AsyncResultArrayCallback<T>): void;
|
||||
parallelLimit<T>(tasks: Dictionary<AsyncFunction<T>>, limit: number, callback?: AsyncResultObjectCallback<T>): void;
|
||||
whilst(test: () => boolean, fn: AsyncVoidFunction, callback: (err: any) => void): void;
|
||||
doWhilst(fn: AsyncVoidFunction, test: () => boolean, callback: (err: any) => void): void;
|
||||
until(test: () => boolean, fn: AsyncVoidFunction, callback: (err: any) => void): void;
|
||||
doUntil(fn: AsyncVoidFunction, test: () => boolean, callback: (err: any) => void): void;
|
||||
during(test: (testCallback : (error: Error, truth: boolean) => void) => void, fn: AsyncVoidFunction, callback: (err: any) => void): void;
|
||||
doDuring(fn: AsyncVoidFunction, test: (testCallback: (error: Error, truth: boolean) => void) => void, callback: (err: any) => void): void;
|
||||
forever(next: (errCallback : (err: Error) => void) => void, errBack: (err: Error) => void) : void;
|
||||
waterfall(tasks: Function[], callback?: (err: Error, results?: any) => void): void;
|
||||
compose(...fns: Function[]): Function;
|
||||
seq(...fns: Function[]): Function;
|
||||
applyEach(fns: Function[], argsAndCallback: any[]): void; // applyEach(fns, args..., callback). TS does not support ... for a middle argument. Callback is optional.
|
||||
applyEachSeries(fns: Function[], argsAndCallback: any[]): void; // applyEachSeries(fns, args..., callback). TS does not support ... for a middle argument. Callback is optional.
|
||||
queue<T>(worker: AsyncWorker<T>, concurrency?: number): AsyncQueue<T>;
|
||||
priorityQueue<T>(worker: AsyncWorker<T>, concurrency: number): AsyncPriorityQueue<T>;
|
||||
cargo(worker : (tasks: any[], callback : ErrorCallback) => void, payload? : number) : AsyncCargo;
|
||||
auto(tasks: any, callback?: (error: Error, results: any) => void): void;
|
||||
retry<T>(opts: number, task: (callback : AsyncResultCallback<T>, results: any) => void, callback: (error: Error, results: any) => void): void;
|
||||
retry<T>(opts: { times: number, interval: number|((retryCount: number) => number) }, task: (callback: AsyncResultCallback<T>, results : any) => void, callback: (error: Error, results: any) => void): void;
|
||||
iterator(tasks: Function[]): Function;
|
||||
apply(fn: Function, ...arguments: any[]): AsyncFunction<any>;
|
||||
nextTick(callback: Function): void;
|
||||
setImmediate(callback: Function): void;
|
||||
|
||||
times<T> (n: number, iterator: AsyncResultIterator<number, T>, callback: AsyncResultArrayCallback<T>): void;
|
||||
timesSeries<T>(n: number, iterator: AsyncResultIterator<number, T>, callback: AsyncResultArrayCallback<T>): void;
|
||||
timesLimit<T>(n: number, limit: number, iterator: AsyncResultIterator<number, T>, callback: AsyncResultArrayCallback<T>): void;
|
||||
|
||||
// Utils
|
||||
memoize(fn: Function, hasher?: Function): Function;
|
||||
unmemoize(fn: Function): Function;
|
||||
ensureAsync(fn: (... argsAndCallback: any[]) => void): Function;
|
||||
constant(...values: any[]): Function;
|
||||
asyncify(fn: Function): Function;
|
||||
wrapSync(fn: Function): Function;
|
||||
log(fn: Function, ...arguments: any[]): void;
|
||||
dir(fn: Function, ...arguments: any[]): void;
|
||||
noConflict(): Async;
|
||||
}
|
||||
|
||||
declare var async: Async;
|
||||
|
||||
declare module "async" {
|
||||
export = async;
|
||||
}
|
38
TypeScriptDefinitions/byline.d.ts
vendored
@ -1,38 +0,0 @@
|
||||
// Type definitions for byline 4.2.1
|
||||
// Project: https://github.com/jahewson/node-byline
|
||||
// Definitions by: Stefan Steinhart <https://github.com/reppners>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
/// <reference path="../node/node.d.ts" />
|
||||
|
||||
declare module "byline" {
|
||||
import stream = require("stream");
|
||||
|
||||
export interface LineStreamOptions extends stream.TransformOptions {
|
||||
keepEmptyLines?: boolean;
|
||||
}
|
||||
|
||||
export interface LineStream extends stream.Transform {
|
||||
}
|
||||
|
||||
export interface LineStreamCreatable extends LineStream {
|
||||
new (options?:LineStreamOptions):LineStream
|
||||
}
|
||||
|
||||
//TODO is it possible to declare static factory functions without name (directly on the module)
|
||||
//
|
||||
// JS:
|
||||
// // convinience API
|
||||
// module.exports = function(readStream, options) {
|
||||
// return module.exports.createStream(readStream, options);
|
||||
// };
|
||||
//
|
||||
// TS:
|
||||
// ():LineStream; // same as createStream():LineStream
|
||||
// (stream:stream.Stream, options?:LineStreamOptions):LineStream; // same as createStream(stream, options?):LineStream
|
||||
|
||||
export function createStream():LineStream;
|
||||
export function createStream(stream:NodeJS.ReadableStream, options?:LineStreamOptions):LineStream;
|
||||
|
||||
export var LineStream:LineStreamCreatable;
|
||||
}
|
95
TypeScriptDefinitions/fs-extra.d.ts
vendored
@ -1,95 +0,0 @@
|
||||
// Type definitions for fs-extra
|
||||
// Project: https://github.com/jprichardson/node-fs-extra
|
||||
// Definitions by: midknight41 <https://github.com/midknight41>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
// Imported from: https://github.com/soywiz/typescript-node-definitions/fs-extra.d.ts
|
||||
|
||||
///<reference path="../node/node.d.ts"/>
|
||||
|
||||
declare module "fs-extra" {
|
||||
export * from "fs";
|
||||
|
||||
export function copy(src: string, dest: string, callback?: (err: Error) => void): void;
|
||||
export function copy(src: string, dest: string, filter: CopyFilter, callback?: (err: Error) => void): void;
|
||||
export function copy(src: string, dest: string, options: CopyOptions, callback?: (err: Error) => void): void;
|
||||
|
||||
export function copySync(src: string, dest: string): void;
|
||||
export function copySync(src: string, dest: string, filter: CopyFilter): void;
|
||||
export function copySync(src: string, dest: string, options: CopyOptions): void;
|
||||
|
||||
export function createFile(file: string, callback?: (err: Error) => void): void;
|
||||
export function createFileSync(file: string): void;
|
||||
|
||||
export function mkdirs(dir: string, callback?: (err: Error) => void): void;
|
||||
export function mkdirp(dir: string, callback?: (err: Error) => void): void;
|
||||
export function mkdirs(dir: string, options?: MkdirOptions, callback?: (err: Error) => void): void;
|
||||
export function mkdirp(dir: string, options?: MkdirOptions, callback?: (err: Error) => void): void;
|
||||
export function mkdirsSync(dir: string, options?: MkdirOptions): void;
|
||||
export function mkdirpSync(dir: string, options?: MkdirOptions): void;
|
||||
|
||||
export function outputFile(file: string, data: any, callback?: (err: Error) => void): void;
|
||||
export function outputFileSync(file: string, data: any): void;
|
||||
|
||||
export function outputJson(file: string, data: any, callback?: (err: Error) => void): void;
|
||||
export function outputJSON(file: string, data: any, callback?: (err: Error) => void): void;
|
||||
export function outputJsonSync(file: string, data: any): void;
|
||||
export function outputJSONSync(file: string, data: any): void;
|
||||
|
||||
export function readJson(file: string, callback: (err: Error, jsonObject: any) => void): void;
|
||||
export function readJson(file: string, options: OpenOptions, callback: (err: Error, jsonObject: any) => void): void;
|
||||
export function readJSON(file: string, callback: (err: Error, jsonObject: any) => void): void;
|
||||
export function readJSON(file: string, options: OpenOptions, callback: (err: Error, jsonObject: any) => void): void;
|
||||
|
||||
export function readJsonSync(file: string, options?: OpenOptions): any;
|
||||
export function readJSONSync(file: string, options?: OpenOptions): any;
|
||||
|
||||
export function remove(dir: string, callback?: (err: Error) => void): void;
|
||||
export function removeSync(dir: string): void;
|
||||
|
||||
export function writeJson(file: string, object: any, callback?: (err: Error) => void): void;
|
||||
export function writeJson(file: string, object: any, options?: OpenOptions, callback?: (err: Error) => void): void;
|
||||
export function writeJSON(file: string, object: any, callback?: (err: Error) => void): void;
|
||||
export function writeJSON(file: string, object: any, options?: OpenOptions, callback?: (err: Error) => void): void;
|
||||
|
||||
export function writeJsonSync(file: string, object: any, options?: OpenOptions): void;
|
||||
export function writeJSONSync(file: string, object: any, options?: OpenOptions): void;
|
||||
|
||||
export function ensureDir(path: string, cb: (err: Error) => void): void;
|
||||
export function ensureDirSync(path: string): void;
|
||||
|
||||
export function ensureFile(path: string, cb: (err: Error) => void): void;
|
||||
export function ensureFileSync(path: string): void;
|
||||
|
||||
export function ensureLink(path: string, cb: (err: Error) => void): void;
|
||||
export function ensureLinkSync(path: string): void;
|
||||
|
||||
export function ensureSymlink(path: string, cb: (err: Error) => void): void;
|
||||
export function ensureSymlinkSync(path: string): void;
|
||||
|
||||
export function emptyDir(path: string, callback?: (err: Error) => void): void;
|
||||
export function emptyDirSync(path: string): boolean;
|
||||
|
||||
export interface CopyFilterFunction {
|
||||
(src: string): boolean
|
||||
}
|
||||
|
||||
export type CopyFilter = CopyFilterFunction | RegExp;
|
||||
|
||||
export interface CopyOptions {
|
||||
clobber?: boolean
|
||||
preserveTimestamps?: boolean
|
||||
dereference?: boolean
|
||||
filter?: CopyFilter
|
||||
}
|
||||
|
||||
export interface OpenOptions {
|
||||
encoding?: string;
|
||||
flag?: string;
|
||||
}
|
||||
|
||||
export interface MkdirOptions {
|
||||
fs?: any;
|
||||
mode?: number;
|
||||
}
|
||||
}
|
290
TypeScriptDefinitions/gulp.d.ts
vendored
@ -1,290 +0,0 @@
|
||||
// Type definitions for Gulp v3.8.x
|
||||
// Project: http://gulpjs.com
|
||||
// Definitions by: Drew Noakes <https://drewnoakes.com>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
/// <reference path="../node/node.d.ts" />
|
||||
/// <reference path="../orchestrator/orchestrator.d.ts" />
|
||||
|
||||
declare module "gulp" {
|
||||
import Orchestrator = require("orchestrator");
|
||||
|
||||
namespace gulp {
|
||||
interface Gulp extends Orchestrator {
|
||||
/**
|
||||
* Define a task
|
||||
* @param name The name of the task.
|
||||
* @param deps An array of task names to be executed and completed before your task will run.
|
||||
* @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete:
|
||||
* <ul>
|
||||
* <li>Take in a callback</li>
|
||||
* <li>Return a stream or a promise</li>
|
||||
* </ul>
|
||||
*/
|
||||
task: Orchestrator.AddMethod;
|
||||
/**
|
||||
* Emits files matching provided glob or an array of globs. Returns a stream of Vinyl files that can be piped to plugins.
|
||||
* @param glob Glob or array of globs to read.
|
||||
* @param opt Options to pass to node-glob through glob-stream.
|
||||
*/
|
||||
src: SrcMethod;
|
||||
/**
|
||||
* Can be piped to and it will write files. Re-emits all data passed to it so you can pipe to multiple folders.
|
||||
* Folders that don't exist will be created.
|
||||
*
|
||||
* @param outFolder The path (output folder) to write files to. Or a function that returns it, the function will be provided a vinyl File instance.
|
||||
* @param opt
|
||||
*/
|
||||
dest: DestMethod;
|
||||
/**
|
||||
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
|
||||
*
|
||||
* @param glob a single glob or array of globs that indicate which files to watch for changes.
|
||||
* @param opt options, that are passed to the gaze library.
|
||||
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
|
||||
*/
|
||||
watch: WatchMethod;
|
||||
}
|
||||
|
||||
interface GulpPlugin {
|
||||
(...args: any[]): NodeJS.ReadWriteStream;
|
||||
}
|
||||
|
||||
interface WatchMethod {
|
||||
/**
|
||||
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
|
||||
*
|
||||
* @param glob a single glob or array of globs that indicate which files to watch for changes.
|
||||
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
|
||||
*/
|
||||
(glob: string|string[], fn: (WatchCallback|string)): NodeJS.EventEmitter;
|
||||
/**
|
||||
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
|
||||
*
|
||||
* @param glob a single glob or array of globs that indicate which files to watch for changes.
|
||||
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
|
||||
*/
|
||||
(glob: string|string[], fn: (WatchCallback|string)[]): NodeJS.EventEmitter;
|
||||
/**
|
||||
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
|
||||
*
|
||||
* @param glob a single glob or array of globs that indicate which files to watch for changes.
|
||||
* @param opt options, that are passed to the gaze library.
|
||||
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
|
||||
*/
|
||||
(glob: string|string[], opt: WatchOptions, fn: (WatchCallback|string)): NodeJS.EventEmitter;
|
||||
/**
|
||||
* Watch files and do something when a file changes. This always returns an EventEmitter that emits change events.
|
||||
*
|
||||
* @param glob a single glob or array of globs that indicate which files to watch for changes.
|
||||
* @param opt options, that are passed to the gaze library.
|
||||
* @param fn a callback or array of callbacks to be called on each change, or names of task(s) to run when a file changes, added with task().
|
||||
*/
|
||||
(glob: string|string[], opt: WatchOptions, fn: (WatchCallback|string)[]): NodeJS.EventEmitter;
|
||||
|
||||
}
|
||||
|
||||
interface DestMethod {
|
||||
/**
|
||||
* Can be piped to and it will write files. Re-emits all data passed to it so you can pipe to multiple folders.
|
||||
* Folders that don't exist will be created.
|
||||
*
|
||||
* @param outFolder The path (output folder) to write files to. Or a function that returns it, the function will be provided a vinyl File instance.
|
||||
* @param opt
|
||||
*/
|
||||
(outFolder: string|((file: string) => string), opt?: DestOptions): NodeJS.ReadWriteStream;
|
||||
}
|
||||
|
||||
interface SrcMethod {
|
||||
/**
|
||||
* Emits files matching provided glob or an array of globs. Returns a stream of Vinyl files that can be piped to plugins.
|
||||
* @param glob Glob or array of globs to read.
|
||||
* @param opt Options to pass to node-glob through glob-stream.
|
||||
*/
|
||||
(glob: string|string[], opt?: SrcOptions): NodeJS.ReadWriteStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options to pass to node-glob through glob-stream.
|
||||
* Specifies two options in addition to those used by node-glob:
|
||||
* https://github.com/isaacs/node-glob#options
|
||||
*/
|
||||
interface SrcOptions {
|
||||
/**
|
||||
* Setting this to <code>false</code> will return <code>file.contents</code> as <code>null</code>
|
||||
* and not read the file at all.
|
||||
* Default: <code>true</code>.
|
||||
*/
|
||||
read?: boolean;
|
||||
|
||||
/**
|
||||
* Setting this to false will return <code>file.contents</code> as a stream and not buffer files.
|
||||
* This is useful when working with large files.
|
||||
* Note: Plugins might not implement support for streams.
|
||||
* Default: <code>true</code>.
|
||||
*/
|
||||
buffer?: boolean;
|
||||
|
||||
/**
|
||||
* The base path of a glob.
|
||||
*
|
||||
* Default is everything before a glob starts.
|
||||
*/
|
||||
base?: string;
|
||||
|
||||
/**
|
||||
* The current working directory in which to search.
|
||||
* Defaults to process.cwd().
|
||||
*/
|
||||
cwd?: string;
|
||||
|
||||
/**
|
||||
* The place where patterns starting with / will be mounted onto.
|
||||
* Defaults to path.resolve(options.cwd, "/") (/ on Unix systems, and C:\ or some such on Windows.)
|
||||
*/
|
||||
root?: string;
|
||||
|
||||
/**
|
||||
* Include .dot files in normal matches and globstar matches.
|
||||
* Note that an explicit dot in a portion of the pattern will always match dot files.
|
||||
*/
|
||||
dot?: boolean;
|
||||
|
||||
/**
|
||||
* By default, a pattern starting with a forward-slash will be "mounted" onto the root setting, so that a valid
|
||||
* filesystem path is returned. Set this flag to disable that behavior.
|
||||
*/
|
||||
nomount?: boolean;
|
||||
|
||||
/**
|
||||
* Add a / character to directory matches. Note that this requires additional stat calls.
|
||||
*/
|
||||
mark?: boolean;
|
||||
|
||||
/**
|
||||
* Don't sort the results.
|
||||
*/
|
||||
nosort?: boolean;
|
||||
|
||||
/**
|
||||
* Set to true to stat all results. This reduces performance somewhat, and is completely unnecessary, unless
|
||||
* readdir is presumed to be an untrustworthy indicator of file existence. It will cause ELOOP to be triggered one
|
||||
* level sooner in the case of cyclical symbolic links.
|
||||
*/
|
||||
stat?: boolean;
|
||||
|
||||
/**
|
||||
* When an unusual error is encountered when attempting to read a directory, a warning will be printed to stderr.
|
||||
* Set the silent option to true to suppress these warnings.
|
||||
*/
|
||||
silent?: boolean;
|
||||
|
||||
/**
|
||||
* When an unusual error is encountered when attempting to read a directory, the process will just continue on in
|
||||
* search of other matches. Set the strict option to raise an error in these cases.
|
||||
*/
|
||||
strict?: boolean;
|
||||
|
||||
/**
|
||||
* See cache property above. Pass in a previously generated cache object to save some fs calls.
|
||||
*/
|
||||
cache?: boolean;
|
||||
|
||||
/**
|
||||
* A cache of results of filesystem information, to prevent unnecessary stat calls.
|
||||
* While it should not normally be necessary to set this, you may pass the statCache from one glob() call to the
|
||||
* options object of another, if you know that the filesystem will not change between calls.
|
||||
*/
|
||||
statCache?: boolean;
|
||||
|
||||
/**
|
||||
* Perform a synchronous glob search.
|
||||
*/
|
||||
sync?: boolean;
|
||||
|
||||
/**
|
||||
* In some cases, brace-expanded patterns can result in the same file showing up multiple times in the result set.
|
||||
* By default, this implementation prevents duplicates in the result set. Set this flag to disable that behavior.
|
||||
*/
|
||||
nounique?: boolean;
|
||||
|
||||
/**
|
||||
* Set to never return an empty set, instead returning a set containing the pattern itself.
|
||||
* This is the default in glob(3).
|
||||
*/
|
||||
nonull?: boolean;
|
||||
|
||||
/**
|
||||
* Perform a case-insensitive match. Note that case-insensitive filesystems will sometimes result in glob returning
|
||||
* results that are case-insensitively matched anyway, since readdir and stat will not raise an error.
|
||||
*/
|
||||
nocase?: boolean;
|
||||
|
||||
/**
|
||||
* Set to enable debug logging in minimatch and glob.
|
||||
*/
|
||||
debug?: boolean;
|
||||
|
||||
/**
|
||||
* Set to enable debug logging in glob, but not minimatch.
|
||||
*/
|
||||
globDebug?: boolean;
|
||||
}
|
||||
|
||||
interface DestOptions {
|
||||
/**
|
||||
* The output folder. Only has an effect if provided output folder is relative.
|
||||
* Default: process.cwd()
|
||||
*/
|
||||
cwd?: string;
|
||||
|
||||
/**
|
||||
* Octal permission string specifying mode for any folders that need to be created for output folder.
|
||||
* Default: 0777.
|
||||
*/
|
||||
mode?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options that are passed to <code>gaze</code>.
|
||||
* https://github.com/shama/gaze
|
||||
*/
|
||||
interface WatchOptions {
|
||||
/** Interval to pass to fs.watchFile. */
|
||||
interval?: number;
|
||||
/** Delay for events called in succession for the same file/event. */
|
||||
debounceDelay?: number;
|
||||
/** Force the watch mode. Either 'auto' (default), 'watch' (force native events), or 'poll' (force stat polling). */
|
||||
mode?: string;
|
||||
/** The current working directory to base file patterns from. Default is process.cwd().. */
|
||||
cwd?: string;
|
||||
}
|
||||
|
||||
interface WatchEvent {
|
||||
/** The type of change that occurred, either added, changed or deleted. */
|
||||
type: string;
|
||||
/** The path to the file that triggered the event. */
|
||||
path: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to be called on each watched file change.
|
||||
*/
|
||||
interface WatchCallback {
|
||||
(event: WatchEvent): void;
|
||||
}
|
||||
|
||||
interface TaskCallback {
|
||||
/**
|
||||
* Defines a task.
|
||||
* Tasks may be made asynchronous if they are passing a callback or return a promise or a stream.
|
||||
* @param cb callback used to signal asynchronous completion. Caller includes <code>err</code> in case of error.
|
||||
*/
|
||||
(cb?: (err?: any) => void): any;
|
||||
}
|
||||
}
|
||||
|
||||
var gulp: gulp.Gulp;
|
||||
|
||||
export = gulp;
|
||||
}
|
73
TypeScriptDefinitions/istanbul.d.ts
vendored
@ -1,73 +0,0 @@
|
||||
// Type definitions for Istanbul v0.4.0
|
||||
// Project: https://github.com/gotwarlost/istanbul
|
||||
// Definitions by: Tanguy Krotoff <https://github.com/tkrotoff>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
declare module 'istanbul' {
|
||||
namespace istanbul {
|
||||
interface Istanbul {
|
||||
new (options?: any): Istanbul;
|
||||
Collector: Collector;
|
||||
config: Config;
|
||||
ContentWriter: ContentWriter;
|
||||
FileWriter: FileWriter;
|
||||
hook: Hook;
|
||||
Instrumenter: Instrumenter;
|
||||
Report: Report;
|
||||
Reporter: Reporter;
|
||||
Store: Store;
|
||||
utils: ObjectUtils;
|
||||
VERSION: string;
|
||||
Writer: Writer;
|
||||
}
|
||||
|
||||
interface Collector {
|
||||
new (options?: any): Collector;
|
||||
add(coverage: any, testName?: string): void;
|
||||
}
|
||||
|
||||
interface Config {
|
||||
}
|
||||
|
||||
interface ContentWriter {
|
||||
}
|
||||
|
||||
interface FileWriter {
|
||||
}
|
||||
|
||||
interface Hook {
|
||||
}
|
||||
|
||||
interface Instrumenter {
|
||||
new (options?: any): Instrumenter;
|
||||
instrumentSync(code: string, filename: string): string;
|
||||
}
|
||||
|
||||
interface Report {
|
||||
}
|
||||
|
||||
interface Configuration {
|
||||
new (obj: any, overrides: any): Configuration;
|
||||
}
|
||||
|
||||
interface Reporter {
|
||||
new (cfg?: Configuration, dir?: string): Reporter;
|
||||
add(fmt: string): void;
|
||||
addAll(fmts: Array<string>): void;
|
||||
write(collector: Collector, sync: boolean, callback: Function): void;
|
||||
}
|
||||
|
||||
interface Store {
|
||||
}
|
||||
|
||||
interface ObjectUtils {
|
||||
}
|
||||
|
||||
interface Writer {
|
||||
}
|
||||
}
|
||||
|
||||
var istanbul: istanbul.Istanbul;
|
||||
|
||||
export = istanbul;
|
||||
}
|
508
TypeScriptDefinitions/jasmine.d.ts
vendored
@ -1,508 +0,0 @@
|
||||
// Type definitions for Jasmine 2.2
|
||||
// Project: http://jasmine.github.io/
|
||||
// Definitions by: Boris Yankov <https://github.com/borisyankov/>, Theodore Brown <https://github.com/theodorejb>, David Pärsson <https://github.com/davidparsson/>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
|
||||
// For ddescribe / iit use : https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/karma-jasmine/karma-jasmine.d.ts
|
||||
|
||||
declare function describe(description: string, specDefinitions: () => void): void;
|
||||
declare function fdescribe(description: string, specDefinitions: () => void): void;
|
||||
declare function xdescribe(description: string, specDefinitions: () => void): void;
|
||||
|
||||
declare function it(expectation: string, assertion?: () => void, timeout?: number): void;
|
||||
declare function it(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void;
|
||||
declare function fit(expectation: string, assertion?: () => void, timeout?: number): void;
|
||||
declare function fit(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void;
|
||||
declare function xit(expectation: string, assertion?: () => void, timeout?: number): void;
|
||||
declare function xit(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void;
|
||||
|
||||
/** If you call the function pending anywhere in the spec body, no matter the expectations, the spec will be marked pending. */
|
||||
declare function pending(reason?: string): void;
|
||||
|
||||
declare function beforeEach(action: () => void, timeout?: number): void;
|
||||
declare function beforeEach(action: (done: DoneFn) => void, timeout?: number): void;
|
||||
declare function afterEach(action: () => void, timeout?: number): void;
|
||||
declare function afterEach(action: (done: DoneFn) => void, timeout?: number): void;
|
||||
|
||||
declare function beforeAll(action: () => void, timeout?: number): void;
|
||||
declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void;
|
||||
declare function afterAll(action: () => void, timeout?: number): void;
|
||||
declare function afterAll(action: (done: DoneFn) => void, timeout?: number): void;
|
||||
|
||||
declare function expect(spy: Function): jasmine.Matchers;
|
||||
declare function expect(actual: any): jasmine.Matchers;
|
||||
|
||||
declare function fail(e?: any): void;
|
||||
/** Action method that should be called when the async work is complete */
|
||||
interface DoneFn extends Function {
|
||||
(): void;
|
||||
|
||||
/** fails the spec and indicates that it has completed. If the message is an Error, Error.message is used */
|
||||
fail: (message?: Error|string) => void;
|
||||
}
|
||||
|
||||
declare function spyOn(object: any, method: string): jasmine.Spy;
|
||||
|
||||
declare function runs(asyncMethod: Function): void;
|
||||
declare function waitsFor(latchMethod: () => boolean, failureMessage?: string, timeout?: number): void;
|
||||
declare function waits(timeout?: number): void;
|
||||
|
||||
declare namespace jasmine {
|
||||
|
||||
var clock: () => Clock;
|
||||
|
||||
function any(aclass: any): Any;
|
||||
function anything(): Any;
|
||||
function arrayContaining(sample: any[]): ArrayContaining;
|
||||
function objectContaining(sample: any): ObjectContaining;
|
||||
function createSpy(name: string, originalFn?: Function): Spy;
|
||||
function createSpyObj(baseName: string, methodNames: any[]): any;
|
||||
function createSpyObj<T>(baseName: string, methodNames: any[]): T;
|
||||
function pp(value: any): string;
|
||||
function getEnv(): Env;
|
||||
function addCustomEqualityTester(equalityTester: CustomEqualityTester): void;
|
||||
function addMatchers(matchers: CustomMatcherFactories): void;
|
||||
function stringMatching(str: string): Any;
|
||||
function stringMatching(str: RegExp): Any;
|
||||
|
||||
interface Any {
|
||||
|
||||
new (expectedClass: any): any;
|
||||
|
||||
jasmineMatches(other: any): boolean;
|
||||
jasmineToString(): string;
|
||||
}
|
||||
|
||||
// taken from TypeScript lib.core.es6.d.ts, applicable to CustomMatchers.contains()
|
||||
interface ArrayLike<T> {
|
||||
length: number;
|
||||
[n: number]: T;
|
||||
}
|
||||
|
||||
interface ArrayContaining {
|
||||
new (sample: any[]): any;
|
||||
|
||||
asymmetricMatch(other: any): boolean;
|
||||
jasmineToString(): string;
|
||||
}
|
||||
|
||||
interface ObjectContaining {
|
||||
new (sample: any): any;
|
||||
|
||||
jasmineMatches(other: any, mismatchKeys: any[], mismatchValues: any[]): boolean;
|
||||
jasmineToString(): string;
|
||||
}
|
||||
|
||||
interface Block {
|
||||
|
||||
new (env: Env, func: SpecFunction, spec: Spec): any;
|
||||
|
||||
execute(onComplete: () => void): void;
|
||||
}
|
||||
|
||||
interface WaitsBlock extends Block {
|
||||
new (env: Env, timeout: number, spec: Spec): any;
|
||||
}
|
||||
|
||||
interface WaitsForBlock extends Block {
|
||||
new (env: Env, timeout: number, latchFunction: SpecFunction, message: string, spec: Spec): any;
|
||||
}
|
||||
|
||||
interface Clock {
|
||||
install(): void;
|
||||
uninstall(): void;
|
||||
/** Calls to any registered callback are triggered when the clock is ticked forward via the jasmine.clock().tick function, which takes a number of milliseconds. */
|
||||
tick(ms: number): void;
|
||||
mockDate(date?: Date): void;
|
||||
}
|
||||
|
||||
interface CustomEqualityTester {
|
||||
(first: any, second: any): boolean;
|
||||
}
|
||||
|
||||
interface CustomMatcher {
|
||||
compare<T>(actual: T, expected: T): CustomMatcherResult;
|
||||
compare(actual: any, expected: any): CustomMatcherResult;
|
||||
}
|
||||
|
||||
interface CustomMatcherFactory {
|
||||
(util: MatchersUtil, customEqualityTesters: Array<CustomEqualityTester>): CustomMatcher;
|
||||
}
|
||||
|
||||
interface CustomMatcherFactories {
|
||||
[index: string]: CustomMatcherFactory;
|
||||
}
|
||||
|
||||
interface CustomMatcherResult {
|
||||
pass: boolean;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
interface MatchersUtil {
|
||||
equals(a: any, b: any, customTesters?: Array<CustomEqualityTester>): boolean;
|
||||
contains<T>(haystack: ArrayLike<T> | string, needle: any, customTesters?: Array<CustomEqualityTester>): boolean;
|
||||
buildFailureMessage(matcherName: string, isNot: boolean, actual: any, ...expected: Array<any>): string;
|
||||
}
|
||||
|
||||
interface Env {
|
||||
setTimeout: any;
|
||||
clearTimeout: void;
|
||||
setInterval: any;
|
||||
clearInterval: void;
|
||||
updateInterval: number;
|
||||
|
||||
currentSpec: Spec;
|
||||
|
||||
matchersClass: Matchers;
|
||||
|
||||
version(): any;
|
||||
versionString(): string;
|
||||
nextSpecId(): number;
|
||||
addReporter(reporter: Reporter): void;
|
||||
execute(): void;
|
||||
describe(description: string, specDefinitions: () => void): Suite;
|
||||
// ddescribe(description: string, specDefinitions: () => void): Suite; Not a part of jasmine. Angular team adds these
|
||||
beforeEach(beforeEachFunction: () => void): void;
|
||||
beforeAll(beforeAllFunction: () => void): void;
|
||||
currentRunner(): Runner;
|
||||
afterEach(afterEachFunction: () => void): void;
|
||||
afterAll(afterAllFunction: () => void): void;
|
||||
xdescribe(desc: string, specDefinitions: () => void): XSuite;
|
||||
it(description: string, func: () => void): Spec;
|
||||
// iit(description: string, func: () => void): Spec; Not a part of jasmine. Angular team adds these
|
||||
xit(desc: string, func: () => void): XSpec;
|
||||
compareRegExps_(a: RegExp, b: RegExp, mismatchKeys: string[], mismatchValues: string[]): boolean;
|
||||
compareObjects_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean;
|
||||
equals_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean;
|
||||
contains_(haystack: any, needle: any): boolean;
|
||||
addCustomEqualityTester(equalityTester: CustomEqualityTester): void;
|
||||
addMatchers(matchers: CustomMatcherFactories): void;
|
||||
specFilter(spec: Spec): boolean;
|
||||
throwOnExpectationFailure(value: boolean): void;
|
||||
}
|
||||
|
||||
interface FakeTimer {
|
||||
|
||||
new (): any;
|
||||
|
||||
reset(): void;
|
||||
tick(millis: number): void;
|
||||
runFunctionsWithinRange(oldMillis: number, nowMillis: number): void;
|
||||
scheduleFunction(timeoutKey: any, funcToCall: () => void, millis: number, recurring: boolean): void;
|
||||
}
|
||||
|
||||
interface HtmlReporter {
|
||||
new (): any;
|
||||
}
|
||||
|
||||
interface HtmlSpecFilter {
|
||||
new (): any;
|
||||
}
|
||||
|
||||
interface Result {
|
||||
type: string;
|
||||
}
|
||||
|
||||
interface NestedResults extends Result {
|
||||
description: string;
|
||||
|
||||
totalCount: number;
|
||||
passedCount: number;
|
||||
failedCount: number;
|
||||
|
||||
skipped: boolean;
|
||||
|
||||
rollupCounts(result: NestedResults): void;
|
||||
log(values: any): void;
|
||||
getItems(): Result[];
|
||||
addResult(result: Result): void;
|
||||
passed(): boolean;
|
||||
}
|
||||
|
||||
interface MessageResult extends Result {
|
||||
values: any;
|
||||
trace: Trace;
|
||||
}
|
||||
|
||||
interface ExpectationResult extends Result {
|
||||
matcherName: string;
|
||||
passed(): boolean;
|
||||
expected: any;
|
||||
actual: any;
|
||||
message: string;
|
||||
trace: Trace;
|
||||
}
|
||||
|
||||
interface Trace {
|
||||
name: string;
|
||||
message: string;
|
||||
stack: any;
|
||||
}
|
||||
|
||||
interface PrettyPrinter {
|
||||
|
||||
new (): any;
|
||||
|
||||
format(value: any): void;
|
||||
iterateObject(obj: any, fn: (property: string, isGetter: boolean) => void): void;
|
||||
emitScalar(value: any): void;
|
||||
emitString(value: string): void;
|
||||
emitArray(array: any[]): void;
|
||||
emitObject(obj: any): void;
|
||||
append(value: any): void;
|
||||
}
|
||||
|
||||
interface StringPrettyPrinter extends PrettyPrinter {
|
||||
}
|
||||
|
||||
interface Queue {
|
||||
|
||||
new (env: any): any;
|
||||
|
||||
env: Env;
|
||||
ensured: boolean[];
|
||||
blocks: Block[];
|
||||
running: boolean;
|
||||
index: number;
|
||||
offset: number;
|
||||
abort: boolean;
|
||||
|
||||
addBefore(block: Block, ensure?: boolean): void;
|
||||
add(block: any, ensure?: boolean): void;
|
||||
insertNext(block: any, ensure?: boolean): void;
|
||||
start(onComplete?: () => void): void;
|
||||
isRunning(): boolean;
|
||||
next_(): void;
|
||||
results(): NestedResults;
|
||||
}
|
||||
|
||||
interface Matchers {
|
||||
|
||||
new (env: Env, actual: any, spec: Env, isNot?: boolean): any;
|
||||
|
||||
env: Env;
|
||||
actual: any;
|
||||
spec: Env;
|
||||
isNot?: boolean;
|
||||
message(): any;
|
||||
|
||||
toBe(expected: any, expectationFailOutput?: any): boolean;
|
||||
toEqual(expected: any, expectationFailOutput?: any): boolean;
|
||||
toMatch(expected: string | RegExp, expectationFailOutput?: any): boolean;
|
||||
toBeDefined(expectationFailOutput?: any): boolean;
|
||||
toBeUndefined(expectationFailOutput?: any): boolean;
|
||||
toBeNull(expectationFailOutput?: any): boolean;
|
||||
toBeNaN(): boolean;
|
||||
toBeTruthy(expectationFailOutput?: any): boolean;
|
||||
toBeFalsy(expectationFailOutput?: any): boolean;
|
||||
toHaveBeenCalled(): boolean;
|
||||
toHaveBeenCalledWith(...params: any[]): boolean;
|
||||
toHaveBeenCalledTimes(expected: number): boolean;
|
||||
toContain(expected: any, expectationFailOutput?: any): boolean;
|
||||
toBeLessThan(expected: number, expectationFailOutput?: any): boolean;
|
||||
toBeGreaterThan(expected: number, expectationFailOutput?: any): boolean;
|
||||
toBeCloseTo(expected: number, precision?: any, expectationFailOutput?: any): boolean;
|
||||
toThrow(expected?: any): boolean;
|
||||
toThrowError(message?: string | RegExp): boolean;
|
||||
toThrowError(expected?: new (...args: any[]) => Error, message?: string | RegExp): boolean;
|
||||
not: Matchers;
|
||||
|
||||
Any: Any;
|
||||
}
|
||||
|
||||
interface Reporter {
|
||||
reportRunnerStarting(runner: Runner): void;
|
||||
reportRunnerResults(runner: Runner): void;
|
||||
reportSuiteResults(suite: Suite): void;
|
||||
reportSpecStarting(spec: Spec): void;
|
||||
reportSpecResults(spec: Spec): void;
|
||||
log(str: string): void;
|
||||
}
|
||||
|
||||
interface MultiReporter extends Reporter {
|
||||
addReporter(reporter: Reporter): void;
|
||||
}
|
||||
|
||||
interface Runner {
|
||||
|
||||
new (env: Env): any;
|
||||
|
||||
execute(): void;
|
||||
beforeEach(beforeEachFunction: SpecFunction): void;
|
||||
afterEach(afterEachFunction: SpecFunction): void;
|
||||
beforeAll(beforeAllFunction: SpecFunction): void;
|
||||
afterAll(afterAllFunction: SpecFunction): void;
|
||||
finishCallback(): void;
|
||||
addSuite(suite: Suite): void;
|
||||
add(block: Block): void;
|
||||
specs(): Spec[];
|
||||
suites(): Suite[];
|
||||
topLevelSuites(): Suite[];
|
||||
results(): NestedResults;
|
||||
}
|
||||
|
||||
interface SpecFunction {
|
||||
(spec?: Spec): void;
|
||||
}
|
||||
|
||||
interface SuiteOrSpec {
|
||||
id: number;
|
||||
env: Env;
|
||||
description: string;
|
||||
queue: Queue;
|
||||
}
|
||||
|
||||
interface Spec extends SuiteOrSpec {
|
||||
|
||||
new (env: Env, suite: Suite, description: string): any;
|
||||
|
||||
suite: Suite;
|
||||
|
||||
afterCallbacks: SpecFunction[];
|
||||
spies_: Spy[];
|
||||
|
||||
results_: NestedResults;
|
||||
matchersClass: Matchers;
|
||||
|
||||
getFullName(): string;
|
||||
results(): NestedResults;
|
||||
log(arguments: any): any;
|
||||
runs(func: SpecFunction): Spec;
|
||||
addToQueue(block: Block): void;
|
||||
addMatcherResult(result: Result): void;
|
||||
expect(actual: any): any;
|
||||
waits(timeout: number): Spec;
|
||||
waitsFor(latchFunction: SpecFunction, timeoutMessage?: string, timeout?: number): Spec;
|
||||
fail(e?: any): void;
|
||||
getMatchersClass_(): Matchers;
|
||||
addMatchers(matchersPrototype: CustomMatcherFactories): void;
|
||||
finishCallback(): void;
|
||||
finish(onComplete?: () => void): void;
|
||||
after(doAfter: SpecFunction): void;
|
||||
execute(onComplete?: () => void): any;
|
||||
addBeforesAndAftersToQueue(): void;
|
||||
explodes(): void;
|
||||
spyOn(obj: any, methodName: string, ignoreMethodDoesntExist: boolean): Spy;
|
||||
removeAllSpies(): void;
|
||||
}
|
||||
|
||||
interface XSpec {
|
||||
id: number;
|
||||
runs(): void;
|
||||
}
|
||||
|
||||
interface Suite extends SuiteOrSpec {
|
||||
|
||||
new (env: Env, description: string, specDefinitions: () => void, parentSuite: Suite): any;
|
||||
|
||||
parentSuite: Suite;
|
||||
|
||||
getFullName(): string;
|
||||
finish(onComplete?: () => void): void;
|
||||
beforeEach(beforeEachFunction: SpecFunction): void;
|
||||
afterEach(afterEachFunction: SpecFunction): void;
|
||||
beforeAll(beforeAllFunction: SpecFunction): void;
|
||||
afterAll(afterAllFunction: SpecFunction): void;
|
||||
results(): NestedResults;
|
||||
add(suiteOrSpec: SuiteOrSpec): void;
|
||||
specs(): Spec[];
|
||||
suites(): Suite[];
|
||||
children(): any[];
|
||||
execute(onComplete?: () => void): void;
|
||||
}
|
||||
|
||||
interface XSuite {
|
||||
execute(): void;
|
||||
}
|
||||
|
||||
interface Spy {
|
||||
(...params: any[]): any;
|
||||
|
||||
identity: string;
|
||||
and: SpyAnd;
|
||||
calls: Calls;
|
||||
mostRecentCall: { args: any[]; };
|
||||
argsForCall: any[];
|
||||
wasCalled: boolean;
|
||||
}
|
||||
|
||||
interface SpyAnd {
|
||||
/** By chaining the spy with and.callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation. */
|
||||
callThrough(): Spy;
|
||||
/** By chaining the spy with and.returnValue, all calls to the function will return a specific value. */
|
||||
returnValue(val: any): Spy;
|
||||
/** By chaining the spy with and.returnValues, all calls to the function will return specific values in order until it reaches the end of the return values list. */
|
||||
returnValues(...values: any[]): Spy;
|
||||
/** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied function. */
|
||||
callFake(fn: Function): Spy;
|
||||
/** By chaining the spy with and.throwError, all calls to the spy will throw the specified value. */
|
||||
throwError(msg: string): Spy;
|
||||
/** When a calling strategy is used for a spy, the original stubbing behavior can be returned at any time with and.stub. */
|
||||
stub(): Spy;
|
||||
}
|
||||
|
||||
interface Calls {
|
||||
/** By chaining the spy with calls.any(), will return false if the spy has not been called at all, and then true once at least one call happens. **/
|
||||
any(): boolean;
|
||||
/** By chaining the spy with calls.count(), will return the number of times the spy was called **/
|
||||
count(): number;
|
||||
/** By chaining the spy with calls.argsFor(), will return the arguments passed to call number index **/
|
||||
argsFor(index: number): any[];
|
||||
/** By chaining the spy with calls.allArgs(), will return the arguments to all calls **/
|
||||
allArgs(): any[];
|
||||
/** By chaining the spy with calls.all(), will return the context (the this) and arguments passed all calls **/
|
||||
all(): CallInfo[];
|
||||
/** By chaining the spy with calls.mostRecent(), will return the context (the this) and arguments for the most recent call **/
|
||||
mostRecent(): CallInfo;
|
||||
/** By chaining the spy with calls.first(), will return the context (the this) and arguments for the first call **/
|
||||
first(): CallInfo;
|
||||
/** By chaining the spy with calls.reset(), will clears all tracking for a spy **/
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
interface CallInfo {
|
||||
/** The context (the this) for the call */
|
||||
object: any;
|
||||
/** All arguments passed to the call */
|
||||
args: any[];
|
||||
/** The return value of the call */
|
||||
returnValue: any;
|
||||
}
|
||||
|
||||
interface Util {
|
||||
inherit(childClass: Function, parentClass: Function): any;
|
||||
formatException(e: any): any;
|
||||
htmlEscape(str: string): string;
|
||||
argsToArray(args: any): any;
|
||||
extend(destination: any, source: any): any;
|
||||
}
|
||||
|
||||
interface JsApiReporter extends Reporter {
|
||||
|
||||
started: boolean;
|
||||
finished: boolean;
|
||||
result: any;
|
||||
messages: any;
|
||||
|
||||
new (): any;
|
||||
|
||||
suites(): Suite[];
|
||||
summarize_(suiteOrSpec: SuiteOrSpec): any;
|
||||
results(): any;
|
||||
resultsForSpec(specId: any): any;
|
||||
log(str: any): any;
|
||||
resultsForSpecs(specIds: any): any;
|
||||
summarizeResult_(result: any): any;
|
||||
}
|
||||
|
||||
interface Jasmine {
|
||||
Spec: Spec;
|
||||
clock: Clock;
|
||||
util: Util;
|
||||
}
|
||||
|
||||
export var HtmlReporter: HtmlReporter;
|
||||
export var HtmlSpecFilter: HtmlSpecFilter;
|
||||
export var DEFAULT_TIMEOUT_INTERVAL: number;
|
||||
}
|
9
TypeScriptDefinitions/open.d.ts
vendored
@ -1,9 +0,0 @@
|
||||
// Type definitions for open 0.0.3
|
||||
// Project: https://github.com/jjrdn/node-open
|
||||
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
declare module 'open' {
|
||||
function open(target: string, app?: string): void;
|
||||
export = open;
|
||||
}
|
262
TypeScriptDefinitions/request.d.ts
vendored
@ -1,262 +0,0 @@
|
||||
// Type definitions for request
|
||||
// Project: https://github.com/mikeal/request
|
||||
// Definitions by: Carlos Ballesteros Velasco <https://github.com/soywiz>, bonnici <https://github.com/bonnici>, Bart van der Schoor <https://github.com/Bartvds>, Joe Skeen <http://github.com/joeskeen>, Christopher Currens <https://github.com/ccurrens>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
// Imported from: https://github.com/soywiz/typescript-node-definitions/d.ts
|
||||
|
||||
/// <reference path="../node/node.d.ts" />
|
||||
/// <reference path="../form-data/form-data.d.ts" />
|
||||
|
||||
declare module 'request' {
|
||||
import stream = require('stream');
|
||||
import http = require('http');
|
||||
import https = require('https');
|
||||
import FormData = require('form-data');
|
||||
import url = require('url');
|
||||
import fs = require('fs');
|
||||
|
||||
namespace request {
|
||||
export interface RequestAPI<TRequest extends Request,
|
||||
TOptions extends CoreOptions,
|
||||
TUriUrlOptions> {
|
||||
|
||||
defaults(options: TOptions): RequestAPI<TRequest, TOptions, RequiredUriUrl>;
|
||||
defaults(options: RequiredUriUrl & TOptions): DefaultUriUrlRequestApi<TRequest, TOptions, OptionalUriUrl>;
|
||||
|
||||
(uri: string, options?: TOptions, callback?: RequestCallback): TRequest;
|
||||
(uri: string, callback?: RequestCallback): TRequest;
|
||||
(options: TUriUrlOptions & TOptions, callback?: RequestCallback): TRequest;
|
||||
|
||||
get(uri: string, options?: TOptions, callback?: RequestCallback): TRequest;
|
||||
get(uri: string, callback?: RequestCallback): TRequest;
|
||||
get(options: TUriUrlOptions & TOptions, callback?: RequestCallback): TRequest;
|
||||
|
||||
post(uri: string, options?: TOptions, callback?: RequestCallback): TRequest;
|
||||
post(uri: string, callback?: RequestCallback): TRequest;
|
||||
post(options: TUriUrlOptions & TOptions, callback?: RequestCallback): TRequest;
|
||||
|
||||
put(uri: string, options?: TOptions, callback?: RequestCallback): TRequest;
|
||||
put(uri: string, callback?: RequestCallback): TRequest;
|
||||
put(options: TUriUrlOptions & TOptions, callback?: RequestCallback): TRequest;
|
||||
|
||||
head(uri: string, options?: TOptions, callback?: RequestCallback): TRequest;
|
||||
head(uri: string, callback?: RequestCallback): TRequest;
|
||||
head(options: TUriUrlOptions & TOptions, callback?: RequestCallback): TRequest;
|
||||
|
||||
patch(uri: string, options?: TOptions, callback?: RequestCallback): TRequest;
|
||||
patch(uri: string, callback?: RequestCallback): TRequest;
|
||||
patch(options: TUriUrlOptions & TOptions, callback?: RequestCallback): TRequest;
|
||||
|
||||
del(uri: string, options?: TOptions, callback?: RequestCallback): TRequest;
|
||||
del(uri: string, callback?: RequestCallback): TRequest;
|
||||
del(options: TUriUrlOptions & TOptions, callback?: RequestCallback): TRequest;
|
||||
|
||||
forever(agentOptions: any, optionsArg: any): TRequest;
|
||||
jar(): CookieJar;
|
||||
cookie(str: string): Cookie;
|
||||
|
||||
initParams: any;
|
||||
debug: boolean;
|
||||
}
|
||||
|
||||
interface DefaultUriUrlRequestApi<TRequest extends Request,
|
||||
TOptions extends CoreOptions,
|
||||
TUriUrlOptions> extends RequestAPI<TRequest, TOptions, TUriUrlOptions> {
|
||||
|
||||
defaults(options: TOptions): DefaultUriUrlRequestApi<TRequest, TOptions, OptionalUriUrl>;
|
||||
(): TRequest;
|
||||
get(): TRequest;
|
||||
post(): TRequest;
|
||||
put(): TRequest;
|
||||
head(): TRequest;
|
||||
patch(): TRequest;
|
||||
del(): TRequest;
|
||||
}
|
||||
|
||||
interface CoreOptions {
|
||||
baseUrl?: string;
|
||||
callback?: (error: any, response: http.IncomingMessage, body: any) => void;
|
||||
jar?: any; // CookieJar
|
||||
formData?: any; // Object
|
||||
form?: any; // Object or string
|
||||
auth?: AuthOptions;
|
||||
oauth?: OAuthOptions;
|
||||
aws?: AWSOptions;
|
||||
hawk?: HawkOptions;
|
||||
qs?: any;
|
||||
json?: any;
|
||||
multipart?: RequestPart[] | Multipart;
|
||||
agent?: http.Agent | https.Agent;
|
||||
agentOptions?: any;
|
||||
agentClass?: any;
|
||||
forever?: any;
|
||||
host?: string;
|
||||
port?: number;
|
||||
method?: string;
|
||||
headers?: Headers;
|
||||
body?: any;
|
||||
followRedirect?: boolean | ((response: http.IncomingMessage) => boolean);
|
||||
followAllRedirects?: boolean;
|
||||
maxRedirects?: number;
|
||||
encoding?: string;
|
||||
pool?: any;
|
||||
timeout?: number;
|
||||
proxy?: any;
|
||||
strictSSL?: boolean;
|
||||
gzip?: boolean;
|
||||
preambleCRLF?: boolean;
|
||||
postambleCRLF?: boolean;
|
||||
key?: Buffer;
|
||||
cert?: Buffer;
|
||||
passphrase?: string;
|
||||
ca?: string | Buffer | string[] | Buffer[];
|
||||
har?: HttpArchiveRequest;
|
||||
useQuerystring?: boolean;
|
||||
}
|
||||
|
||||
interface UriOptions {
|
||||
uri: string;
|
||||
}
|
||||
interface UrlOptions {
|
||||
url: string;
|
||||
}
|
||||
export type RequiredUriUrl = UriOptions | UrlOptions;
|
||||
|
||||
interface OptionalUriUrl {
|
||||
uri?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export type OptionsWithUri = UriOptions & CoreOptions;
|
||||
export type OptionsWithUrl = UrlOptions & CoreOptions;
|
||||
export type Options = OptionsWithUri | OptionsWithUrl;
|
||||
|
||||
export interface RequestCallback {
|
||||
(error: any, response: http.IncomingMessage, body: any): void;
|
||||
}
|
||||
|
||||
export interface HttpArchiveRequest {
|
||||
url?: string;
|
||||
method?: string;
|
||||
headers?: NameValuePair[];
|
||||
postData?: {
|
||||
mimeType?: string;
|
||||
params?: NameValuePair[];
|
||||
}
|
||||
}
|
||||
|
||||
export interface NameValuePair {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface Multipart {
|
||||
chunked?: boolean;
|
||||
data?: {
|
||||
'content-type'?: string,
|
||||
body: string
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface RequestPart {
|
||||
headers?: Headers;
|
||||
body: any;
|
||||
}
|
||||
|
||||
export interface Request extends stream.Stream {
|
||||
readable: boolean;
|
||||
writable: boolean;
|
||||
|
||||
getAgent(): http.Agent;
|
||||
//start(): void;
|
||||
//abort(): void;
|
||||
pipeDest(dest: any): void;
|
||||
setHeader(name: string, value: string, clobber?: boolean): Request;
|
||||
setHeaders(headers: Headers): Request;
|
||||
qs(q: Object, clobber?: boolean): Request;
|
||||
form(): FormData.FormData;
|
||||
form(form: any): Request;
|
||||
multipart(multipart: RequestPart[]): Request;
|
||||
json(val: any): Request;
|
||||
aws(opts: AWSOptions, now?: boolean): Request;
|
||||
auth(username: string, password: string, sendInmediately?: boolean, bearer?: string): Request;
|
||||
oauth(oauth: OAuthOptions): Request;
|
||||
jar(jar: CookieJar): Request;
|
||||
|
||||
on(event: string, listener: Function): this;
|
||||
on(event: 'request', listener: (req: http.ClientRequest) => void): this;
|
||||
on(event: 'response', listener: (resp: http.IncomingMessage) => void): this;
|
||||
on(event: 'data', listener: (data: Buffer | string) => void): this;
|
||||
on(event: 'error', listener: (e: Error) => void): this;
|
||||
on(event: 'complete', listener: (resp: http.IncomingMessage, body?: string | Buffer) => void): this;
|
||||
|
||||
write(buffer: Buffer, cb?: Function): boolean;
|
||||
write(str: string, cb?: Function): boolean;
|
||||
write(str: string, encoding: string, cb?: Function): boolean;
|
||||
write(str: string, encoding?: string, fd?: string): boolean;
|
||||
end(): void;
|
||||
end(chunk: Buffer, cb?: Function): void;
|
||||
end(chunk: string, cb?: Function): void;
|
||||
end(chunk: string, encoding: string, cb?: Function): void;
|
||||
pause(): void;
|
||||
resume(): void;
|
||||
abort(): void;
|
||||
destroy(): void;
|
||||
toJSON(): Object;
|
||||
}
|
||||
|
||||
export interface Headers {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface AuthOptions {
|
||||
user?: string;
|
||||
username?: string;
|
||||
pass?: string;
|
||||
password?: string;
|
||||
sendImmediately?: boolean;
|
||||
bearer?: string;
|
||||
}
|
||||
|
||||
export interface OAuthOptions {
|
||||
callback?: string;
|
||||
consumer_key?: string;
|
||||
consumer_secret?: string;
|
||||
token?: string;
|
||||
token_secret?: string;
|
||||
verifier?: string;
|
||||
}
|
||||
|
||||
export interface HawkOptions {
|
||||
credentials: any;
|
||||
}
|
||||
|
||||
export interface AWSOptions {
|
||||
secret: string;
|
||||
bucket?: string;
|
||||
}
|
||||
|
||||
export interface CookieJar {
|
||||
setCookie(cookie: Cookie, uri: string | url.Url, options?: any): void
|
||||
getCookieString(uri: string | url.Url): string
|
||||
getCookies(uri: string | url.Url): Cookie[]
|
||||
}
|
||||
|
||||
export interface CookieValue {
|
||||
name: string;
|
||||
value: any;
|
||||
httpOnly: boolean;
|
||||
}
|
||||
|
||||
export interface Cookie extends Array<CookieValue> {
|
||||
constructor(name: string, req: Request): void;
|
||||
str: string;
|
||||
expires: Date;
|
||||
path: string;
|
||||
toString(): string;
|
||||
}
|
||||
}
|
||||
var request: request.RequestAPI<request.Request, request.CoreOptions, request.RequiredUriUrl>;
|
||||
export = request;
|
||||
}
|
170
TypeScriptDefinitions/yargs.d.ts
vendored
@ -1,170 +0,0 @@
|
||||
// Type definitions for yargs
|
||||
// Project: https://github.com/chevex/yargs
|
||||
// Definitions by: Martin Poelstra <https://github.com/poelstra>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
declare module "yargs" {
|
||||
|
||||
namespace yargs {
|
||||
interface Argv {
|
||||
argv: any;
|
||||
(...args: any[]): any;
|
||||
parse(...args: any[]): any;
|
||||
|
||||
reset(): Argv;
|
||||
|
||||
locale(): string;
|
||||
locale(loc:string): Argv;
|
||||
|
||||
detectLocale(detect:boolean): Argv;
|
||||
|
||||
alias(shortName: string, longName: string): Argv;
|
||||
alias(aliases: { [shortName: string]: string }): Argv;
|
||||
alias(aliases: { [shortName: string]: string[] }): Argv;
|
||||
|
||||
array(key: string): Argv;
|
||||
array(keys: string[]): Argv;
|
||||
|
||||
default(key: string, value: any): Argv;
|
||||
default(defaults: { [key: string]: any}): Argv;
|
||||
|
||||
demand(key: string, msg: string): Argv;
|
||||
demand(key: string, required?: boolean): Argv;
|
||||
demand(keys: string[], msg: string): Argv;
|
||||
demand(keys: string[], required?: boolean): Argv;
|
||||
demand(positionals: number, required?: boolean): Argv;
|
||||
demand(positionals: number, msg: string): Argv;
|
||||
|
||||
require(key: string, msg: string): Argv;
|
||||
require(key: string, required: boolean): Argv;
|
||||
require(keys: number[], msg: string): Argv;
|
||||
require(keys: number[], required: boolean): Argv;
|
||||
require(positionals: number, required: boolean): Argv;
|
||||
require(positionals: number, msg: string): Argv;
|
||||
|
||||
required(key: string, msg: string): Argv;
|
||||
required(key: string, required: boolean): Argv;
|
||||
required(keys: number[], msg: string): Argv;
|
||||
required(keys: number[], required: boolean): Argv;
|
||||
required(positionals: number, required: boolean): Argv;
|
||||
required(positionals: number, msg: string): Argv;
|
||||
|
||||
requiresArg(key: string): Argv;
|
||||
requiresArg(keys: string[]): Argv;
|
||||
|
||||
describe(key: string, description: string): Argv;
|
||||
describe(descriptions: { [key: string]: string }): Argv;
|
||||
|
||||
option(key: string, options: Options): Argv;
|
||||
option(options: { [key: string]: Options }): Argv;
|
||||
options(key: string, options: Options): Argv;
|
||||
options(options: { [key: string]: Options }): Argv;
|
||||
|
||||
usage(message: string, options?: { [key: string]: Options }): Argv;
|
||||
usage(options?: { [key: string]: Options }): Argv;
|
||||
|
||||
command(command: string, description: string): Argv;
|
||||
command(command: string, description: string, handler: (args: Argv) => void): Argv;
|
||||
command(command: string, description: string, builder: (args: Argv) => Options): Argv;
|
||||
command(command: string, description: string, builder: { [optionName: string]: Options }): Argv;
|
||||
command(command: string, description: string, builder: { [optionName: string]: Options }, handler: (args: Argv) => void): Argv;
|
||||
command(command: string, description: string, builder: (args: Argv) => Options, handler: (args: Argv) => void): Argv;
|
||||
|
||||
completion(cmd: string, fn?: SyncCompletionFunction): Argv;
|
||||
completion(cmd: string, description?: string, fn?: SyncCompletionFunction): Argv;
|
||||
completion(cmd: string, fn?: AsyncCompletionFunction): Argv;
|
||||
completion(cmd: string, description?: string, fn?: AsyncCompletionFunction): Argv;
|
||||
|
||||
example(command: string, description: string): Argv;
|
||||
|
||||
check(func: (argv: any, aliases: { [alias: string]: string }) => any): Argv;
|
||||
|
||||
boolean(key: string): Argv;
|
||||
boolean(keys: string[]): Argv;
|
||||
|
||||
string(key: string): Argv;
|
||||
string(keys: string[]): Argv;
|
||||
|
||||
choices(choices: Object): Argv;
|
||||
choices(key: string, values:any[]): Argv;
|
||||
|
||||
config(key: string): Argv;
|
||||
config(keys: string[]): Argv;
|
||||
|
||||
wrap(columns: number): Argv;
|
||||
|
||||
strict(): Argv;
|
||||
|
||||
help(): string;
|
||||
help(option: string, description?: string): Argv;
|
||||
|
||||
env(prefix?: string): Argv;
|
||||
env(enable: boolean): Argv;
|
||||
|
||||
epilog(msg: string): Argv;
|
||||
epilogue(msg: string): Argv;
|
||||
|
||||
version(version: string, option?: string, description?: string): Argv;
|
||||
version(version: () => string, option?: string, description?: string): Argv;
|
||||
|
||||
showHelpOnFail(enable: boolean, message?: string): Argv;
|
||||
|
||||
showHelp(func?: (message: string) => any): Argv;
|
||||
|
||||
exitProcess(enabled:boolean): Argv;
|
||||
|
||||
global(key: string): Argv;
|
||||
global(keys: string[]): Argv;
|
||||
|
||||
group(key: string, groupName: string): Argv;
|
||||
group(keys: string[], groupName: string): Argv;
|
||||
|
||||
nargs(key: string, count: number): Argv;
|
||||
nargs(nargs: { [key: string]: number }): Argv;
|
||||
|
||||
/* Undocumented */
|
||||
|
||||
normalize(key: string): Argv;
|
||||
normalize(keys: string[]): Argv;
|
||||
|
||||
implies(key: string, value: string): Argv;
|
||||
implies(implies: { [key: string]: string }): Argv;
|
||||
|
||||
count(key: string): Argv;
|
||||
count(keys: string[]): Argv;
|
||||
|
||||
fail(func: (msg: string) => any): void;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
type?: string;
|
||||
group?: string;
|
||||
alias?: any;
|
||||
demand?: any;
|
||||
required?: any;
|
||||
require?: any;
|
||||
default?: any;
|
||||
defaultDescription?: string;
|
||||
boolean?: boolean;
|
||||
string?: boolean;
|
||||
count?: boolean;
|
||||
describe?: any;
|
||||
description?: any;
|
||||
desc?: any;
|
||||
requiresArg?: any;
|
||||
choices?:string[];
|
||||
global?: boolean;
|
||||
array?: boolean;
|
||||
config?: boolean;
|
||||
number?: boolean;
|
||||
normalize?: boolean;
|
||||
nargs?: number;
|
||||
}
|
||||
|
||||
type SyncCompletionFunction = (current: string, argv: any) => string[];
|
||||
type AsyncCompletionFunction = (current: string, argv: any, done: (completion: string[]) => void) => void;
|
||||
}
|
||||
|
||||
var yargs: yargs.Argv;
|
||||
export = yargs;
|
||||
}
|
174
bin/obj2gltf.js
@ -1,53 +1,147 @@
|
||||
#!/usr/bin/env node
|
||||
"use strict";
|
||||
var argv = require('yargs').argv;
|
||||
'use strict';
|
||||
var Cesium = require('cesium');
|
||||
var path = require('path');
|
||||
var yargs = require('yargs');
|
||||
var obj2gltf = require('../lib/obj2gltf');
|
||||
|
||||
var defined = Cesium.defined;
|
||||
var defaultValue = Cesium.defaultValue;
|
||||
var convert = require('../lib/convert');
|
||||
|
||||
if (process.argv.length < 3 || defined(argv.h) || defined(argv.help)) {
|
||||
console.log('Usage: ./bin/obj2gltf.js [INPUT] [OPTIONS]');
|
||||
console.log(' -i, --input Path to obj file');
|
||||
console.log(' -o, --output Directory or filename for the exported glTF file');
|
||||
console.log(' -b, --binary Output binary glTF');
|
||||
console.log(' -s --separate Writes out separate geometry/animation data files, shader files, and textures instead of embedding them in the glTF file.');
|
||||
console.log(' -t --separateImage Write out separate textures only.');
|
||||
console.log(' -c --compress Quantize positions, compress texture coordinates, and oct-encode normals.');
|
||||
console.log(' -h, --help Display this help');
|
||||
console.log(' --ao Apply ambient occlusion to the converted model');
|
||||
console.log(' --cesium Optimize the glTF for Cesium by using the sun as a default light source.');
|
||||
process.exit(0);
|
||||
var defaults = obj2gltf.defaults;
|
||||
|
||||
var args = process.argv;
|
||||
|
||||
var argv = yargs
|
||||
.usage('Usage: node $0 -i inputPath -o outputPath')
|
||||
.example('node $0 -i ./specs/data/box/box.obj -o box.gltf')
|
||||
.help('h')
|
||||
.alias('h', 'help')
|
||||
.options({
|
||||
input : {
|
||||
alias: 'i',
|
||||
describe: 'Path to the obj file.',
|
||||
type: 'string',
|
||||
normalize: true,
|
||||
demandOption: true
|
||||
},
|
||||
output : {
|
||||
alias: 'o',
|
||||
describe: 'Path of the converted glTF file.',
|
||||
type: 'string',
|
||||
normalize: true
|
||||
},
|
||||
binary : {
|
||||
alias: 'b',
|
||||
describe: 'Save as binary glTF.',
|
||||
type: 'boolean',
|
||||
default: defaults.binary
|
||||
},
|
||||
separate : {
|
||||
alias: 's',
|
||||
describe: 'Write separate geometry data files, shader files, and textures instead of embedding them in the glTF.',
|
||||
type: 'boolean',
|
||||
default: defaults.separate
|
||||
},
|
||||
separateTextures : {
|
||||
alias: 't',
|
||||
describe: 'Write out separate textures only.',
|
||||
type: 'boolean',
|
||||
default: defaults.separateTextures
|
||||
},
|
||||
compress : {
|
||||
alias: 'c',
|
||||
describe: 'Quantize positions, compress texture coordinates, and oct-encode normals.',
|
||||
type: 'boolean',
|
||||
default: defaults.compress
|
||||
},
|
||||
optimize : {
|
||||
alias: 'z',
|
||||
describe: 'Optimize the glTF for size and runtime performance.',
|
||||
type: 'boolean',
|
||||
default: defaults.optimize
|
||||
},
|
||||
optimizeForCesium : {
|
||||
describe: 'Optimize the glTF for Cesium by using the sun as a default light source.',
|
||||
type: 'boolean',
|
||||
default: defaults.optimizeForCesium
|
||||
},
|
||||
generateNormals : {
|
||||
alias: 'n',
|
||||
describe: 'Generate normals if they are missing.',
|
||||
type: 'boolean',
|
||||
default: defaults.generateNormals
|
||||
},
|
||||
ao : {
|
||||
describe: 'Apply ambient occlusion to the converted model.',
|
||||
type: 'boolean',
|
||||
default: defaults.ao
|
||||
},
|
||||
kmc : {
|
||||
describe: 'Output glTF with the KHR_materials_common extension.',
|
||||
type: 'boolean',
|
||||
default: defaults.kmc
|
||||
},
|
||||
bypassPipeline : {
|
||||
describe: 'Bypass the gltf-pipeline for debugging purposes. This option overrides many of the options above and will save the glTF with the KHR_materials_common extension.',
|
||||
type: 'boolean',
|
||||
default: defaults.bypassPipeline
|
||||
},
|
||||
checkTransparency : {
|
||||
describe: 'Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel. By default textures are considered to be opaque.',
|
||||
type: 'boolean',
|
||||
default: defaults.checkTransparency
|
||||
},
|
||||
secure : {
|
||||
describe: 'Prevent the converter from reading image or mtl files outside of the input obj directory.',
|
||||
type: 'boolean',
|
||||
default: defaults.secure
|
||||
},
|
||||
inputUpAxis : {
|
||||
describe: 'Up axis of the obj.',
|
||||
choices: ['X', 'Y', 'Z'],
|
||||
type: 'string',
|
||||
default: 'Y'
|
||||
},
|
||||
outputUpAxis : {
|
||||
describe: 'Up axis of the converted glTF.',
|
||||
choices: ['X', 'Y', 'Z'],
|
||||
type: 'string',
|
||||
default: 'Y'
|
||||
}
|
||||
}).parse(args);
|
||||
|
||||
var objPath = argv.i;
|
||||
var gltfPath = argv.o;
|
||||
|
||||
if (!defined(gltfPath)) {
|
||||
var extension = argv.b ? '.glb' : '.gltf';
|
||||
var modelName = path.basename(objPath, path.extname(objPath));
|
||||
gltfPath = path.join(path.dirname(objPath), modelName + extension);
|
||||
}
|
||||
|
||||
var objFile = defaultValue(argv._[0], defaultValue(argv.i, argv.input));
|
||||
var outputPath = defaultValue(argv._[1], defaultValue(argv.o, argv.output));
|
||||
var binary = defaultValue(defaultValue(argv.b, argv.binary), false);
|
||||
var separate = defaultValue(defaultValue(argv.s, argv.separate), false);
|
||||
var separateImage = defaultValue(defaultValue(argv.t, argv.separateImage), false);
|
||||
var compress = defaultValue(defaultValue(argv.c, argv.compress), false);
|
||||
var ao = defaultValue(argv.ao, false);
|
||||
var optimizeForCesium = defaultValue(argv.cesium, false);
|
||||
|
||||
if (!defined(objFile)) {
|
||||
throw new Error('-i or --input argument is required. See --help for details.');
|
||||
}
|
||||
var options = {
|
||||
binary : argv.binary,
|
||||
separate : argv.separate,
|
||||
separateTextures : argv.separateTextures,
|
||||
compress : argv.compress,
|
||||
optimize : argv.optimize,
|
||||
optimizeForCesium : argv.optimizeForCesium,
|
||||
generateNormals : argv.generateNormals,
|
||||
ao : argv.ao,
|
||||
kmc : argv.kmc,
|
||||
bypassPipeline : argv.bypassPipeline,
|
||||
checkTransparency : argv.checkTransparency,
|
||||
secure : argv.secure,
|
||||
inputUpAxis : argv.inputUpAxis,
|
||||
outputUpAxis : argv.outputUpAxis
|
||||
};
|
||||
|
||||
console.time('Total');
|
||||
|
||||
var options = {
|
||||
binary : binary,
|
||||
embed : !separate,
|
||||
embedImage : !separateImage,
|
||||
compress : compress,
|
||||
ao : ao,
|
||||
optimizeForCesium : optimizeForCesium
|
||||
};
|
||||
|
||||
convert(objFile, outputPath, options)
|
||||
obj2gltf(objPath, gltfPath, options)
|
||||
.then(function() {
|
||||
console.timeEnd('Total');
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.log(err);
|
||||
.catch(function(error) {
|
||||
console.log(error.message);
|
||||
});
|
||||
|
60
gulpfile.js
@ -4,12 +4,10 @@ var Cesium = require('cesium');
|
||||
var child_process = require('child_process');
|
||||
var fsExtra = require('fs-extra');
|
||||
var gulp = require('gulp');
|
||||
var gulpJshint = require('gulp-jshint');
|
||||
var Jasmine = require('jasmine');
|
||||
var JasmineSpecReporter = require('jasmine-spec-reporter');
|
||||
var JasmineSpecReporter = require('jasmine-spec-reporter').SpecReporter;
|
||||
var open = require('open');
|
||||
var path = require('path');
|
||||
var request = require('request');
|
||||
var yargs = require('yargs');
|
||||
|
||||
var defined = Cesium.defined;
|
||||
@ -21,24 +19,7 @@ var environmentSeparator = process.platform === 'win32' ? ';' : ':';
|
||||
var nodeBinaries = path.join(__dirname, 'node_modules', '.bin');
|
||||
process.env.PATH += environmentSeparator + nodeBinaries;
|
||||
|
||||
var jsHintFiles = ['**/*.js', '!node_modules/**', '!coverage/**'];
|
||||
var specFiles = ['**/*.js', '!node_modules/**', '!coverage/**'];
|
||||
|
||||
gulp.task('jsHint', function () {
|
||||
var stream = gulp.src(jsHintFiles)
|
||||
.pipe(gulpJshint())
|
||||
.pipe(gulpJshint.reporter('jshint-stylish'));
|
||||
|
||||
if (argv.failTaskOnError) {
|
||||
stream = stream.pipe(gulpJshint.reporter('fail'));
|
||||
}
|
||||
|
||||
return stream;
|
||||
});
|
||||
|
||||
gulp.task('jsHint-watch', function () {
|
||||
gulp.watch(jsHintFiles, ['jsHint']);
|
||||
});
|
||||
var specFiles = ['**/*.js', '!node_modules/**', '!coverage/**', '!doc/**', '!bin/**'];
|
||||
|
||||
gulp.task('test', function (done) {
|
||||
var jasmine = new Jasmine();
|
||||
@ -54,8 +35,8 @@ gulp.task('test', function (done) {
|
||||
|
||||
gulp.task('test-watch', function () {
|
||||
gulp.watch(specFiles).on('change', function () {
|
||||
//We can't simply depend on the test task because Jasmine
|
||||
//does not like being run multiple times in the same process.
|
||||
// We can't simply depend on the test task because Jasmine
|
||||
// does not like being run multiple times in the same process.
|
||||
try {
|
||||
child_process.execSync('jasmine JASMINE_CONFIG_PATH=specs/jasmine.json', {
|
||||
stdio: [process.stdin, process.stdout, process.stderr]
|
||||
@ -68,39 +49,14 @@ gulp.task('test-watch', function () {
|
||||
|
||||
gulp.task('coverage', function () {
|
||||
fsExtra.removeSync('coverage/server');
|
||||
child_process.execSync('istanbul' +
|
||||
' cover' +
|
||||
' --include-all-sources' +
|
||||
child_process.execSync('nyc' +
|
||||
' --all' +
|
||||
' --reporter=lcov' +
|
||||
' --dir coverage' +
|
||||
' -x "specs/** coverage/** index.js gulpfile.js"' +
|
||||
' -x "specs/**" -x "coverage/**" -x "doc/**" -x "bin/**" -x "index.js" -x "gulpfile.js"' +
|
||||
' node_modules/jasmine/bin/jasmine.js' +
|
||||
' JASMINE_CONFIG_PATH=specs/jasmine.json', {
|
||||
stdio: [process.stdin, process.stdout, process.stderr]
|
||||
});
|
||||
open('coverage/lcov-report/index.html');
|
||||
});
|
||||
|
||||
function copyModule(module) {
|
||||
var tsName = module + '.d.ts';
|
||||
var srcUrl = 'https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/master/' + module + '/' + tsName;
|
||||
var desPath = path.join('TypeScriptDefinitions', tsName);
|
||||
|
||||
request.get({
|
||||
url: srcUrl
|
||||
}, function (error, response) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
return;
|
||||
}
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
fsExtra.outputFileSync(desPath, response.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
gulp.task('update-ts-definitions', function () {
|
||||
fsExtra.removeSync('TypeScriptDefinitions');
|
||||
var packageJson = require('./package.json');
|
||||
Object.keys(packageJson.dependencies).forEach(copyModule);
|
||||
Object.keys(packageJson.devDependencies).forEach(copyModule);
|
||||
});
|
||||
|
5
index.js
@ -1,3 +1,2 @@
|
||||
module.exports = {
|
||||
convert : require('./lib/convert')
|
||||
};
|
||||
'use strict';
|
||||
module.exports = require('./lib/obj2gltf');
|
||||
|
107
lib/ArrayStorage.js
Normal file
@ -0,0 +1,107 @@
|
||||
'use strict';
|
||||
var Cesium = require('cesium');
|
||||
|
||||
var ComponentDatatype = Cesium.ComponentDatatype;
|
||||
|
||||
module.exports = ArrayStorage;
|
||||
|
||||
var initialLength = 1024; // 2^10
|
||||
var doublingThreshold = 33554432; // 2^25 (~134 MB for a Float32Array)
|
||||
var fixedExpansionLength = 33554432; // 2^25 (~134 MB for a Float32Array)
|
||||
|
||||
/**
|
||||
* Provides expandable typed array storage for geometry data. This is preferable to JS arrays which are
|
||||
* stored with double precision. The resizing mechanism is similar to std::vector.
|
||||
*
|
||||
* @param {ComponentDatatype} componentDatatype The data type.
|
||||
* @constructor
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function ArrayStorage(componentDatatype) {
|
||||
this.componentDatatype = componentDatatype;
|
||||
this.typedArray = ComponentDatatype.createTypedArray(componentDatatype, 0);
|
||||
this.length = 0;
|
||||
}
|
||||
|
||||
function resize(storage, length) {
|
||||
var typedArray = ComponentDatatype.createTypedArray(storage.componentDatatype, length);
|
||||
typedArray.set(storage.typedArray);
|
||||
storage.typedArray = typedArray;
|
||||
}
|
||||
|
||||
ArrayStorage.prototype.push = function(value) {
|
||||
var length = this.length;
|
||||
var typedArrayLength = this.typedArray.length;
|
||||
|
||||
if (length === 0) {
|
||||
resize(this, initialLength);
|
||||
} else if (length === typedArrayLength) {
|
||||
if (length < doublingThreshold) {
|
||||
resize(this, typedArrayLength * 2);
|
||||
} else {
|
||||
resize(this, typedArrayLength + fixedExpansionLength);
|
||||
}
|
||||
}
|
||||
|
||||
this.typedArray[this.length++] = value;
|
||||
};
|
||||
|
||||
ArrayStorage.prototype.get = function(index) {
|
||||
return this.typedArray[index];
|
||||
};
|
||||
|
||||
var sizeOfUint16 = 2;
|
||||
var sizeOfUint32 = 4;
|
||||
var sizeOfFloat = 4;
|
||||
|
||||
ArrayStorage.prototype.toUint16Buffer = function() {
|
||||
var length = this.length;
|
||||
var typedArray = this.typedArray;
|
||||
var paddedLength = length + ((length % 2 === 0) ? 0 : 1); // Round to next multiple of 2
|
||||
var buffer = Buffer.alloc(paddedLength * sizeOfUint16);
|
||||
for (var i = 0; i < length; ++i) {
|
||||
buffer.writeUInt16LE(typedArray[i], i * sizeOfUint16);
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
ArrayStorage.prototype.toUint32Buffer = function() {
|
||||
var length = this.length;
|
||||
var typedArray = this.typedArray;
|
||||
var buffer = Buffer.alloc(length * sizeOfUint32);
|
||||
for (var i = 0; i < length; ++i) {
|
||||
buffer.writeUInt32LE(typedArray[i], i * sizeOfUint32);
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
ArrayStorage.prototype.toFloatBuffer = function() {
|
||||
var length = this.length;
|
||||
var typedArray = this.typedArray;
|
||||
var buffer = Buffer.alloc(length * sizeOfFloat);
|
||||
for (var i = 0; i < length; ++i) {
|
||||
buffer.writeFloatLE(typedArray[i], i * sizeOfFloat);
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
ArrayStorage.prototype.getMinMax = function(components) {
|
||||
var length = this.length;
|
||||
var typedArray = this.typedArray;
|
||||
var count = length / components;
|
||||
var min = new Array(components).fill(Number.POSITIVE_INFINITY);
|
||||
var max = new Array(components).fill(Number.NEGATIVE_INFINITY);
|
||||
for (var i = 0; i < count; ++i) {
|
||||
for (var j = 0; j < components; ++j) {
|
||||
var index = i * components + j;
|
||||
var value = typedArray[index];
|
||||
min[j] = Math.min(min[j], value);
|
||||
max[j] = Math.max(max[j], value);
|
||||
}
|
||||
}
|
||||
return {
|
||||
min : min,
|
||||
max : max
|
||||
};
|
||||
};
|
19
lib/Material.js
Normal file
@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = Material;
|
||||
|
||||
function Material() {
|
||||
this.ambientColor = [0.0, 0.0, 0.0, 1.0]; // Ka
|
||||
this.emissionColor = [0.0, 0.0, 0.0, 1.0]; // Ke
|
||||
this.diffuseColor = [0.5, 0.5, 0.5, 1.0]; // Kd
|
||||
this.specularColor = [0.0, 0.0, 0.0, 1.0]; // Ks
|
||||
this.specularShininess = 0.0; // Ns
|
||||
this.alpha = 1.0; // d / Tr
|
||||
this.ambientTexture = undefined; // map_Ka
|
||||
this.emissionTexture = undefined; // map_Ke
|
||||
this.diffuseTexture = undefined; // map_Kd
|
||||
this.specularTexture = undefined; // map_Ks
|
||||
this.specularShininessMap = undefined; // map_Ns
|
||||
this.normalMap = undefined; // map_Bump
|
||||
this.alphaMap = undefined; // map_d
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
"use strict";
|
||||
var path = require('path');
|
||||
var GltfPipeline = require('gltf-pipeline').Pipeline;
|
||||
var parseObj = require('./obj');
|
||||
var createGltf = require('./gltf');
|
||||
var Cesium = require('cesium');
|
||||
var defined = Cesium.defined;
|
||||
var defaultValue = Cesium.defaultValue;
|
||||
|
||||
module.exports = convert;
|
||||
|
||||
function convert(objFile, outputPath, options) {
|
||||
options = defaultValue(options, {});
|
||||
var binary = defaultValue(options.binary, false);
|
||||
var embed = defaultValue(options.embed, true);
|
||||
var embedImage = defaultValue(options.embedImage, true);
|
||||
var compress = defaultValue(options.compress, false);
|
||||
var ao = defaultValue(options.ao, false);
|
||||
var optimizeForCesium = defaultValue(options.optimizeForCesium, false);
|
||||
|
||||
if (!defined(objFile)) {
|
||||
throw new Error('objFile is required');
|
||||
}
|
||||
|
||||
if (!defined(outputPath)) {
|
||||
outputPath = path.dirname(objFile);
|
||||
}
|
||||
|
||||
var inputPath = path.dirname(objFile);
|
||||
var modelName = path.basename(objFile, '.obj');
|
||||
|
||||
var extension = path.extname(outputPath);
|
||||
if (extension !== '') {
|
||||
modelName = path.basename(outputPath, extension);
|
||||
outputPath = path.dirname(outputPath);
|
||||
}
|
||||
|
||||
extension = binary ? '.glb' : '.gltf';
|
||||
var gltfFile = path.join(outputPath, modelName + extension);
|
||||
|
||||
return parseObj(objFile, inputPath)
|
||||
.then(function(data) {
|
||||
return createGltf(data, inputPath, modelName);
|
||||
})
|
||||
.then(function(gltf) {
|
||||
var aoOptions = ao ? {} : undefined;
|
||||
var options = {
|
||||
binary: binary,
|
||||
embed: embed,
|
||||
embedImage: embedImage,
|
||||
encodeNormals: compress,
|
||||
quantize: compress,
|
||||
aoOptions: aoOptions,
|
||||
optimizeForCesium : optimizeForCesium,
|
||||
createDirectory: false,
|
||||
basePath: inputPath
|
||||
};
|
||||
return GltfPipeline.processJSONToDisk(gltf, gltfFile, options);
|
||||
});
|
||||
}
|
347
lib/createGltf.js
Normal file
@ -0,0 +1,347 @@
|
||||
'use strict';
|
||||
var Cesium = require('cesium');
|
||||
var path = require('path');
|
||||
var Material = require('./Material');
|
||||
|
||||
var defined = Cesium.defined;
|
||||
var defaultValue = Cesium.defaultValue;
|
||||
var WebGLConstants = Cesium.WebGLConstants;
|
||||
|
||||
module.exports = createGltf;
|
||||
|
||||
/**
|
||||
* Create a glTF from obj data.
|
||||
*
|
||||
* @param {Object} objData Output of obj.js, containing an array of nodes containing geometry information, materials, and images.
|
||||
* @returns {Object} A glTF asset with the KHR_materials_common extension.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function createGltf(objData, options) {
|
||||
var nodes = objData.nodes;
|
||||
var materials = objData.materials;
|
||||
var images = objData.images;
|
||||
var sceneId = 'scene';
|
||||
var samplerId = 'sampler';
|
||||
var bufferId = 'buffer';
|
||||
var vertexBufferViewId = 'bufferView_vertex';
|
||||
var indexBufferViewId = 'bufferView_index';
|
||||
|
||||
var gltf = {
|
||||
accessors : {},
|
||||
asset : {},
|
||||
buffers : {},
|
||||
bufferViews : {},
|
||||
extensionsUsed : ['KHR_materials_common'],
|
||||
images : {},
|
||||
materials : {},
|
||||
meshes : {},
|
||||
nodes : {},
|
||||
samplers : {},
|
||||
scene : sceneId,
|
||||
scenes : {},
|
||||
textures : {}
|
||||
};
|
||||
|
||||
gltf.asset = {
|
||||
generator : 'obj2gltf',
|
||||
profile : {
|
||||
api : 'WebGL',
|
||||
version : '1.0'
|
||||
},
|
||||
version: '1.0'
|
||||
};
|
||||
|
||||
gltf.scenes[sceneId] = {
|
||||
nodes : []
|
||||
};
|
||||
|
||||
function getImageId(imagePath) {
|
||||
return path.basename(imagePath, path.extname(imagePath));
|
||||
}
|
||||
|
||||
function getTextureId(imagePath) {
|
||||
if (!defined(imagePath) || !defined(images[imagePath])) {
|
||||
return undefined;
|
||||
}
|
||||
return 'texture_' + getImageId(imagePath);
|
||||
}
|
||||
|
||||
function createMaterial(material, hasNormals, options) {
|
||||
var ambient = defaultValue(defaultValue(getTextureId(material.ambientTexture), material.ambientColor));
|
||||
var diffuse = defaultValue(defaultValue(getTextureId(material.diffuseTexture), material.diffuseColor));
|
||||
var emission = defaultValue(defaultValue(getTextureId(material.emissionTexture), material.emissionColor));
|
||||
var specular = defaultValue(defaultValue(getTextureId(material.specularTexture), material.specularColor));
|
||||
var alpha = defaultValue(defaultValue(material.alpha), 1.0);
|
||||
var shininess = defaultValue(material.specularShininess, 0.0);
|
||||
var hasSpecular = (shininess > 0.0) && (specular[0] > 0.0 || specular[1] > 0.0 || specular[2] > 0.0);
|
||||
|
||||
var transparent;
|
||||
var transparency = 1.0;
|
||||
if (typeof diffuse === 'string') {
|
||||
transparency = alpha;
|
||||
transparent = images[material.diffuseTexture].transparent || (transparency < 1.0);
|
||||
} else {
|
||||
diffuse[3] = alpha;
|
||||
transparent = diffuse[3] < 1.0;
|
||||
}
|
||||
|
||||
if (Array.isArray(ambient)) {
|
||||
// If ambient color is [1, 1, 1] assume it is a multiplier and instead change to [0, 0, 0]
|
||||
if (ambient[0] === 1.0 && ambient[1] === 1.0 && ambient[2] === 1.0) {
|
||||
ambient = [0.0, 0.0, 0.0, 1.0];
|
||||
}
|
||||
}
|
||||
|
||||
var doubleSided = transparent;
|
||||
|
||||
if (!hasNormals && !options.generateNormals) {
|
||||
// Constant technique only factors in ambient and emission sources - set emission to diffuse
|
||||
emission = diffuse;
|
||||
diffuse = [0, 0, 0, 1];
|
||||
}
|
||||
|
||||
var technique = hasNormals ? (hasSpecular ? 'PHONG' : 'LAMBERT') : 'CONSTANT';
|
||||
return {
|
||||
extensions : {
|
||||
KHR_materials_common : {
|
||||
technique : technique,
|
||||
transparent : transparent,
|
||||
doubleSided : doubleSided,
|
||||
values : {
|
||||
ambient : ambient,
|
||||
diffuse : diffuse,
|
||||
emission : emission,
|
||||
specular : specular,
|
||||
shininess : shininess,
|
||||
transparency : transparency,
|
||||
transparent : transparent,
|
||||
doubleSided : doubleSided
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (Object.keys(images).length > 0) {
|
||||
gltf.samplers[samplerId] = {
|
||||
magFilter : WebGLConstants.LINEAR,
|
||||
minFilter : WebGLConstants.NEAREST_MIPMAP_LINEAR,
|
||||
wrapS : WebGLConstants.REPEAT,
|
||||
wrapT : WebGLConstants.REPEAT
|
||||
};
|
||||
}
|
||||
|
||||
for (var imagePath in images) {
|
||||
if (images.hasOwnProperty(imagePath)) {
|
||||
var image = images[imagePath];
|
||||
var imageId = getImageId(imagePath);
|
||||
var textureId = getTextureId(imagePath);
|
||||
|
||||
gltf.images[imageId] = {
|
||||
name : imageId,
|
||||
extras : {
|
||||
_obj2gltf : {
|
||||
source : image.source,
|
||||
extension : image.extension
|
||||
}
|
||||
}
|
||||
};
|
||||
gltf.textures[textureId] = {
|
||||
format : image.format,
|
||||
internalFormat : image.format,
|
||||
sampler : samplerId,
|
||||
source : imageId,
|
||||
target : WebGLConstants.TEXTURE_2D,
|
||||
type : WebGLConstants.UNSIGNED_BYTE
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var vertexBuffers = [];
|
||||
var vertexBufferByteOffset = 0;
|
||||
var indexBuffers = [];
|
||||
var indexBufferByteOffset = 0;
|
||||
var accessorCount = 0;
|
||||
|
||||
function addVertexAttribute(array, components) {
|
||||
var count = array.length / components;
|
||||
var buffer = array.toFloatBuffer();
|
||||
var minMax = array.getMinMax(components);
|
||||
|
||||
var type = (components === 3 ? 'VEC3' : 'VEC2');
|
||||
var accessor = {
|
||||
bufferView : vertexBufferViewId,
|
||||
byteOffset : vertexBufferByteOffset,
|
||||
byteStride : 0,
|
||||
componentType : WebGLConstants.FLOAT,
|
||||
count : count,
|
||||
min : minMax.min,
|
||||
max : minMax.max,
|
||||
type : type
|
||||
};
|
||||
|
||||
vertexBufferByteOffset += buffer.length;
|
||||
vertexBuffers.push(buffer);
|
||||
var accessorId = 'accessor_' + accessorCount++;
|
||||
gltf.accessors[accessorId] = accessor;
|
||||
return accessorId;
|
||||
}
|
||||
|
||||
function addIndexArray(array, uint32Indices) {
|
||||
var buffer = uint32Indices ? array.toUint32Buffer() : array.toUint16Buffer();
|
||||
var componentType = uint32Indices ? WebGLConstants.UNSIGNED_INT : WebGLConstants.UNSIGNED_SHORT;
|
||||
var length = array.length;
|
||||
var minMax = array.getMinMax(1);
|
||||
var accessor = {
|
||||
bufferView : indexBufferViewId,
|
||||
byteOffset : indexBufferByteOffset,
|
||||
byteStride : 0,
|
||||
componentType : componentType,
|
||||
count : length,
|
||||
min : minMax.min,
|
||||
max : minMax.max,
|
||||
type : 'SCALAR'
|
||||
};
|
||||
|
||||
indexBufferByteOffset += buffer.length;
|
||||
indexBuffers.push(buffer);
|
||||
|
||||
var accessorId = 'accessor_' + accessorCount++;
|
||||
gltf.accessors[accessorId] = accessor;
|
||||
return accessorId;
|
||||
}
|
||||
|
||||
function requiresUint32Indices(nodes) {
|
||||
var nodesLength = nodes.length;
|
||||
for (var i = 0; i < nodesLength; ++i) {
|
||||
var meshes = nodes[i].meshes;
|
||||
var meshesLength = meshes.length;
|
||||
for (var j = 0; j < meshesLength; ++j) {
|
||||
// Reserve the 65535 index for primitive restart
|
||||
var vertexCount = meshes[j].positions.length / 3;
|
||||
if (vertexCount > 65534) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var uint32Indices = requiresUint32Indices(nodes);
|
||||
var gltfSceneNodes = gltf.scenes[sceneId].nodes;
|
||||
var nodesLength = nodes.length;
|
||||
for (var i = 0; i < nodesLength; ++i) {
|
||||
// Add node
|
||||
var node = nodes[i];
|
||||
var nodeId = node.name;
|
||||
gltfSceneNodes.push(nodeId);
|
||||
var gltfNodeMeshes = [];
|
||||
gltf.nodes[nodeId] = {
|
||||
name : nodeId,
|
||||
meshes : gltfNodeMeshes
|
||||
};
|
||||
|
||||
// Add meshes to node
|
||||
var meshes = node.meshes;
|
||||
var meshesLength = meshes.length;
|
||||
for (var j = 0; j < meshesLength; ++j) {
|
||||
var mesh = meshes[j];
|
||||
var meshId = mesh.name;
|
||||
gltfNodeMeshes.push(meshId);
|
||||
|
||||
var hasPositions = mesh.positions.length > 0;
|
||||
var hasNormals = mesh.normals.length > 0;
|
||||
var hasUVs = mesh.uvs.length > 0;
|
||||
|
||||
var attributes = {};
|
||||
if (hasPositions) {
|
||||
attributes.POSITION = addVertexAttribute(mesh.positions, 3);
|
||||
}
|
||||
if (hasNormals) {
|
||||
attributes.NORMAL = addVertexAttribute(mesh.normals, 3);
|
||||
}
|
||||
if (hasUVs) {
|
||||
attributes.TEXCOORD_0 = addVertexAttribute(mesh.uvs, 2);
|
||||
}
|
||||
|
||||
// Unload resources
|
||||
mesh.positions = undefined;
|
||||
mesh.normals = undefined;
|
||||
mesh.uvs = undefined;
|
||||
|
||||
var gltfMeshPrimitives = [];
|
||||
gltf.meshes[meshId] = {
|
||||
name : meshId,
|
||||
primitives : gltfMeshPrimitives
|
||||
};
|
||||
|
||||
// Add primitives to mesh
|
||||
var primitives = mesh.primitives;
|
||||
var primitivesLength = primitives.length;
|
||||
for (var k = 0; k < primitivesLength; ++k) {
|
||||
var primitive = primitives[k];
|
||||
var indexAccessorId = addIndexArray(primitive.indices, uint32Indices);
|
||||
primitive.indices = undefined; // Unload resources
|
||||
var materialId = primitive.material;
|
||||
|
||||
if (!defined(materialId)) {
|
||||
// Create a default material if the primitive does not specify one
|
||||
materialId = 'default';
|
||||
}
|
||||
|
||||
var material = materials[materialId];
|
||||
material = defined(material) ? material : new Material();
|
||||
var gltfMaterial = gltf.materials[materialId];
|
||||
if (defined(gltfMaterial)) {
|
||||
// Check if this material has already been added but with incompatible shading
|
||||
var normalShading = (gltfMaterial.extensions.KHR_materials_common.technique !== 'CONSTANT');
|
||||
if (hasNormals !== normalShading) {
|
||||
materialId += (hasNormals ? '_shaded' : '_constant');
|
||||
gltfMaterial = gltf.materials[materialId];
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined(gltfMaterial)) {
|
||||
gltf.materials[materialId] = createMaterial(material, hasNormals, options);
|
||||
}
|
||||
|
||||
gltfMeshPrimitives.push({
|
||||
attributes : attributes,
|
||||
indices : indexAccessorId,
|
||||
material : materialId,
|
||||
mode : WebGLConstants.TRIANGLES
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var buffers = [];
|
||||
buffers = buffers.concat(vertexBuffers, indexBuffers);
|
||||
var buffer = Buffer.concat(buffers);
|
||||
|
||||
gltf.buffers[bufferId] = {
|
||||
byteLength : buffer.byteLength,
|
||||
extras : {
|
||||
_obj2gltf : {
|
||||
source : buffer
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gltf.bufferViews[vertexBufferViewId] = {
|
||||
buffer : bufferId,
|
||||
byteLength : vertexBufferByteOffset,
|
||||
byteOffset : 0,
|
||||
target : WebGLConstants.ARRAY_BUFFER
|
||||
};
|
||||
|
||||
gltf.bufferViews[indexBufferViewId] = {
|
||||
buffer : bufferId,
|
||||
byteLength : indexBufferByteOffset,
|
||||
byteOffset : vertexBufferByteOffset,
|
||||
target : WebGLConstants.ELEMENT_ARRAY_BUFFER
|
||||
};
|
||||
|
||||
return gltf;
|
||||
}
|
338
lib/gltf.js
@ -1,338 +0,0 @@
|
||||
"use strict";
|
||||
var Cesium = require('cesium');
|
||||
var Promise = require('bluebird');
|
||||
var fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
|
||||
var defined = Cesium.defined;
|
||||
var defaultValue = Cesium.defaultValue;
|
||||
var WebGLConstants = Cesium.WebGLConstants;
|
||||
|
||||
var fsWriteFile = Promise.promisify(fs.writeFile);
|
||||
|
||||
module.exports = createGltf;
|
||||
|
||||
function createGltf(data, inputPath, modelName) {
|
||||
var vertexCount = data.vertexCount;
|
||||
var vertexArray = data.vertexArray;
|
||||
var positionMin = data.positionMin;
|
||||
var positionMax = data.positionMax;
|
||||
var hasUVs = data.hasUVs;
|
||||
var hasNormals = data.hasNormals;
|
||||
var materialGroups = data.materialGroups;
|
||||
var materials = data.materials;
|
||||
var images = data.images;
|
||||
|
||||
var i, j, name;
|
||||
|
||||
var sizeOfFloat32 = 4;
|
||||
var sizeOfUint32 = 4;
|
||||
var sizeOfUint16 = 2;
|
||||
|
||||
var indexComponentType;
|
||||
var indexComponentSize;
|
||||
|
||||
// Reserve the 65535 index for primitive restart
|
||||
if (vertexCount < 65535) {
|
||||
indexComponentType = WebGLConstants.UNSIGNED_SHORT;
|
||||
indexComponentSize = sizeOfUint16;
|
||||
} else {
|
||||
indexComponentType = WebGLConstants.UNSIGNED_INT;
|
||||
indexComponentSize = sizeOfUint32;
|
||||
}
|
||||
|
||||
// Create primitives
|
||||
var primitives = [];
|
||||
var indexArrayLength = 0;
|
||||
var indexArray;
|
||||
var indexCount;
|
||||
for (name in materialGroups) {
|
||||
if (materialGroups.hasOwnProperty(name)) {
|
||||
indexArray = materialGroups[name];
|
||||
indexCount = indexArray.length;
|
||||
primitives.push({
|
||||
indexArray : indexArray,
|
||||
indexOffset : indexArrayLength,
|
||||
indexCount : indexCount,
|
||||
material : name
|
||||
});
|
||||
indexArrayLength += indexCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Create buffer to store vertex and index data
|
||||
var indexArrayByteLength = indexArrayLength * indexComponentSize;
|
||||
var vertexArrayLength = vertexArray.length; // In floats
|
||||
var vertexArrayByteLength = vertexArrayLength * sizeOfFloat32;
|
||||
var bufferByteLength = vertexArrayByteLength + indexArrayByteLength;
|
||||
var buffer = new Buffer(bufferByteLength);
|
||||
|
||||
// Write vertex data
|
||||
var byteOffset = 0;
|
||||
for (i = 0; i < vertexArrayLength; ++i) {
|
||||
buffer.writeFloatLE(vertexArray[i], byteOffset);
|
||||
byteOffset += sizeOfFloat32;
|
||||
}
|
||||
|
||||
// Write index data
|
||||
var primitivesLength = primitives.length;
|
||||
for (i = 0; i < primitivesLength; ++i) {
|
||||
indexArray = primitives[i].indexArray;
|
||||
indexCount = indexArray.length;
|
||||
for (j = 0; j < indexCount; ++j) {
|
||||
if (indexComponentSize === sizeOfUint16) {
|
||||
buffer.writeUInt16LE(indexArray[j], byteOffset);
|
||||
} else {
|
||||
buffer.writeUInt32LE(indexArray[j], byteOffset);
|
||||
}
|
||||
byteOffset += indexComponentSize;
|
||||
}
|
||||
}
|
||||
|
||||
var positionByteOffset = 0;
|
||||
var normalByteOffset = 0;
|
||||
var uvByteOffset = 0;
|
||||
var vertexByteStride = 0;
|
||||
|
||||
if (hasNormals && hasUVs) {
|
||||
normalByteOffset = sizeOfFloat32 * 3;
|
||||
uvByteOffset = sizeOfFloat32 * 6;
|
||||
vertexByteStride = sizeOfFloat32 * 8;
|
||||
} else if (hasNormals && !hasUVs) {
|
||||
normalByteOffset = sizeOfFloat32 * 3;
|
||||
vertexByteStride = sizeOfFloat32 * 6;
|
||||
} else if (!hasNormals && hasUVs) {
|
||||
uvByteOffset = sizeOfFloat32 * 3;
|
||||
vertexByteStride = sizeOfFloat32 * 5;
|
||||
} else if (!hasNormals && !hasUVs) {
|
||||
vertexByteStride = sizeOfFloat32 * 3;
|
||||
}
|
||||
|
||||
var bufferId = modelName + '_buffer';
|
||||
var bufferViewVertexId = 'bufferView_vertex';
|
||||
var bufferViewIndexId = 'bufferView_index';
|
||||
var accessorPositionId = 'accessor_position';
|
||||
var accessorUVId = 'accessor_uv';
|
||||
var accessorNormalId = 'accessor_normal';
|
||||
var meshId = 'mesh_' + modelName;
|
||||
var sceneId = 'scene_' + modelName;
|
||||
var nodeId = 'node_' + modelName;
|
||||
var samplerId = 'sampler_0';
|
||||
|
||||
function getAccessorIndexId(i) {
|
||||
return 'accessor_index_' + i;
|
||||
}
|
||||
|
||||
function getMaterialId(material) {
|
||||
return 'material_' + material;
|
||||
}
|
||||
|
||||
function getTextureId(image) {
|
||||
if (!defined(image)) {
|
||||
return undefined;
|
||||
}
|
||||
return 'texture_' + path.basename(image).substr(0, image.lastIndexOf('.'));
|
||||
}
|
||||
|
||||
function getImageId(image) {
|
||||
return path.basename(image, path.extname(image));
|
||||
}
|
||||
|
||||
var gltf = {
|
||||
accessors : {},
|
||||
asset : {},
|
||||
buffers : {},
|
||||
bufferViews : {},
|
||||
images : {},
|
||||
materials : {},
|
||||
meshes : {},
|
||||
nodes : {},
|
||||
samplers : {},
|
||||
scene : sceneId,
|
||||
scenes : {},
|
||||
textures : {}
|
||||
};
|
||||
|
||||
gltf.asset = {
|
||||
"generator": "OBJ2GLTF",
|
||||
"premultipliedAlpha": true,
|
||||
"profile": {
|
||||
"api": "WebGL",
|
||||
"version": "1.0"
|
||||
},
|
||||
"version": 1
|
||||
};
|
||||
|
||||
gltf.scenes[sceneId] = {
|
||||
nodes : [nodeId]
|
||||
};
|
||||
|
||||
gltf.nodes[nodeId] = {
|
||||
children : [],
|
||||
matrix : [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
||||
meshes : [meshId],
|
||||
name : modelName
|
||||
};
|
||||
|
||||
gltf.samplers[samplerId] = {}; // Use default values
|
||||
|
||||
var bufferSeparate = false;
|
||||
var bufferUri;
|
||||
if (buffer.length > 201326580) {
|
||||
// toString fails for buffers larger than ~192MB. Instead save the buffer to a .bin file.
|
||||
// Source: https://github.com/nodejs/node/issues/4266
|
||||
bufferSeparate = true;
|
||||
bufferUri = modelName + '.bin';
|
||||
} else {
|
||||
bufferUri = 'data:application/octet-stream;base64,' + buffer.toString('base64');
|
||||
}
|
||||
|
||||
gltf.buffers[bufferId] = {
|
||||
byteLength : bufferByteLength,
|
||||
type : 'arraybuffer',
|
||||
uri : bufferUri
|
||||
};
|
||||
|
||||
gltf.bufferViews[bufferViewVertexId] = {
|
||||
buffer : bufferId,
|
||||
byteLength : vertexArrayByteLength,
|
||||
byteOffset : 0,
|
||||
target : WebGLConstants.ARRAY_BUFFER
|
||||
};
|
||||
gltf.bufferViews[bufferViewIndexId] = {
|
||||
buffer : bufferId,
|
||||
byteLength : indexArrayByteLength,
|
||||
byteOffset : vertexArrayByteLength,
|
||||
target : WebGLConstants.ELEMENT_ARRAY_BUFFER
|
||||
};
|
||||
|
||||
for (i = 0; i < primitivesLength; ++i) {
|
||||
var primitive = primitives[i];
|
||||
gltf.accessors[getAccessorIndexId(i)] = {
|
||||
bufferView : bufferViewIndexId,
|
||||
byteOffset : primitive.indexOffset * indexComponentSize,
|
||||
byteStride : 0,
|
||||
componentType : indexComponentType,
|
||||
count : primitive.indexCount,
|
||||
type : 'SCALAR'
|
||||
};
|
||||
}
|
||||
|
||||
gltf.accessors[accessorPositionId] = {
|
||||
bufferView : bufferViewVertexId,
|
||||
byteOffset : positionByteOffset,
|
||||
byteStride : vertexByteStride,
|
||||
componentType : WebGLConstants.FLOAT,
|
||||
count : vertexCount,
|
||||
min : positionMin,
|
||||
max : positionMax,
|
||||
type : 'VEC3'
|
||||
};
|
||||
|
||||
if (hasNormals) {
|
||||
gltf.accessors[accessorNormalId] = {
|
||||
bufferView : bufferViewVertexId,
|
||||
byteOffset : normalByteOffset,
|
||||
byteStride : vertexByteStride,
|
||||
componentType : WebGLConstants.FLOAT,
|
||||
count : vertexCount,
|
||||
type : 'VEC3'
|
||||
};
|
||||
}
|
||||
|
||||
if (hasUVs) {
|
||||
gltf.accessors[accessorUVId] = {
|
||||
bufferView : bufferViewVertexId,
|
||||
byteOffset : uvByteOffset,
|
||||
byteStride : vertexByteStride,
|
||||
componentType : WebGLConstants.FLOAT,
|
||||
count : vertexCount,
|
||||
type : 'VEC2'
|
||||
};
|
||||
}
|
||||
|
||||
var gltfPrimitives = [];
|
||||
gltf.meshes[meshId] = {
|
||||
name : modelName,
|
||||
primitives : gltfPrimitives
|
||||
};
|
||||
|
||||
var gltfAttributes = {};
|
||||
gltfAttributes.POSITION = accessorPositionId;
|
||||
if (hasNormals) {
|
||||
gltfAttributes.NORMAL = accessorNormalId;
|
||||
}
|
||||
if (hasUVs) {
|
||||
gltfAttributes.TEXCOORD_0 = accessorUVId;
|
||||
}
|
||||
|
||||
for (i = 0; i < primitivesLength; ++i) {
|
||||
gltfPrimitives.push({
|
||||
attributes : gltfAttributes,
|
||||
indices : getAccessorIndexId(i),
|
||||
material : getMaterialId(primitives[i].material),
|
||||
mode : WebGLConstants.TRIANGLES
|
||||
});
|
||||
}
|
||||
|
||||
for (name in materials) {
|
||||
if (materials.hasOwnProperty(name)) {
|
||||
var material = materials[name];
|
||||
var materialId = getMaterialId(name);
|
||||
var values = {
|
||||
ambient : defaultValue(defaultValue(getTextureId(material.ambientColorMap), material.ambientColor), [0, 0, 0, 1]),
|
||||
diffuse : defaultValue(defaultValue(getTextureId(material.diffuseColorMap), material.diffuseColor), [0, 0, 0, 1]),
|
||||
emission : defaultValue(defaultValue(getTextureId(material.emissionColorMap), material.emissionColor), [0, 0, 0, 1]),
|
||||
specular : defaultValue(defaultValue(getTextureId(material.specularColorMap), material.specularColor), [0, 0, 0, 1]),
|
||||
shininess : defaultValue(material.specularShininess, 0.0)
|
||||
};
|
||||
|
||||
gltf.materials[materialId] = {
|
||||
name: name,
|
||||
values: values
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for (name in images) {
|
||||
if (images.hasOwnProperty(name)) {
|
||||
var image = images[name];
|
||||
var imageId = getImageId(name);
|
||||
var textureId = getTextureId(name);
|
||||
var format;
|
||||
var channels = image.channels;
|
||||
switch (channels) {
|
||||
case 1:
|
||||
format = WebGLConstants.ALPHA;
|
||||
break;
|
||||
case 2:
|
||||
format = WebGLConstants.LUMINANCE_ALPHA;
|
||||
break;
|
||||
case 3:
|
||||
format = WebGLConstants.RGB;
|
||||
break;
|
||||
case 4:
|
||||
format = WebGLConstants.RGBA;
|
||||
break;
|
||||
}
|
||||
|
||||
gltf.images[imageId] = {
|
||||
uri : image.uri
|
||||
};
|
||||
gltf.textures[textureId] = {
|
||||
format : format,
|
||||
internalFormat : format,
|
||||
sampler : samplerId,
|
||||
source : imageId,
|
||||
target : WebGLConstants.TEXTURE_2D,
|
||||
type : WebGLConstants.UNSIGNED_BYTE
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (bufferSeparate) {
|
||||
var bufferPath = path.join(inputPath, modelName + '.bin');
|
||||
return fsWriteFile(bufferPath, buffer);
|
||||
}
|
||||
return gltf;
|
||||
}
|
63
lib/image.js
@ -1,63 +0,0 @@
|
||||
"use strict";
|
||||
var Promise = require('bluebird');
|
||||
var fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
|
||||
var fsReadFile = Promise.promisify(fs.readFile);
|
||||
|
||||
module.exports = loadImage;
|
||||
|
||||
function getChannels(colorType) {
|
||||
switch (colorType) {
|
||||
case 0: // greyscale
|
||||
return 1;
|
||||
case 2: // RGB
|
||||
return 3;
|
||||
case 4: // greyscale + alpha
|
||||
return 2;
|
||||
case 6: // RGB + alpha
|
||||
return 4;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
function getUriType(extension) {
|
||||
switch (extension) {
|
||||
case 'png':
|
||||
return 'data:image/png';
|
||||
case 'jpg':
|
||||
return 'data:image/jpeg';
|
||||
case 'jpeg':
|
||||
return 'data:image/jpeg';
|
||||
case 'gif':
|
||||
return 'data:image/gif';
|
||||
default:
|
||||
return 'data:image/' + extension;
|
||||
}
|
||||
}
|
||||
|
||||
function loadImage(imagePath) {
|
||||
return fsReadFile(imagePath)
|
||||
.then(function(data) {
|
||||
var extension = path.extname(imagePath).slice(1);
|
||||
var uriType = getUriType(extension);
|
||||
var uri = uriType + ';base64,' + data.toString('base64');
|
||||
|
||||
var info = {
|
||||
transparent: false,
|
||||
channels: 3,
|
||||
data: data,
|
||||
uri: uri
|
||||
};
|
||||
|
||||
if (path.extname(imagePath) === 'png') {
|
||||
// Color type is encoded in the 25th bit of the png
|
||||
var colorType = data[25];
|
||||
var channels = getChannels(colorType);
|
||||
info.channels = channels;
|
||||
info.transparent = (channels === 4);
|
||||
}
|
||||
return info;
|
||||
});
|
||||
}
|
107
lib/loadImage.js
Normal file
@ -0,0 +1,107 @@
|
||||
'use strict';
|
||||
var Cesium = require('cesium');
|
||||
var fsExtra = require('fs-extra');
|
||||
var path = require('path');
|
||||
var PNG = require('pngjs').PNG;
|
||||
var Promise = require('bluebird');
|
||||
|
||||
var defined = Cesium.defined;
|
||||
var WebGLConstants = Cesium.WebGLConstants;
|
||||
|
||||
module.exports = loadImage;
|
||||
|
||||
/**
|
||||
* Load an image file and get information about it.
|
||||
*
|
||||
* @param {String} imagePath Path to the image file.
|
||||
* @param {Object} options An object with the following properties:
|
||||
* @param {Boolean} options.checkTransparency Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
|
||||
* @returns {Promise} A promise resolving to the image information, or undefined if the file doesn't exist.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function loadImage(imagePath, options) {
|
||||
return fsExtra.readFile(imagePath)
|
||||
.then(function(data) {
|
||||
var extension = path.extname(imagePath).toLowerCase();
|
||||
|
||||
var info = {
|
||||
transparent : false,
|
||||
format : getFormat(3),
|
||||
source : data,
|
||||
extension : extension
|
||||
};
|
||||
|
||||
if (extension === '.png') {
|
||||
return getPngInfo(data, info, options);
|
||||
}
|
||||
|
||||
return info;
|
||||
});
|
||||
}
|
||||
|
||||
function getPngInfo(data, info, options) {
|
||||
// Color type is encoded in the 25th bit of the png
|
||||
var colorType = data[25];
|
||||
var channels = getChannels(colorType);
|
||||
info.format = getFormat(channels);
|
||||
|
||||
if (channels === 4) {
|
||||
if (options.checkTransparency) {
|
||||
return isTransparent(data)
|
||||
.then(function(transparent) {
|
||||
info.transparent = transparent;
|
||||
return info;
|
||||
});
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
function isTransparent(data) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
new PNG().parse(data, function(error, data) {
|
||||
if (defined(error)) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
var pixels = data.data;
|
||||
var pixelsLength = data.width * data.height;
|
||||
for (var i = 0; i < pixelsLength; ++i) {
|
||||
if (pixels[i * 4 + 3] < 255) {
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getChannels(colorType) {
|
||||
switch (colorType) {
|
||||
case 0: // greyscale
|
||||
return 1;
|
||||
case 2: // RGB
|
||||
return 3;
|
||||
case 4: // greyscale + alpha
|
||||
return 2;
|
||||
case 6: // RGB + alpha
|
||||
return 4;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
function getFormat(channels) {
|
||||
switch (channels) {
|
||||
case 1:
|
||||
return WebGLConstants.ALPHA;
|
||||
case 2:
|
||||
return WebGLConstants.LUMINANCE_ALPHA;
|
||||
case 3:
|
||||
return WebGLConstants.RGB;
|
||||
case 4:
|
||||
return WebGLConstants.RGBA;
|
||||
}
|
||||
}
|
91
lib/loadMtl.js
Normal file
@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
var path = require('path');
|
||||
var Material = require('./Material');
|
||||
var readLines = require('./readLines');
|
||||
|
||||
module.exports = loadMtl;
|
||||
|
||||
/**
|
||||
* Parse an mtl file.
|
||||
*
|
||||
* @param {String} mtlPath Path to the mtl file.
|
||||
* @returns {Promise} A promise resolving to the materials.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function loadMtl(mtlPath) {
|
||||
var material;
|
||||
var values;
|
||||
var value;
|
||||
var mtlDirectory = path.dirname(mtlPath);
|
||||
var materials = {};
|
||||
|
||||
function parseLine(line) {
|
||||
line = line.trim();
|
||||
if (/^newmtl /i.test(line)) {
|
||||
var name = line.substring(7).trim();
|
||||
material = new Material();
|
||||
materials[name] = material;
|
||||
} else if (/^Ka /i.test(line)) {
|
||||
values = line.substring(3).trim().split(' ');
|
||||
material.ambientColor = [
|
||||
parseFloat(values[0]),
|
||||
parseFloat(values[1]),
|
||||
parseFloat(values[2]),
|
||||
1.0
|
||||
];
|
||||
} else if (/^Ke /i.test(line)) {
|
||||
values = line.substring(3).trim().split(' ');
|
||||
material.emissionColor = [
|
||||
parseFloat(values[0]),
|
||||
parseFloat(values[1]),
|
||||
parseFloat(values[2]),
|
||||
1.0
|
||||
];
|
||||
} else if (/^Kd /i.test(line)) {
|
||||
values = line.substring(3).trim().split(' ');
|
||||
material.diffuseColor = [
|
||||
parseFloat(values[0]),
|
||||
parseFloat(values[1]),
|
||||
parseFloat(values[2]),
|
||||
1.0
|
||||
];
|
||||
} else if (/^Ks /i.test(line)) {
|
||||
values = line.substring(3).trim().split(' ');
|
||||
material.specularColor = [
|
||||
parseFloat(values[0]),
|
||||
parseFloat(values[1]),
|
||||
parseFloat(values[2]),
|
||||
1.0
|
||||
];
|
||||
} else if (/^Ns /i.test(line)) {
|
||||
value = line.substring(3).trim();
|
||||
material.specularShininess = parseFloat(value);
|
||||
} else if (/^d /i.test(line)) {
|
||||
value = line.substring(2).trim();
|
||||
material.alpha = parseFloat(value);
|
||||
} else if (/^Tr /i.test(line)) {
|
||||
value = line.substring(3).trim();
|
||||
material.alpha = 1.0 - parseFloat(value);
|
||||
} else if (/^map_Ka /i.test(line)) {
|
||||
material.ambientTexture = path.resolve(mtlDirectory, line.substring(7).trim());
|
||||
} else if (/^map_Ke /i.test(line)) {
|
||||
material.emissionTexture = path.resolve(mtlDirectory, line.substring(7).trim());
|
||||
} else if (/^map_Kd /i.test(line)) {
|
||||
material.diffuseTexture = path.resolve(mtlDirectory, line.substring(7).trim());
|
||||
} else if (/^map_Ks /i.test(line)) {
|
||||
material.specularTexture = path.resolve(mtlDirectory, line.substring(7).trim());
|
||||
} else if (/^map_Ns /i.test(line)) {
|
||||
material.specularShininessMap = path.resolve(mtlDirectory, line.substring(7).trim());
|
||||
} else if (/^map_Bump /i.test(line)) {
|
||||
material.normalMap = path.resolve(mtlDirectory, line.substring(9).trim());
|
||||
} else if (/^map_d /i.test(line)) {
|
||||
material.alphaMap = path.resolve(mtlDirectory, line.substring(6).trim());
|
||||
}
|
||||
}
|
||||
|
||||
return readLines(mtlPath, parseLine)
|
||||
.then(function() {
|
||||
return materials;
|
||||
});
|
||||
}
|
487
lib/loadObj.js
Normal file
@ -0,0 +1,487 @@
|
||||
'use strict';
|
||||
var Cesium = require('cesium');
|
||||
var path = require('path');
|
||||
var Promise = require('bluebird');
|
||||
|
||||
var ArrayStorage = require('./ArrayStorage');
|
||||
var loadImage = require('./loadImage');
|
||||
var loadMtl = require('./loadMtl');
|
||||
var readLines = require('./readLines');
|
||||
|
||||
var Axis = Cesium.Axis;
|
||||
var Cartesian3 = Cesium.Cartesian3;
|
||||
var ComponentDatatype = Cesium.ComponentDatatype;
|
||||
var defaultValue = Cesium.defaultValue;
|
||||
var defined = Cesium.defined;
|
||||
var Matrix4 = Cesium.Matrix4;
|
||||
var RuntimeError = Cesium.RuntimeError;
|
||||
|
||||
module.exports = loadObj;
|
||||
|
||||
// Object name (o) -> node
|
||||
// Group name (g) -> mesh
|
||||
// Material name (usemtl) -> primitive
|
||||
|
||||
function Node() {
|
||||
this.name = undefined;
|
||||
this.meshes = [];
|
||||
}
|
||||
|
||||
function Mesh() {
|
||||
this.name = undefined;
|
||||
this.primitives = [];
|
||||
this.positions = new ArrayStorage(ComponentDatatype.FLOAT);
|
||||
this.normals = new ArrayStorage(ComponentDatatype.FLOAT);
|
||||
this.uvs = new ArrayStorage(ComponentDatatype.FLOAT);
|
||||
}
|
||||
|
||||
function Primitive() {
|
||||
this.material = undefined;
|
||||
this.indices = new ArrayStorage(ComponentDatatype.UNSIGNED_INT);
|
||||
}
|
||||
|
||||
// OBJ regex patterns are modified from ThreeJS (https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js)
|
||||
var vertexPattern = /v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; // v float float float
|
||||
var normalPattern = /vn( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; // vn float float float
|
||||
var uvPattern = /vt( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; // vt float float
|
||||
var facePattern1 = /f( +-?\d+)\/?( +-?\d+)\/?( +-?\d+)\/?( +-?\d+)?\/?/; // f vertex vertex vertex ...
|
||||
var facePattern2 = /f( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)?/; // f vertex/uv vertex/uv vertex/uv ...
|
||||
var facePattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/; // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
|
||||
var facePattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/; // f vertex//normal vertex//normal vertex//normal ...
|
||||
|
||||
var scratchCartesian = new Cartesian3();
|
||||
|
||||
/**
|
||||
* Parse an obj file.
|
||||
*
|
||||
* @param {String} objPath Path to the obj file.
|
||||
* @param {Object} options An object with the following properties:
|
||||
* @param {Boolean} options.checkTransparency Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
|
||||
* @param {Boolean} options.secure Prevent the converter from reading image or mtl files outside of the input obj directory.
|
||||
* @param {String} options.inputUpAxis Up axis of the obj.
|
||||
* @param {String} options.outputUpAxis Up axis of the converted glTF.
|
||||
* @param {Boolean} options.logger A callback function for handling logged messages. Defaults to console.log.
|
||||
* @returns {Promise} A promise resolving to the obj data.
|
||||
* @exception {RuntimeError} The file does not have any geometry information in it.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function loadObj(objPath, options) {
|
||||
var axisTransform = getAxisTransform(options.inputUpAxis, options.outputUpAxis);
|
||||
|
||||
// Global store of vertex attributes listed in the obj file
|
||||
var positions = new ArrayStorage(ComponentDatatype.FLOAT);
|
||||
var normals = new ArrayStorage(ComponentDatatype.FLOAT);
|
||||
var uvs = new ArrayStorage(ComponentDatatype.FLOAT);
|
||||
|
||||
// The current node, mesh, and primitive
|
||||
var node;
|
||||
var mesh;
|
||||
var primitive;
|
||||
|
||||
// All nodes seen in the obj
|
||||
var nodes = [];
|
||||
|
||||
// Used to build the indices. The vertex cache is unique to each mesh.
|
||||
var vertexCache = {};
|
||||
var vertexCacheLimit = 1000000;
|
||||
var vertexCacheCount = 0;
|
||||
var vertexCount = 0;
|
||||
|
||||
// All mtl paths seen in the obj
|
||||
var mtlPaths = [];
|
||||
|
||||
function getName(name) {
|
||||
return (name === '' ? undefined : name);
|
||||
}
|
||||
|
||||
function addNode(name) {
|
||||
node = new Node();
|
||||
node.name = getName(name);
|
||||
nodes.push(node);
|
||||
addMesh();
|
||||
}
|
||||
|
||||
function addMesh(name) {
|
||||
mesh = new Mesh();
|
||||
mesh.name = getName(name);
|
||||
node.meshes.push(mesh);
|
||||
addPrimitive();
|
||||
|
||||
// Clear the vertex cache for each new mesh
|
||||
vertexCache = {};
|
||||
vertexCacheCount = 0;
|
||||
vertexCount = 0;
|
||||
}
|
||||
|
||||
function addPrimitive() {
|
||||
primitive = new Primitive();
|
||||
mesh.primitives.push(primitive);
|
||||
}
|
||||
|
||||
function useMaterial(name) {
|
||||
// Look to see if this material has already been used by a primitive in the mesh
|
||||
var material = getName(name);
|
||||
var primitives = mesh.primitives;
|
||||
var primitivesLength = primitives.length;
|
||||
for (var i = 0; i < primitivesLength; ++i) {
|
||||
if (primitives[i].material === material) {
|
||||
primitive = primitives[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Add a new primitive with this material
|
||||
addPrimitive();
|
||||
primitive.material = getName(name);
|
||||
}
|
||||
|
||||
function getOffset(a, attributeData, components) {
|
||||
var i = parseInt(a);
|
||||
if (i < 0) {
|
||||
// Negative vertex indexes reference the vertices immediately above it
|
||||
return (attributeData.length / components + i) * components;
|
||||
}
|
||||
return (i - 1) * components;
|
||||
}
|
||||
|
||||
function createVertex(p, u, n) {
|
||||
// Positions
|
||||
if (defined(p)) {
|
||||
var pi = getOffset(p, positions, 3);
|
||||
var px = positions.get(pi + 0);
|
||||
var py = positions.get(pi + 1);
|
||||
var pz = positions.get(pi + 2);
|
||||
mesh.positions.push(px);
|
||||
mesh.positions.push(py);
|
||||
mesh.positions.push(pz);
|
||||
}
|
||||
|
||||
// Normals
|
||||
if (defined(n)) {
|
||||
var ni = getOffset(n, normals, 3);
|
||||
var nx = normals.get(ni + 0);
|
||||
var ny = normals.get(ni + 1);
|
||||
var nz = normals.get(ni + 2);
|
||||
mesh.normals.push(nx);
|
||||
mesh.normals.push(ny);
|
||||
mesh.normals.push(nz);
|
||||
}
|
||||
|
||||
// UVs
|
||||
if (defined(u)) {
|
||||
var ui = getOffset(u, uvs, 2);
|
||||
var ux = uvs.get(ui + 0);
|
||||
var uy = uvs.get(ui + 1);
|
||||
mesh.uvs.push(ux);
|
||||
mesh.uvs.push(uy);
|
||||
}
|
||||
}
|
||||
|
||||
function addVertex(v, p, u, n) {
|
||||
var index = vertexCache[v];
|
||||
if (!defined(index)) {
|
||||
index = vertexCount++;
|
||||
vertexCache[v] = index;
|
||||
createVertex(p, u, n);
|
||||
|
||||
// Prevent the vertex cache from growing too large. As a result of clearing the cache there
|
||||
// may be some duplicate vertices.
|
||||
vertexCacheCount++;
|
||||
if (vertexCacheCount > vertexCacheLimit) {
|
||||
vertexCacheCount = 0;
|
||||
vertexCache = {};
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
function addFace(v1, p1, u1, n1, v2, p2, u2, n2, v3, p3, u3, n3, v4, p4, u4, n4) {
|
||||
var index1 = addVertex(v1, p1, u1, n1);
|
||||
var index2 = addVertex(v2, p2, u2, n2);
|
||||
var index3 = addVertex(v3, p3, u3, n3);
|
||||
|
||||
primitive.indices.push(index1);
|
||||
primitive.indices.push(index2);
|
||||
primitive.indices.push(index3);
|
||||
|
||||
// Triangulate if the face is a quad
|
||||
if (defined(v4)) {
|
||||
var index4 = addVertex(v4, p4, u4, n4);
|
||||
primitive.indices.push(index1);
|
||||
primitive.indices.push(index3);
|
||||
primitive.indices.push(index4);
|
||||
}
|
||||
}
|
||||
|
||||
function parseLine(line) {
|
||||
line = line.trim();
|
||||
var result;
|
||||
|
||||
if ((line.length === 0) || (line.charAt(0) === '#')) {
|
||||
// Don't process empty lines or comments
|
||||
} else if (/^o\s/i.test(line)) {
|
||||
var objectName = line.substring(2).trim();
|
||||
addNode(objectName);
|
||||
} else if (/^g\s/i.test(line)) {
|
||||
var groupName = line.substring(2).trim();
|
||||
addMesh(groupName);
|
||||
} else if (/^usemtl\s/i.test(line)) {
|
||||
var materialName = line.substring(7).trim();
|
||||
useMaterial(materialName);
|
||||
} else if (/^mtllib/i.test(line)) {
|
||||
var paths = line.substring(7).trim().split(' ');
|
||||
mtlPaths = mtlPaths.concat(paths);
|
||||
} else if ((result = vertexPattern.exec(line)) !== null) {
|
||||
var position = scratchCartesian;
|
||||
position.x = parseFloat(result[1]);
|
||||
position.y = parseFloat(result[2]);
|
||||
position.z = parseFloat(result[3]);
|
||||
if (defined(axisTransform)) {
|
||||
Matrix4.multiplyByPoint(axisTransform, position, position);
|
||||
}
|
||||
positions.push(position.x);
|
||||
positions.push(position.y);
|
||||
positions.push(position.z);
|
||||
} else if ((result = normalPattern.exec(line) ) !== null) {
|
||||
var normal = scratchCartesian;
|
||||
normal.x = parseFloat(result[1]);
|
||||
normal.y = parseFloat(result[2]);
|
||||
normal.z = parseFloat(result[3]);
|
||||
if (defined(axisTransform)) {
|
||||
Matrix4.multiplyByPointAsVector(axisTransform, normal, normal);
|
||||
}
|
||||
normals.push(normal.x);
|
||||
normals.push(normal.y);
|
||||
normals.push(normal.z);
|
||||
} else if ((result = uvPattern.exec(line)) !== null) {
|
||||
uvs.push(parseFloat(result[1]));
|
||||
uvs.push(1.0 - parseFloat(result[2])); // Flip y so 0.0 is the bottom of the image
|
||||
} else if ((result = facePattern1.exec(line)) !== null) {
|
||||
addFace(
|
||||
result[1], result[1], undefined, undefined,
|
||||
result[2], result[2], undefined, undefined,
|
||||
result[3], result[3], undefined, undefined,
|
||||
result[4], result[4], undefined, undefined
|
||||
);
|
||||
} else if ((result = facePattern2.exec(line)) !== null) {
|
||||
addFace(
|
||||
result[1], result[2], result[3], undefined,
|
||||
result[4], result[5], result[6], undefined,
|
||||
result[7], result[8], result[9], undefined,
|
||||
result[10], result[11], result[12], undefined
|
||||
);
|
||||
} else if ((result = facePattern3.exec(line)) !== null) {
|
||||
addFace(
|
||||
result[1], result[2], result[3], result[4],
|
||||
result[5], result[6], result[7], result[8],
|
||||
result[9], result[10], result[11], result[12],
|
||||
result[13], result[14], result[15], result[16]
|
||||
);
|
||||
} else if ((result = facePattern4.exec(line)) !== null) {
|
||||
addFace(
|
||||
result[1], result[2], undefined, result[3],
|
||||
result[4], result[5], undefined, result[6],
|
||||
result[7], result[8], undefined, result[9],
|
||||
result[10], result[11], undefined, result[12]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a default node in case there are no o/g/usemtl lines in the obj
|
||||
addNode();
|
||||
|
||||
// Parse the obj file
|
||||
return readLines(objPath, parseLine)
|
||||
.then(function() {
|
||||
// Unload resources
|
||||
positions = undefined;
|
||||
normals = undefined;
|
||||
uvs = undefined;
|
||||
|
||||
// Load materials and images
|
||||
return finishLoading(nodes, mtlPaths, objPath, options);
|
||||
});
|
||||
}
|
||||
|
||||
function finishLoading(nodes, mtlPaths, objPath, options) {
|
||||
nodes = cleanNodes(nodes);
|
||||
if (nodes.length === 0) {
|
||||
return Promise.reject(new RuntimeError(objPath + ' does not have any geometry data'));
|
||||
}
|
||||
return loadMaterials(mtlPaths, objPath, options)
|
||||
.then(function(materials) {
|
||||
var imagePaths = getImagePaths(materials);
|
||||
return loadImages(imagePaths, objPath, options)
|
||||
.then(function(images) {
|
||||
return {
|
||||
nodes : nodes,
|
||||
materials : materials,
|
||||
images : images
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function outsideDirectory(filePath, objPath) {
|
||||
return (path.relative(path.dirname(objPath), filePath).indexOf('..') === 0);
|
||||
}
|
||||
|
||||
function loadMaterials(mtlPaths, objPath, options) {
|
||||
var secure = options.secure;
|
||||
var logger = options.logger;
|
||||
var objDirectory = path.dirname(objPath);
|
||||
var materials = {};
|
||||
return Promise.map(mtlPaths, function(mtlPath) {
|
||||
mtlPath = path.resolve(objDirectory, mtlPath);
|
||||
if (secure && outsideDirectory(mtlPath, objPath)) {
|
||||
logger('Could not read mtl file at ' + mtlPath + ' because it is outside of the obj directory and the secure flag is true. Using default material instead.');
|
||||
return;
|
||||
}
|
||||
return loadMtl(mtlPath)
|
||||
.then(function(materialsInMtl) {
|
||||
materials = Object.assign(materials, materialsInMtl);
|
||||
})
|
||||
.catch(function() {
|
||||
logger('Could not read mtl file at ' + mtlPath + '. Using default material instead.');
|
||||
});
|
||||
}, {concurrency : 10})
|
||||
.thenReturn(materials);
|
||||
}
|
||||
|
||||
function loadImages(imagePaths, objPath, options) {
|
||||
var secure = options.secure;
|
||||
var logger = options.logger;
|
||||
var images = {};
|
||||
return Promise.map(imagePaths, function(imagePath) {
|
||||
if (secure && outsideDirectory(imagePath, objPath)) {
|
||||
logger('Could not read image file at ' + imagePath + ' because it is outside of the obj directory and the secure flag is true. Material will ignore this image.');
|
||||
return;
|
||||
}
|
||||
return loadImage(imagePath, options)
|
||||
.then(function(image) {
|
||||
images[imagePath] = image;
|
||||
})
|
||||
.catch(function() {
|
||||
logger('Could not read image file at ' + imagePath + '. Material will ignore this image.');
|
||||
});
|
||||
}, {concurrency : 10})
|
||||
.thenReturn(images);
|
||||
}
|
||||
|
||||
function getImagePaths(materials) {
|
||||
var imagePaths = {};
|
||||
for (var name in materials) {
|
||||
if (materials.hasOwnProperty(name)) {
|
||||
var material = materials[name];
|
||||
if (defined(material.ambientTexture)) {
|
||||
imagePaths[material.ambientTexture] = true;
|
||||
}
|
||||
if (defined(material.diffuseTexture)) {
|
||||
imagePaths[material.diffuseTexture] = true;
|
||||
}
|
||||
if (defined(material.emissionTexture)) {
|
||||
imagePaths[material.emissionTexture] = true;
|
||||
}
|
||||
if (defined(material.specularTexture)) {
|
||||
imagePaths[material.specularTexture] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.keys(imagePaths);
|
||||
}
|
||||
|
||||
function removeEmptyMeshes(meshes) {
|
||||
return meshes.filter(function(mesh) {
|
||||
// Remove empty primitives
|
||||
mesh.primitives = mesh.primitives.filter(function(primitive) {
|
||||
return primitive.indices.length > 0;
|
||||
});
|
||||
// Valid meshes must have at least one primitive and contain positions
|
||||
return (mesh.primitives.length > 0) && (mesh.positions.length > 0);
|
||||
});
|
||||
}
|
||||
|
||||
function meshesHaveNames(meshes) {
|
||||
var meshesLength = meshes.length;
|
||||
for (var i = 0; i < meshesLength; ++i) {
|
||||
if (defined(meshes[i].name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function removeEmptyNodes(nodes) {
|
||||
var final = [];
|
||||
var nodesLength = nodes.length;
|
||||
for (var i = 0; i < nodesLength; ++i) {
|
||||
var node = nodes[i];
|
||||
var meshes = removeEmptyMeshes(node.meshes);
|
||||
if (meshes.length === 0) {
|
||||
continue;
|
||||
}
|
||||
node.meshes = meshes;
|
||||
if (!defined(node.name) && meshesHaveNames(meshes)) {
|
||||
// If the obj has groups (g) but not object groups (o) then convert meshes to nodes
|
||||
var meshesLength = meshes.length;
|
||||
for (var j = 0; j < meshesLength; ++j) {
|
||||
var mesh = meshes[j];
|
||||
var convertedNode = new Node();
|
||||
convertedNode.name = mesh.name;
|
||||
convertedNode.meshes = [mesh];
|
||||
final.push(convertedNode);
|
||||
}
|
||||
} else {
|
||||
final.push(node);
|
||||
}
|
||||
}
|
||||
return final;
|
||||
}
|
||||
|
||||
function setDefaultNames(items, defaultName, usedNames) {
|
||||
var itemsLength = items.length;
|
||||
for (var i = 0; i < itemsLength; ++i) {
|
||||
var item = items[i];
|
||||
var name = defaultValue(item.name, defaultName);
|
||||
var occurrences = usedNames[name];
|
||||
if (defined(occurrences)) {
|
||||
usedNames[name]++;
|
||||
name = name + '_' + occurrences;
|
||||
} else {
|
||||
usedNames[name] = 1;
|
||||
}
|
||||
item.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
function setDefaults(nodes) {
|
||||
var usedNames = {};
|
||||
setDefaultNames(nodes, 'Node', usedNames);
|
||||
var nodesLength = nodes.length;
|
||||
for (var i = 0; i < nodesLength; ++i) {
|
||||
var node = nodes[i];
|
||||
setDefaultNames(node.meshes, node.name + '-Mesh', usedNames);
|
||||
}
|
||||
}
|
||||
|
||||
function cleanNodes(nodes) {
|
||||
nodes = removeEmptyNodes(nodes);
|
||||
setDefaults(nodes);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
function getAxisTransform(inputUpAxis, outputUpAxis) {
|
||||
if (inputUpAxis === 'X' && outputUpAxis === 'Y') {
|
||||
return Axis.X_UP_TO_Y_UP;
|
||||
} else if (inputUpAxis === 'X' && outputUpAxis === 'Z') {
|
||||
return Axis.X_UP_TO_Z_UP;
|
||||
} else if (inputUpAxis === 'Y' && outputUpAxis === 'X') {
|
||||
return Axis.Y_UP_TO_X_UP;
|
||||
} else if (inputUpAxis === 'Y' && outputUpAxis === 'Z') {
|
||||
return Axis.Y_UP_TO_Z_UP;
|
||||
} else if (inputUpAxis === 'Z' && outputUpAxis === 'X') {
|
||||
return Axis.Z_UP_TO_X_UP;
|
||||
} else if (inputUpAxis === 'Z' && outputUpAxis === 'Y') {
|
||||
return Axis.Z_UP_TO_Y_UP;
|
||||
}
|
||||
}
|
118
lib/mtl.js
@ -1,118 +0,0 @@
|
||||
"use strict";
|
||||
var Promise = require('bluebird');
|
||||
var fs = require('fs-extra');
|
||||
var defined = require('cesium').defined;
|
||||
|
||||
var fsReadFile = Promise.promisify(fs.readFile);
|
||||
|
||||
module.exports = {
|
||||
getDefault : getDefault,
|
||||
parse : parse
|
||||
};
|
||||
|
||||
function createMaterial() {
|
||||
return {
|
||||
ambientColor : undefined, // Ka
|
||||
emissionColor : undefined, // Ke
|
||||
diffuseColor : undefined, // Kd
|
||||
specularColor : undefined, // Ks
|
||||
specularShininess : undefined, // Ns
|
||||
alpha : undefined, // d / Tr
|
||||
ambientColorMap : undefined, // map_Ka
|
||||
emissionColorMap : undefined, // map_Ke
|
||||
diffuseColorMap : undefined, // map_Kd
|
||||
specularColorMap : undefined, // map_Ks
|
||||
specularShininessMap : undefined, // map_Ns
|
||||
normalMap : undefined, // map_Bump
|
||||
alphaMap : undefined // map_d
|
||||
};
|
||||
}
|
||||
|
||||
function getDefault() {
|
||||
var material = createMaterial();
|
||||
material.diffuseColor = [0.5, 0.5, 0.5, 1.0];
|
||||
return material;
|
||||
}
|
||||
|
||||
function parse(mtlPath) {
|
||||
return fsReadFile(mtlPath, 'utf8')
|
||||
.then(function (contents) {
|
||||
var materials = {};
|
||||
var material;
|
||||
var values;
|
||||
var value;
|
||||
var lines = contents.split('\n');
|
||||
var length = lines.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
var line = lines[i].trim();
|
||||
if (/^newmtl /i.test(line)) {
|
||||
var name = line.substring(7).trim();
|
||||
material = createMaterial();
|
||||
materials[name] = material;
|
||||
} else if (/^Ka /i.test(line)) {
|
||||
values = line.substring(3).trim().split(' ');
|
||||
material.ambientColor = [
|
||||
parseFloat(values[0]),
|
||||
parseFloat(values[1]),
|
||||
parseFloat(values[2]),
|
||||
1.0
|
||||
];
|
||||
} else if (/^Ke /i.test(line)) {
|
||||
values = line.substring(3).trim().split(' ');
|
||||
material.emissionColor = [
|
||||
parseFloat(values[0]),
|
||||
parseFloat(values[1]),
|
||||
parseFloat(values[2]),
|
||||
1.0
|
||||
];
|
||||
} else if (/^Kd /i.test(line)) {
|
||||
values = line.substring(3).trim().split(' ');
|
||||
material.diffuseColor = [
|
||||
parseFloat(values[0]),
|
||||
parseFloat(values[1]),
|
||||
parseFloat(values[2]),
|
||||
1.0
|
||||
];
|
||||
} else if (/^Ks /i.test(line)) {
|
||||
values = line.substring(3).trim().split(' ');
|
||||
material.specularColor = [
|
||||
parseFloat(values[0]),
|
||||
parseFloat(values[1]),
|
||||
parseFloat(values[2]),
|
||||
1.0
|
||||
];
|
||||
} else if (/^Ns /i.test(line)) {
|
||||
value = line.substring(3).trim();
|
||||
material.specularShininess = parseFloat(value);
|
||||
} else if (/^d /i.test(line)) {
|
||||
value = line.substring(2).trim();
|
||||
material.alpha = parseFloat(value);
|
||||
} else if (/^Tr /i.test(line)) {
|
||||
value = line.substring(3).trim();
|
||||
material.alpha = parseFloat(value);
|
||||
} else if (/^map_Ka /i.test(line)) {
|
||||
material.ambientColorMap = line.substring(7).trim();
|
||||
} else if (/^map_Ke /i.test(line)) {
|
||||
material.emissionColorMap = line.substring(7).trim();
|
||||
} else if (/^map_Kd /i.test(line)) {
|
||||
material.diffuseColorMap = line.substring(7).trim();
|
||||
} else if (/^map_Ks /i.test(line)) {
|
||||
material.specularColorMap = line.substring(7).trim();
|
||||
} else if (/^map_Ns /i.test(line)) {
|
||||
material.specularShininessMap = line.substring(7).trim();
|
||||
} else if (/^map_Bump /i.test(line)) {
|
||||
material.normalMap = line.substring(9).trim();
|
||||
} else if (/^map_d /i.test(line)) {
|
||||
material.alphaMap = line.substring(6).trim();
|
||||
}
|
||||
}
|
||||
if (defined(material.alpha)) {
|
||||
material.diffuseColor[3] = material.alpha;
|
||||
}
|
||||
return materials;
|
||||
})
|
||||
.catch(function() {
|
||||
console.log('Could not read material file at ' + mtlPath + '. Using default material instead.');
|
||||
return {};
|
||||
});
|
||||
}
|
365
lib/obj.js
@ -1,365 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var Cesium = require('cesium');
|
||||
var Promise = require('bluebird');
|
||||
var byline = require('byline');
|
||||
var fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
|
||||
var loadImage = require('./image');
|
||||
var Material = require('./mtl');
|
||||
|
||||
var Cartesian3 = Cesium.Cartesian3;
|
||||
var defined = Cesium.defined;
|
||||
|
||||
module.exports = parseObj;
|
||||
|
||||
// OBJ regex patterns are from ThreeJS (https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js)
|
||||
|
||||
function parseObj(objFile, inputPath) {
|
||||
return getObjInfo(objFile, inputPath)
|
||||
.then(function(result) {
|
||||
var info = result.info;
|
||||
var materials = result.materials;
|
||||
var images = result.images;
|
||||
return processObj(objFile, info, materials, images);
|
||||
});
|
||||
}
|
||||
|
||||
function processObj(objFile, info, materials, images) {
|
||||
return new Promise(function(resolve) {
|
||||
// A vertex is specified by indexes into each of the attribute arrays,
|
||||
// but these indexes may be different. This maps the separate indexes to a single index.
|
||||
var vertexCache = {};
|
||||
var vertexCount = 0;
|
||||
|
||||
var vertexArray = [];
|
||||
|
||||
var positions = [];
|
||||
var normals = [];
|
||||
var uvs = [];
|
||||
|
||||
var positionMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
|
||||
var positionMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
|
||||
|
||||
var hasNormals = info.hasNormals;
|
||||
var hasUVs = info.hasUVs;
|
||||
|
||||
var materialGroups = {}; // Map material to index array
|
||||
var currentIndexArray;
|
||||
|
||||
// Switch to the material-specific index array, or create it if it doesn't exist
|
||||
function useMaterial(material) {
|
||||
if (!defined(materials[material])) {
|
||||
useDefaultMaterial();
|
||||
} else {
|
||||
currentIndexArray = materialGroups[material];
|
||||
if (!defined(currentIndexArray)) {
|
||||
currentIndexArray = [];
|
||||
materialGroups[material] = currentIndexArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function useDefaultMaterial() {
|
||||
var defaultMaterial = 'czmDefaultMat';
|
||||
if (!defined(materials[defaultMaterial])) {
|
||||
materials[defaultMaterial] = Material.getDefault();
|
||||
}
|
||||
useMaterial(defaultMaterial);
|
||||
}
|
||||
|
||||
var materialsLength = Object.keys(materials).length;
|
||||
if (materialsLength === 0) {
|
||||
useDefaultMaterial();
|
||||
}
|
||||
|
||||
function getOffset(a, data, components) {
|
||||
var i = parseInt(a);
|
||||
if (i < 0) {
|
||||
// Negative vertex indexes reference the vertices immediately above it
|
||||
return (data.length / components + i) * components;
|
||||
}
|
||||
return (i - 1) * components;
|
||||
}
|
||||
|
||||
function createVertex(p, u, n) {
|
||||
// Positions
|
||||
var pi = getOffset(p, positions, 3);
|
||||
var px = positions[pi + 0];
|
||||
var py = positions[pi + 1];
|
||||
var pz = positions[pi + 2];
|
||||
|
||||
positionMin[0] = Math.min(px, positionMin[0]);
|
||||
positionMin[1] = Math.min(py, positionMin[1]);
|
||||
positionMin[2] = Math.min(pz, positionMin[2]);
|
||||
positionMax[0] = Math.max(px, positionMax[0]);
|
||||
positionMax[1] = Math.max(py, positionMax[1]);
|
||||
positionMax[2] = Math.max(pz, positionMax[2]);
|
||||
vertexArray.push(px, py, pz);
|
||||
|
||||
// Normals
|
||||
if (hasNormals) {
|
||||
var ni = getOffset(n, normals, 3);
|
||||
var nx = normals[ni + 0];
|
||||
var ny = normals[ni + 1];
|
||||
var nz = normals[ni + 2];
|
||||
vertexArray.push(nx, ny, nz);
|
||||
}
|
||||
|
||||
// UVs
|
||||
if (hasUVs) {
|
||||
if (defined(u)) {
|
||||
var ui = getOffset(u, uvs, 2);
|
||||
var ux = uvs[ui + 0];
|
||||
var uy = uvs[ui + 1];
|
||||
// Flip y so 0.0 is the bottom of the image
|
||||
uy = 1.0 - uy;
|
||||
vertexArray.push(ux, uy);
|
||||
} else {
|
||||
// Some objects in the model may not have uvs, fill with 0's for consistency
|
||||
vertexArray.push(0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addVertex(v, p, u, n) {
|
||||
var index = vertexCache[v];
|
||||
if (!defined(index)) {
|
||||
index = vertexCount++;
|
||||
vertexCache[v] = index;
|
||||
createVertex(p, u, n);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
function addFace(v1, p1, u1, n1, v2, p2, u2, n2, v3, p3, u3, n3, v4, p4, u4, n4) {
|
||||
var index1 = addVertex(v1, p1, u1, n1);
|
||||
var index2 = addVertex(v2, p2, u2, n2);
|
||||
var index3 = addVertex(v3, p3, u3, n3);
|
||||
|
||||
currentIndexArray.push(index1);
|
||||
currentIndexArray.push(index2);
|
||||
currentIndexArray.push(index3);
|
||||
|
||||
// Triangulate if the face is a quad
|
||||
if (defined(v4)) {
|
||||
var index4 = addVertex(v4, p4, u4, n4);
|
||||
currentIndexArray.push(index1);
|
||||
currentIndexArray.push(index3);
|
||||
currentIndexArray.push(index4);
|
||||
}
|
||||
}
|
||||
|
||||
// v float float float
|
||||
var vertexPattern = /v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
|
||||
|
||||
// vn float float float
|
||||
var normalPattern = /vn( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
|
||||
|
||||
// vt float float
|
||||
var uvPattern = /vt( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
|
||||
|
||||
// f vertex vertex vertex ...
|
||||
var facePattern1 = /f( +-?\d+)\/?( +-?\d+)\/?( +-?\d+)\/?( +-?\d+)?\/?/;
|
||||
|
||||
// f vertex/uv vertex/uv vertex/uv ...
|
||||
var facePattern2 = /f( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)?/;
|
||||
|
||||
// f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
|
||||
var facePattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/;
|
||||
|
||||
// f vertex//normal vertex//normal vertex//normal ...
|
||||
var facePattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/;
|
||||
|
||||
var stream = byline(fs.createReadStream(objFile, {encoding: 'utf8'}));
|
||||
stream.on('data', function (line) {
|
||||
line = line.trim();
|
||||
var result;
|
||||
if ((line.length === 0) || (line.charAt(0) === '#')) {
|
||||
// Don't process empty lines or comments
|
||||
} else if ((result = vertexPattern.exec(line)) !== null) {
|
||||
positions.push(
|
||||
parseFloat(result[1]),
|
||||
parseFloat(result[2]),
|
||||
parseFloat(result[3])
|
||||
);
|
||||
} else if ((result = normalPattern.exec(line) ) !== null) {
|
||||
var nx = parseFloat(result[1]);
|
||||
var ny = parseFloat(result[2]);
|
||||
var nz = parseFloat(result[3]);
|
||||
var normal = Cartesian3.normalize(new Cartesian3(nx, ny, nz), new Cartesian3());
|
||||
normals.push(normal.x, normal.y, normal.z);
|
||||
} else if ((result = uvPattern.exec(line)) !== null) {
|
||||
uvs.push(
|
||||
parseFloat(result[1]),
|
||||
parseFloat(result[2])
|
||||
);
|
||||
} else if ((result = facePattern1.exec(line)) !== null) {
|
||||
addFace(
|
||||
result[1], result[1], undefined, undefined,
|
||||
result[2], result[2], undefined, undefined,
|
||||
result[3], result[3], undefined, undefined,
|
||||
result[4], result[4], undefined, undefined
|
||||
);
|
||||
} else if ((result = facePattern2.exec(line)) !== null) {
|
||||
addFace(
|
||||
result[1], result[2], result[3], undefined,
|
||||
result[4], result[5], result[6], undefined,
|
||||
result[7], result[8], result[9], undefined,
|
||||
result[10], result[11], result[12], undefined
|
||||
);
|
||||
} else if ((result = facePattern3.exec(line)) !== null) {
|
||||
addFace(
|
||||
result[1], result[2], result[3], result[4],
|
||||
result[5], result[6], result[7], result[8],
|
||||
result[9], result[10], result[11], result[12],
|
||||
result[13], result[14], result[15], result[16]
|
||||
);
|
||||
} else if ((result = facePattern4.exec(line)) !== null) {
|
||||
addFace(
|
||||
result[1], result[2], undefined, result[3],
|
||||
result[4], result[5], undefined, result[6],
|
||||
result[7], result[8], undefined, result[9],
|
||||
result[10], result[11], undefined, result[12]
|
||||
);
|
||||
} else if (/^usemtl /.test(line)) {
|
||||
var materialName = line.substring(7).trim();
|
||||
useMaterial(materialName);
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('end', function () {
|
||||
resolve({
|
||||
vertexCount: vertexCount,
|
||||
vertexArray: vertexArray,
|
||||
positionMin: positionMin,
|
||||
positionMax: positionMax,
|
||||
hasUVs: hasUVs,
|
||||
hasNormals: hasNormals,
|
||||
materialGroups: materialGroups,
|
||||
materials: materials,
|
||||
images: images
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getImages(inputPath, materials) {
|
||||
// Collect all the image files from the materials
|
||||
var images = [];
|
||||
for (var name in materials) {
|
||||
if (materials.hasOwnProperty(name)) {
|
||||
var material = materials[name];
|
||||
if (defined(material.ambientColorMap) && (images.indexOf(material.ambientColorMap) === -1)) {
|
||||
images.push(material.ambientColorMap);
|
||||
}
|
||||
if (defined(material.diffuseColorMap) && (images.indexOf(material.diffuseColorMap) === -1)) {
|
||||
images.push(material.diffuseColorMap);
|
||||
}
|
||||
if (defined(material.emissionColorMap) && (images.indexOf(material.emissionColorMap) === -1)) {
|
||||
images.push(material.emissionColorMap);
|
||||
}
|
||||
if (defined(material.specularColorMap) && (images.indexOf(material.specularColorMap) === -1)) {
|
||||
images.push(material.specularColorMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load the image files
|
||||
var promises = [];
|
||||
var imagesInfo = {};
|
||||
var imagesLength = images.length;
|
||||
for (var i = 0; i < imagesLength; i++) {
|
||||
var imagePath = images[i];
|
||||
if (!path.isAbsolute(imagePath)) {
|
||||
imagePath = path.join(inputPath, imagePath);
|
||||
}
|
||||
promises.push(loadImage(imagePath));
|
||||
}
|
||||
return Promise.all(promises)
|
||||
.then(function(imageInfoArray) {
|
||||
var imageInfoArrayLength = imageInfoArray.length;
|
||||
for (var j = 0; j < imageInfoArrayLength; j++) {
|
||||
var image = images[j];
|
||||
var imageInfo = imageInfoArray[j];
|
||||
imagesInfo[image] = imageInfo;
|
||||
}
|
||||
return imagesInfo;
|
||||
});
|
||||
}
|
||||
|
||||
function getMaterials(mtlPath, hasMaterialGroups) {
|
||||
if (hasMaterialGroups && defined(mtlPath)) {
|
||||
return Material.parse(mtlPath);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
function getObjInfo(objFile, inputPath) {
|
||||
var mtlPath;
|
||||
var materials;
|
||||
var info;
|
||||
var hasMaterialGroups = false;
|
||||
var hasPositions = false;
|
||||
var hasNormals = false;
|
||||
var hasUVs = false;
|
||||
return new Promise(function(resolve, reject) {
|
||||
var stream = byline(fs.createReadStream(objFile, {encoding: 'utf8'}));
|
||||
stream.on('data', function (line) {
|
||||
if (!defined(mtlPath)) {
|
||||
var mtllibMatches = line.match(/^mtllib.*/gm);
|
||||
if (mtllibMatches !== null) {
|
||||
var mtlFile = mtllibMatches[0].substring(7).trim();
|
||||
mtlPath = mtlFile;
|
||||
if (!path.isAbsolute(mtlPath)) {
|
||||
mtlPath = path.join(inputPath, mtlFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasMaterialGroups) {
|
||||
hasMaterialGroups = /^usemtl/gm.test(line);
|
||||
}
|
||||
if (!hasPositions) {
|
||||
hasPositions = /^v\s/gm.test(line);
|
||||
}
|
||||
if (!hasNormals) {
|
||||
hasNormals = /^vn/gm.test(line);
|
||||
}
|
||||
if (!hasUVs) {
|
||||
hasUVs = /^vt/gm.test(line);
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('error', function(err) {
|
||||
reject(err);
|
||||
});
|
||||
|
||||
stream.on('end', function () {
|
||||
if (!hasPositions) {
|
||||
reject(new Error('Could not process OBJ file, no positions.'));
|
||||
}
|
||||
info = {
|
||||
hasNormals: hasNormals,
|
||||
hasUVs: hasUVs
|
||||
};
|
||||
resolve();
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
return getMaterials(mtlPath, hasMaterialGroups);
|
||||
})
|
||||
.then(function(returnedMaterials) {
|
||||
materials = returnedMaterials;
|
||||
return getImages(inputPath, materials);
|
||||
})
|
||||
.then(function(images) {
|
||||
return {
|
||||
info : info,
|
||||
materials : materials,
|
||||
images : images
|
||||
};
|
||||
});
|
||||
}
|
253
lib/obj2gltf.js
Normal file
@ -0,0 +1,253 @@
|
||||
'use strict';
|
||||
var Cesium = require('cesium');
|
||||
var fsExtra = require('fs-extra');
|
||||
var GltfPipeline = require('gltf-pipeline').Pipeline;
|
||||
var os = require('os');
|
||||
var path = require('path');
|
||||
var Promise = require('bluebird');
|
||||
var uuid = require('uuid');
|
||||
var createGltf = require('./createGltf');
|
||||
var loadObj = require('./loadObj');
|
||||
var writeUris = require('./writeUris');
|
||||
|
||||
var defaultValue = Cesium.defaultValue;
|
||||
var defined = Cesium.defined;
|
||||
var DeveloperError = Cesium.DeveloperError;
|
||||
var RuntimeError = Cesium.RuntimeError;
|
||||
|
||||
module.exports = obj2gltf;
|
||||
|
||||
/**
|
||||
* Converts an obj file to a glTF file.
|
||||
*
|
||||
* @param {String} objPath Path to the obj file.
|
||||
* @param {String} gltfPath Path of the converted glTF file.
|
||||
* @param {Object} [options] An object with the following properties:
|
||||
* @param {Boolean} [options.binary=false] Save as binary glTF.
|
||||
* @param {Boolean} [options.separate=false] Writes out separate geometry data files, shader files, and textures instead of embedding them in the glTF.
|
||||
* @param {Boolean} [options.separateTextures=false] Write out separate textures only.
|
||||
* @param {Boolean} [options.compress=false] Quantize positions, compress texture coordinates, and oct-encode normals.
|
||||
* @param {Boolean} [options.optimize=false] Optimize the glTF for size and runtime performance.
|
||||
* @param {Boolean} [options.optimizeForCesium=false] Optimize the glTF for Cesium by using the sun as a default light source.
|
||||
* @param {Boolean} [options.generateNormals=false] Generate normals if they are missing.
|
||||
* @param {Boolean} [options.ao=false] Apply ambient occlusion to the converted model.
|
||||
* @param {Boolean} [options.kmc=false] Output glTF with the KHR_materials_common extension.
|
||||
* @param {Boolean} [options.textureCompressionOptions] Options sent to the compressTextures stage of gltf-pipeline.
|
||||
* @param {Boolean} [options.bypassPipeline=false] Bypass the gltf-pipeline for debugging purposes. This option overrides many of the options above and will save the glTF with the KHR_materials_common extension.
|
||||
* @param {Boolean} [options.checkTransparency=false] Do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
|
||||
* @param {Boolean} [options.secure=false] Prevent the converter from reading image or mtl files outside of the input obj directory.
|
||||
* @param {String} [options.inputUpAxis='Y'] Up axis of the obj. Choices are 'X', 'Y', and 'Z'.
|
||||
* @param {String} [options.outputUpAxis='Y'] Up axis of the converted glTF. Choices are 'X', 'Y', and 'Z'.
|
||||
* @param {Logger} [options.logger] A callback function for handling logged messages. Defaults to console.log.
|
||||
*/
|
||||
function obj2gltf(objPath, gltfPath, options) {
|
||||
var defaults = obj2gltf.defaults;
|
||||
|
||||
options = defaultValue(options, {});
|
||||
var binary = defaultValue(options.binary, defaults.binary);
|
||||
var separate = defaultValue(options.separate, defaults.separate);
|
||||
var separateTextures = defaultValue(options.separateTextures, defaults.separateTextures) || separate;
|
||||
var compress = defaultValue(options.compress, defaults.compress);
|
||||
var optimize = defaultValue(options.optimize, defaults.optimize);
|
||||
var optimizeForCesium = defaultValue(options.optimizeForCesium, defaults.optimizeForCesium);
|
||||
var generateNormals = defaultValue(options.generateNormals, defaults.generateNormals);
|
||||
var ao = defaultValue(options.ao, defaults.ao);
|
||||
var kmc = defaultValue(options.kmc, defaults.kmc);
|
||||
var textureCompressionOptions = options.textureCompressionOptions;
|
||||
var bypassPipeline = defaultValue(options.bypassPipeline, defaults.bypassPipeline);
|
||||
var checkTransparency = defaultValue(options.checkTransparency, defaults.checkTransparency);
|
||||
var secure = defaultValue(options.secure, defaults.secure);
|
||||
var inputUpAxis = defaultValue(options.inputUpAxis, defaults.inputUpAxis);
|
||||
var outputUpAxis = defaultValue(options.outputUpAxis, defaults.outputUpAxis);
|
||||
var logger = defaultValue(options.logger, defaults.logger);
|
||||
|
||||
options.generateNormals = generateNormals;
|
||||
options.separate = separate;
|
||||
options.separateTextures = separateTextures;
|
||||
options.checkTransparency = checkTransparency;
|
||||
options.secure = secure;
|
||||
options.inputUpAxis = inputUpAxis;
|
||||
options.outputUpAxis = outputUpAxis;
|
||||
options.logger = logger;
|
||||
|
||||
if (!defined(objPath)) {
|
||||
throw new DeveloperError('objPath is required');
|
||||
}
|
||||
|
||||
if (!defined(gltfPath)) {
|
||||
throw new DeveloperError('gltfPath is required');
|
||||
}
|
||||
|
||||
var extension = path.extname(gltfPath).toLowerCase();
|
||||
var modelName = path.basename(gltfPath, path.extname(gltfPath));
|
||||
if (extension === '.glb') {
|
||||
binary = true;
|
||||
}
|
||||
|
||||
if (binary && bypassPipeline) {
|
||||
return Promise.reject(new RuntimeError('--bypassPipeline does not convert to binary glTF'));
|
||||
}
|
||||
|
||||
gltfPath = path.join(path.dirname(gltfPath), modelName + extension);
|
||||
var resourcesDirectory = options.bypassPipeline ? path.dirname(gltfPath) : obj2gltf._getTempDirectory();
|
||||
|
||||
var aoOptions = ao ? {} : undefined;
|
||||
var kmcOptions = kmc ? {} : undefined;
|
||||
|
||||
var pipelineOptions = {
|
||||
createDirectory : false,
|
||||
basePath : resourcesDirectory,
|
||||
binary : binary,
|
||||
embed : !separate,
|
||||
embedImage : !separateTextures,
|
||||
quantize : compress,
|
||||
compressTextureCoordinates : compress,
|
||||
encodeNormals : compress,
|
||||
preserve : !optimize,
|
||||
optimizeForCesium : optimizeForCesium,
|
||||
smoothNormals : generateNormals,
|
||||
aoOptions : aoOptions,
|
||||
kmcOptions : kmcOptions,
|
||||
textureCompressionOptions : textureCompressionOptions
|
||||
};
|
||||
|
||||
return loadObj(objPath, options)
|
||||
.then(function(objData) {
|
||||
return createGltf(objData, options);
|
||||
})
|
||||
.then(function(gltf) {
|
||||
return writeUris(gltf, gltfPath, resourcesDirectory, options);
|
||||
})
|
||||
.then(function(gltf) {
|
||||
if (bypassPipeline) {
|
||||
return fsExtra.outputJson(gltfPath, gltf);
|
||||
}
|
||||
return GltfPipeline.processJSONToDisk(gltf, gltfPath, pipelineOptions);
|
||||
})
|
||||
.finally(function() {
|
||||
return cleanup(resourcesDirectory, options);
|
||||
});
|
||||
}
|
||||
|
||||
function cleanup(resourcesDirectory, options) {
|
||||
if (!options.bypassPipeline && options.separate) {
|
||||
fsExtra.remove(resourcesDirectory, function () {
|
||||
// Don't fail simply because we couldn't
|
||||
// clean up the temporary files.
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default values that will be used when calling obj2gltf(options) unless specified in the options object.
|
||||
*/
|
||||
obj2gltf.defaults = {
|
||||
/**
|
||||
* Gets or sets whether the model will be saved as binary glTF.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
binary: false,
|
||||
/**
|
||||
* Gets or sets whether to write out separate geometry/animation data files,
|
||||
* shader files, and textures instead of embedding them in the glTF.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
separate: false,
|
||||
/**
|
||||
* Gets or sets whether to write out separate textures only.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
separateTextures: false,
|
||||
/**
|
||||
* Gets or sets whether to compress attribute data. This includes quantizing positions, compressing texture coordinates, and oct-encoding normals.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
compress: false,
|
||||
/**
|
||||
* Gets or sets whether the model is optimized for size and runtime performance.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
optimize: false,
|
||||
/**
|
||||
* Gets or sets whether the model is optimized for Cesium by using the sun as a default light source.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
optimizeForCesium: false,
|
||||
/**
|
||||
* Gets or sets whether normals will be generated for the model if they are missing.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
generateNormals: false,
|
||||
/**
|
||||
* Gets or sets whether the model will have ambient occlusion applied.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
ao: false,
|
||||
/**
|
||||
* Gets or sets whether the model will be saved with the KHR_materials_common extension.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
kmc: false,
|
||||
/**
|
||||
* Gets or sets whether the converter will bypass the gltf-pipeline for debugging purposes.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
bypassPipeline: false,
|
||||
/**
|
||||
* Gets or sets whether the converter will do a more exhaustive check for texture transparency by looking at the alpha channel of each pixel.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
checkTransparency: false,
|
||||
/**
|
||||
* Gets or sets whether the source model can reference paths outside of its directory.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
*/
|
||||
secure: false,
|
||||
/**
|
||||
* Gets or sets the up axis of the obj.
|
||||
* @type String
|
||||
* @default 'Y'
|
||||
*/
|
||||
inputUpAxis: 'Y',
|
||||
/**
|
||||
* Gets or sets the up axis of the converted glTF.
|
||||
* @type String
|
||||
* @default 'Y'
|
||||
*/
|
||||
outputUpAxis: 'Y',
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
logger: function(message) {
|
||||
console.log(message);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Exposed for testing
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
obj2gltf._getTempDirectory = function () {
|
||||
return path.join(os.tmpdir(), uuid());
|
||||
};
|
||||
|
||||
/**
|
||||
* A callback function that logs messages.
|
||||
* @callback Logger
|
||||
*
|
||||
* @param {String} message The message to log.
|
||||
*/
|
||||
|
28
lib/readLines.js
Normal file
@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
var fsExtra = require('fs-extra');
|
||||
var Promise = require('bluebird');
|
||||
var readline = require('readline');
|
||||
|
||||
module.exports = readLines;
|
||||
|
||||
/**
|
||||
* Read a file line-by-line.
|
||||
*
|
||||
* @param {String} path Path to the file.
|
||||
* @param {Function} callback Function to call when reading each line.
|
||||
* @returns {Promise} A promise when the reader is finished.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function readLines(path, callback) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var stream = fsExtra.createReadStream(path);
|
||||
stream.on('error', reject);
|
||||
stream.on('end', resolve);
|
||||
|
||||
var lineReader = readline.createInterface({
|
||||
input: stream
|
||||
});
|
||||
lineReader.on('line', callback);
|
||||
});
|
||||
}
|
119
lib/writeUris.js
Normal file
@ -0,0 +1,119 @@
|
||||
'use strict';
|
||||
var Cesium = require('cesium');
|
||||
var fsExtra = require('fs-extra');
|
||||
var mime = require('mime');
|
||||
var path = require('path');
|
||||
var Promise = require('bluebird');
|
||||
|
||||
var RuntimeError = Cesium.RuntimeError;
|
||||
|
||||
module.exports = writeUris;
|
||||
|
||||
/**
|
||||
* Write glTF resources as embedded data uris or external files.
|
||||
*
|
||||
* @param {Object} gltf The glTF asset.
|
||||
* @param {String} gltfPath Path where the glTF will be saved.
|
||||
* @param {String} resourcesDirectory Path where separate resources will be saved.
|
||||
* @param {Object} options An object with the following properties:
|
||||
* @param {Boolean} options.separate Writes out separate buffers.
|
||||
* @param {Boolean} options.separateTextures Write out separate textures only.
|
||||
* @returns {Promise} A promise that resolves to the glTF asset.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function writeUris(gltf, gltfPath, resourcesDirectory, options) {
|
||||
var separate = options.separate;
|
||||
var separateTextures = options.separateTextures;
|
||||
|
||||
var promises = [];
|
||||
|
||||
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
|
||||
var bufferByteLength = buffer.extras._obj2gltf.source.length;
|
||||
|
||||
var texturesByteLength = 0;
|
||||
var images = gltf.images;
|
||||
for (var id in images) {
|
||||
if (images.hasOwnProperty(id)) {
|
||||
texturesByteLength += images[id].extras._obj2gltf.source.length;
|
||||
}
|
||||
}
|
||||
|
||||
// Buffers larger than ~192MB cannot be base64 encoded due to a NodeJS limitation. Source: https://github.com/nodejs/node/issues/4266
|
||||
var exceedsMaximum = (texturesByteLength + bufferByteLength > 201326580);
|
||||
|
||||
if (exceedsMaximum && !separate) {
|
||||
return Promise.reject(new RuntimeError('Buffers and textures are too large to encode in the glTF. Use the --separate flag instead.'));
|
||||
}
|
||||
|
||||
var name = path.basename(gltfPath, path.extname(gltfPath));
|
||||
|
||||
if (separate) {
|
||||
promises.push(writeSeparateBuffer(gltf, resourcesDirectory, name));
|
||||
} else {
|
||||
writeEmbeddedBuffer(gltf);
|
||||
}
|
||||
|
||||
if (separateTextures) {
|
||||
promises.push(writeSeparateTextures(gltf, resourcesDirectory));
|
||||
} else {
|
||||
writeEmbeddedTextures(gltf);
|
||||
}
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(function() {
|
||||
deleteExtras(gltf);
|
||||
return gltf;
|
||||
});
|
||||
}
|
||||
|
||||
function deleteExtras(gltf) {
|
||||
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
|
||||
delete buffer.extras;
|
||||
|
||||
var images = gltf.images;
|
||||
for (var id in images) {
|
||||
if (images.hasOwnProperty(id)) {
|
||||
var image = images[id];
|
||||
delete image.extras;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeSeparateBuffer(gltf, resourcesDirectory, name) {
|
||||
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
|
||||
var source = buffer.extras._obj2gltf.source;
|
||||
var bufferUri = name + '.bin';
|
||||
buffer.uri = bufferUri;
|
||||
var bufferPath = path.join(resourcesDirectory, bufferUri);
|
||||
return fsExtra.outputFile(bufferPath, source);
|
||||
}
|
||||
|
||||
function writeSeparateTextures(gltf, resourcesDirectory) {
|
||||
var images = gltf.images;
|
||||
return Promise.map(Object.keys(images), function(id) {
|
||||
var image = images[id];
|
||||
var extras = image.extras._obj2gltf;
|
||||
var imageUri = image.name + extras.extension;
|
||||
image.uri = imageUri;
|
||||
var imagePath = path.join(resourcesDirectory, imageUri);
|
||||
return fsExtra.outputFile(imagePath, extras.source);
|
||||
}, {concurrency : 10});
|
||||
}
|
||||
|
||||
function writeEmbeddedBuffer(gltf) {
|
||||
var buffer = gltf.buffers[Object.keys(gltf.buffers)[0]];
|
||||
var source = buffer.extras._obj2gltf.source;
|
||||
buffer.uri = 'data:application/octet-stream;base64,' + source.toString('base64');
|
||||
}
|
||||
|
||||
function writeEmbeddedTextures(gltf) {
|
||||
var images = gltf.images;
|
||||
for (var id in images) {
|
||||
if (images.hasOwnProperty(id)) {
|
||||
var image = images[id];
|
||||
var extras = image.extras._obj2gltf;
|
||||
image.uri = 'data:' + mime.lookup(extras.extension) + ';base64,' + extras.source.toString('base64');
|
||||
}
|
||||
}
|
||||
}
|
53
package.json
@ -1,58 +1,59 @@
|
||||
{
|
||||
"name": "obj2gltf",
|
||||
"version": "0.1.5",
|
||||
"version": "1.1.1",
|
||||
"description": "Convert OBJ model format to glTF",
|
||||
"license": "Apache-2.0",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Analytical Graphics, Inc., and Contributors",
|
||||
"url": "https://github.com/AnalyticalGraphicsInc/OBJ2GLTF/graphs/contributors"
|
||||
"name": "Analytical Graphics, Inc. and Contributors",
|
||||
"url": "https://github.com/AnalyticalGraphicsInc/obj2gltf/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"keywords": [
|
||||
"obj",
|
||||
"gltf"
|
||||
],
|
||||
"homepage": "https://github.com/AnalyticalGraphicsInc/OBJ2GLTF",
|
||||
"homepage": "https://github.com/AnalyticalGraphicsInc/obj2gltf",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:AnalyticalGraphicsInc/OBJ2GLTF.git"
|
||||
"url": "git@github.com:AnalyticalGraphicsInc/obj2gltf.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/AnalyticalGraphicsInc/OBJ2GLTF/issues"
|
||||
"url": "https://github.com/AnalyticalGraphicsInc/obj2gltf/issues"
|
||||
},
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "2.0.0-rc.6",
|
||||
"bluebird": "^3.4.1",
|
||||
"byline": "4.2.1",
|
||||
"cesium": "1.23.0",
|
||||
"fs-extra": "0.30.0",
|
||||
"gltf-pipeline": "0.1.0-alpha4",
|
||||
"yargs": "4.7.1"
|
||||
"bluebird": "^3.4.7",
|
||||
"cesium": "^1.31.0",
|
||||
"fs-extra": "^3.0.1",
|
||||
"gltf-pipeline": "^0.1.0-alpha11",
|
||||
"mime": "^1.3.4",
|
||||
"pngjs": "^3.0.1",
|
||||
"uuid": "^3.0.1",
|
||||
"yargs": "^8.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "3.9.1",
|
||||
"gulp-jshint": "2.0.1",
|
||||
"istanbul": "0.4.4",
|
||||
"jasmine": "2.4.1",
|
||||
"jasmine-spec-reporter": "2.5.0",
|
||||
"jshint": "2.9.2",
|
||||
"jshint-stylish": "2.2.0",
|
||||
"open": "0.0.5",
|
||||
"request": "2.72.0",
|
||||
"requirejs": "2.2.0"
|
||||
"coveralls": "^2.12.0",
|
||||
"eslint": "^4.1.1",
|
||||
"eslint-config-cesium": "^2.0.0",
|
||||
"gulp": "^3.9.1",
|
||||
"jasmine": "^2.5.3",
|
||||
"jasmine-spec-reporter": "^4.1.0",
|
||||
"jsdoc": "^3.4.3",
|
||||
"nyc": "^11.0.2",
|
||||
"open": "^0.0.5",
|
||||
"requirejs": "^2.3.3"
|
||||
},
|
||||
"scripts": {
|
||||
"jsHint": "gulp jsHint",
|
||||
"jsHint-watch": "gulp jsHint-watch",
|
||||
"jsdoc": "jsdoc ./lib -R ./README.md -d doc",
|
||||
"eslint": "eslint \"./**/*.js\" --cache --quiet",
|
||||
"test": "gulp test",
|
||||
"test-watch": "gulp test-watch",
|
||||
"coverage": "gulp coverage",
|
||||
"update-ts-definitions": "gulp update-ts-definitions"
|
||||
"coveralls": "cat ./coverage/lcov.info | ./node_modules/.bin/coveralls"
|
||||
},
|
||||
"bin": {
|
||||
"obj2gltf": "./bin/obj2gltf.js"
|
||||
|
6
specs/.eslintrc.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../.eslintrc.json",
|
||||
"env": {
|
||||
"jasmine": true
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"extends": "../.jshintrc",
|
||||
"jasmine": true,
|
||||
"unused": false
|
||||
}
|
Before Width: | Height: | Size: 22 KiB |
BIN
specs/data/box-complex-material/alpha.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
specs/data/box-complex-material/ambient.gif
Normal file
After Width: | Height: | Size: 3.9 KiB |
20
specs/data/box-complex-material/box-complex-material.mtl
Normal file
@ -0,0 +1,20 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.200000 0.200000 0.200000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.100000 0.100000 0.100000
|
||||
Ni 1.000000
|
||||
d 0.900000
|
||||
Tr 0.100000
|
||||
map_Ka ambient.gif
|
||||
map_Ke emission.jpg
|
||||
map_Kd diffuse.png
|
||||
map_Ks specular.jpeg
|
||||
map_Ns shininess.png
|
||||
map_Bump bump.png
|
||||
map_d alpha.png
|
||||
illum 2
|
@ -1,7 +1,7 @@
|
||||
# Blender v2.77 (sub 0) OBJ File: 'BoxTextured.blend'
|
||||
# Blender v2.78 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib BoxTextured.mtl
|
||||
o Cube_Cube.001
|
||||
mtllib box-complex-material.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
@ -26,9 +26,9 @@ vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
@ -36,11 +36,11 @@ vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Textured
|
||||
usemtl Material
|
||||
s off
|
||||
f 2/1/1 4/2/1 3/3/1 1/4/1
|
||||
f 4/5/2 8/6/2 7/7/2 3/8/2
|
||||
f 8/9/3 6/10/3 5/11/3 7/12/3
|
||||
f 6/13/4 2/14/4 1/15/4 5/16/4
|
||||
f 1/17/5 3/18/5 7/7/5 5/16/5
|
||||
f 6/13/6 8/6/6 4/19/6 2/20/6
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
BIN
specs/data/box-complex-material/bump.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
specs/data/box-complex-material/diffuse.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
specs/data/box-complex-material/emission.jpg
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
specs/data/box-complex-material/shininess.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
specs/data/box-complex-material/specular.jpeg
Normal file
After Width: | Height: | Size: 5.5 KiB |
13
specs/data/box-external-resources/box-external-resources.mtl
Normal file
@ -0,0 +1,13 @@
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl MaterialTextured
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
map_Kd ../box-textured/cesium.png
|
46
specs/data/box-external-resources/box-external-resources.obj
Normal file
@ -0,0 +1,46 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-multiple-materials.blend'
|
||||
# www.blender.org
|
||||
mtllib box-external-resources.mtl
|
||||
mtllib ../box/box.mtl
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
usemtl MaterialTextured
|
||||
f 3/1/1 7/2/1 5/3/1 1/4/1
|
||||
f 1/9/3 2/10/3 4/11/3 3/12/3
|
||||
f 3/1/5 4/6/5 8/17/5 7/18/5
|
||||
usemtl Material
|
||||
f 8/5/2 4/6/2 2/7/2 6/8/2
|
||||
f 7/13/4 8/14/4 6/15/4 5/16/4
|
||||
f 5/19/6 6/20/6 2/7/6 1/4/6
|
32
specs/data/box-groups/box-groups.mtl
Normal file
@ -0,0 +1,32 @@
|
||||
# Blender MTL File: 'box-objects.blend'
|
||||
# Material Count: 3
|
||||
|
||||
newmtl Blue
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.000000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Green
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.640000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Red
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.000000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
132
specs/data/box-groups/box-groups.obj
Normal file
@ -0,0 +1,132 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-objects.blend'
|
||||
# www.blender.org
|
||||
mtllib box-groups.mtl
|
||||
g CubeBlue
|
||||
v -1.000000 -1.000000 -4.000000
|
||||
v -1.000000 1.000000 -4.000000
|
||||
v -1.000000 -1.000000 -6.000000
|
||||
v -1.000000 1.000000 -6.000000
|
||||
v 1.000000 -1.000000 -4.000000
|
||||
v 1.000000 1.000000 -4.000000
|
||||
v 1.000000 -1.000000 -6.000000
|
||||
v 1.000000 1.000000 -6.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Blue
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
||||
g CubeGreen
|
||||
v 4.000000 -1.000000 1.000000
|
||||
v 4.000000 1.000000 1.000000
|
||||
v 4.000000 -1.000000 -1.000000
|
||||
v 4.000000 1.000000 -1.000000
|
||||
v 6.000000 -1.000000 1.000000
|
||||
v 6.000000 1.000000 1.000000
|
||||
v 6.000000 -1.000000 -1.000000
|
||||
v 6.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Green
|
||||
s off
|
||||
f 9/21/7 10/22/7 12/23/7 11/24/7
|
||||
f 11/25/8 12/26/8 16/27/8 15/28/8
|
||||
f 15/29/9 16/30/9 14/31/9 13/32/9
|
||||
f 13/33/10 14/34/10 10/35/10 9/36/10
|
||||
f 11/25/11 15/37/11 13/38/11 9/36/11
|
||||
f 16/39/12 12/26/12 10/35/12 14/40/12
|
||||
g CubeRed
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Red
|
||||
s off
|
||||
f 17/41/13 18/42/13 20/43/13 19/44/13
|
||||
f 19/45/14 20/46/14 24/47/14 23/48/14
|
||||
f 23/49/15 24/50/15 22/51/15 21/52/15
|
||||
f 21/53/16 22/54/16 18/55/16 17/56/16
|
||||
f 19/45/17 23/57/17 21/58/17 17/56/17
|
||||
f 24/59/18 20/46/18 18/55/18 22/60/18
|
46
specs/data/box-missing-mtllib/box-missing-mtllib.obj
Normal file
@ -0,0 +1,46 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib box.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
@ -1,13 +1,13 @@
|
||||
# Blender MTL File: 'BoxTextured.blend'
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Textured
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
map_Kd CesiumLogoFlat.png
|
||||
map_Kd cesium.png
|
46
specs/data/box-missing-texture/box-missing-texture.obj
Normal file
@ -0,0 +1,46 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
|
||||
# www.blender.org
|
||||
mtllib box-missing-texture.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
12
specs/data/box-mtllib/box-mtllib-blue.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'box-multiple-materials.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Blue
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.000000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
12
specs/data/box-mtllib/box-mtllib-green.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'box-multiple-materials.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Green
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.640000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
12
specs/data/box-mtllib/box-mtllib-red.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'box-multiple-materials.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Red
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.000000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
50
specs/data/box-mtllib/box-mtllib.obj
Normal file
@ -0,0 +1,50 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-multiple-materials.blend'
|
||||
# www.blender.org
|
||||
mtllib box-mtllib-red.mtl
|
||||
mtllib box-mtllib-green.mtl box-mtllib-blue.mtl
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
usemtl Red
|
||||
f 3/1/1 7/2/1 5/3/1 1/4/1
|
||||
usemtl Green
|
||||
f 1/9/3 2/10/3 4/11/3 3/12/3
|
||||
usemtl Blue
|
||||
f 3/1/5 4/6/5 8/17/5 7/18/5
|
||||
usemtl Red
|
||||
f 8/5/2 4/6/2 2/7/2 6/8/2
|
||||
usemtl Green
|
||||
f 7/13/4 8/14/4 6/15/4 5/16/4
|
||||
usemtl Blue
|
||||
f 5/19/6 6/20/6 2/7/6 1/4/6
|
32
specs/data/box-multiple-materials/box-multiple-materials.mtl
Normal file
@ -0,0 +1,32 @@
|
||||
# Blender MTL File: 'box-multiple-materials.blend'
|
||||
# Material Count: 3
|
||||
|
||||
newmtl Blue
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.000000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Green
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.640000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Red
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.000000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
49
specs/data/box-multiple-materials/box-multiple-materials.obj
Normal file
@ -0,0 +1,49 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-multiple-materials.blend'
|
||||
# www.blender.org
|
||||
mtllib box-multiple-materials.mtl
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
usemtl Red
|
||||
f 3/1/1 7/2/1 5/3/1 1/4/1
|
||||
usemtl Green
|
||||
f 1/9/3 2/10/3 4/11/3 3/12/3
|
||||
usemtl Blue
|
||||
f 3/1/5 4/6/5 8/17/5 7/18/5
|
||||
usemtl Red
|
||||
f 8/5/2 4/6/2 2/7/2 6/8/2
|
||||
usemtl Green
|
||||
f 7/13/4 8/14/4 6/15/4 5/16/4
|
||||
usemtl Blue
|
||||
f 5/19/6 6/20/6 2/7/6 1/4/6
|
12
specs/data/box-negative-indices/box-negative-indices.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
20
specs/data/box-negative-indices/box-negative-indices.obj
Normal file
@ -0,0 +1,20 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
|
||||
# www.blender.org
|
||||
mtllib box-negative-indices.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
usemtl Material
|
||||
s off
|
||||
f -8 -7 -5 -6
|
||||
f -6 -5 -1 -2
|
||||
f -2 -1 -3 -4
|
||||
f -4 -3 -7 -8
|
||||
f -6 -2 -4 -8
|
||||
f -1 -5 -7 -3
|
125
specs/data/box-no-materials/box-no-materials.obj
Normal file
@ -0,0 +1,125 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-objects.blend'
|
||||
# www.blender.org
|
||||
v -1.000000 -1.000000 -4.000000
|
||||
v -1.000000 1.000000 -4.000000
|
||||
v -1.000000 -1.000000 -6.000000
|
||||
v -1.000000 1.000000 -6.000000
|
||||
v 1.000000 -1.000000 -4.000000
|
||||
v 1.000000 1.000000 -4.000000
|
||||
v 1.000000 -1.000000 -6.000000
|
||||
v 1.000000 1.000000 -6.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
||||
v 4.000000 -1.000000 1.000000
|
||||
v 4.000000 1.000000 1.000000
|
||||
v 4.000000 -1.000000 -1.000000
|
||||
v 4.000000 1.000000 -1.000000
|
||||
v 6.000000 -1.000000 1.000000
|
||||
v 6.000000 1.000000 1.000000
|
||||
v 6.000000 -1.000000 -1.000000
|
||||
v 6.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
s off
|
||||
f 9/21/7 10/22/7 12/23/7 11/24/7
|
||||
f 11/25/8 12/26/8 16/27/8 15/28/8
|
||||
f 15/29/9 16/30/9 14/31/9 13/32/9
|
||||
f 13/33/10 14/34/10 10/35/10 9/36/10
|
||||
f 11/25/11 15/37/11 13/38/11 9/36/11
|
||||
f 16/39/12 12/26/12 10/35/12 14/40/12
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
s off
|
||||
f 17/41/13 18/42/13 20/43/13 19/44/13
|
||||
f 19/45/14 20/46/14 24/47/14 23/48/14
|
||||
f 23/49/15 24/50/15 22/51/15 21/52/15
|
||||
f 21/53/16 22/54/16 18/55/16 17/56/16
|
||||
f 19/45/17 23/57/17 21/58/17 17/56/17
|
||||
f 24/59/18 20/46/18 18/55/18 22/60/18
|
12
specs/data/box-normals/box-normals.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
26
specs/data/box-normals/box-normals.obj
Normal file
@ -0,0 +1,26 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
|
||||
# www.blender.org
|
||||
mtllib box-normals.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1//1 2//1 4//1 3//1
|
||||
f 3//2 4//2 8//2 7//2
|
||||
f 7//3 8//3 6//3 5//3
|
||||
f 5//4 6//4 2//4 1//4
|
||||
f 3//5 7//5 5//5 1//5
|
||||
f 8//6 4//6 2//6 6//6
|
@ -0,0 +1,492 @@
|
||||
{
|
||||
"accessors": {
|
||||
"accessor_0": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 0,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
-1,
|
||||
-1,
|
||||
-6
|
||||
],
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
-4
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_1": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 288,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_2": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 576,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"max": [
|
||||
1,
|
||||
1
|
||||
],
|
||||
"type": "VEC2"
|
||||
},
|
||||
"accessor_3": {
|
||||
"bufferView": "bufferView_index",
|
||||
"byteOffset": 0,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 18,
|
||||
"min": [
|
||||
0
|
||||
],
|
||||
"max": [
|
||||
11
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
"accessor_4": {
|
||||
"bufferView": "bufferView_index",
|
||||
"byteOffset": 36,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 18,
|
||||
"min": [
|
||||
12
|
||||
],
|
||||
"max": [
|
||||
23
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
"accessor_5": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 768,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
4,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"max": [
|
||||
6,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_6": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 1056,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_7": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 1344,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"max": [
|
||||
1,
|
||||
1
|
||||
],
|
||||
"type": "VEC2"
|
||||
},
|
||||
"accessor_8": {
|
||||
"bufferView": "bufferView_index",
|
||||
"byteOffset": 72,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 18,
|
||||
"min": [
|
||||
0
|
||||
],
|
||||
"max": [
|
||||
11
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
"accessor_9": {
|
||||
"bufferView": "bufferView_index",
|
||||
"byteOffset": 108,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 18,
|
||||
"min": [
|
||||
12
|
||||
],
|
||||
"max": [
|
||||
23
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
"accessor_10": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 1536,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_11": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 1824,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
"accessor_12": {
|
||||
"bufferView": "bufferView_vertex",
|
||||
"byteOffset": 2112,
|
||||
"byteStride": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"min": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"max": [
|
||||
1,
|
||||
1
|
||||
],
|
||||
"type": "VEC2"
|
||||
},
|
||||
"accessor_13": {
|
||||
"bufferView": "bufferView_index",
|
||||
"byteOffset": 144,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 18,
|
||||
"min": [
|
||||
0
|
||||
],
|
||||
"max": [
|
||||
11
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
"accessor_14": {
|
||||
"bufferView": "bufferView_index",
|
||||
"byteOffset": 180,
|
||||
"byteStride": 0,
|
||||
"componentType": 5123,
|
||||
"count": 18,
|
||||
"min": [
|
||||
12
|
||||
],
|
||||
"max": [
|
||||
23
|
||||
],
|
||||
"type": "SCALAR"
|
||||
}
|
||||
},
|
||||
"asset": {
|
||||
"generator": "obj2gltf",
|
||||
"profile": {
|
||||
"api": "WebGL",
|
||||
"version": "1.0"
|
||||
},
|
||||
"version": "1.0"
|
||||
},
|
||||
"buffers": {
|
||||
"buffer": {
|
||||
"byteLength": 2520,
|
||||
"uri": "data:application/octet-stream;base64,AACAvwAAgL8AAIDAAACAvwAAgD8AAIDAAACAvwAAgD8AAMDAAACAvwAAgL8AAMDAAACAvwAAgL8AAMDAAACAvwAAgD8AAMDAAACAPwAAgD8AAMDAAACAPwAAgL8AAMDAAACAPwAAgL8AAMDAAACAPwAAgD8AAMDAAACAPwAAgD8AAIDAAACAPwAAgL8AAIDAAACAPwAAgL8AAIDAAACAPwAAgD8AAIDAAACAvwAAgD8AAIDAAACAvwAAgL8AAIDAAACAvwAAgL8AAMDAAACAPwAAgL8AAMDAAACAPwAAgL8AAIDAAACAvwAAgL8AAIDAAACAPwAAgD8AAMDAAACAvwAAgD8AAMDAAACAvwAAgD8AAIDAAACAPwAAgD8AAIDAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAQAAAgL8AAIA/AACAQAAAgD8AAIA/AACAQAAAgD8AAIC/AACAQAAAgL8AAIC/AACAQAAAgL8AAIC/AACAQAAAgD8AAIC/AADAQAAAgD8AAIC/AADAQAAAgL8AAIC/AADAQAAAgL8AAIC/AADAQAAAgD8AAIC/AADAQAAAgD8AAIA/AADAQAAAgL8AAIA/AADAQAAAgL8AAIA/AADAQAAAgD8AAIA/AACAQAAAgD8AAIA/AACAQAAAgL8AAIA/AACAQAAAgL8AAIC/AADAQAAAgL8AAIC/AADAQAAAgL8AAIA/AACAQAAAgL8AAIA/AADAQAAAgD8AAIC/AACAQAAAgD8AAIC/AACAQAAAgD8AAIA/AADAQAAAgD8AAIA/AACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIA/AACAvwAAgL8AAIA/AACAPwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIA/AACAPwAAgD8AAIA/AACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAABAAIAAAACAAMABAAFAAYABAAGAAcACAAJAAoACAAKAAsADAANAA4ADAAOAA8AEAARABIAEAASABMAFAAVABYAFAAWABcAAAABAAIAAAACAAMABAAFAAYABAAGAAcACAAJAAoACAAKAAsADAANAA4ADAAOAA8AEAARABIAEAASABMAFAAVABYAFAAWABcAAAABAAIAAAACAAMABAAFAAYABAAGAAcACAAJAAoACAAKAAsADAANAA4ADAAOAA8AEAARABIAEAASABMAFAAVABYAFAAWABcA"
|
||||
}
|
||||
},
|
||||
"bufferViews": {
|
||||
"bufferView_vertex": {
|
||||
"buffer": "buffer",
|
||||
"byteLength": 2304,
|
||||
"byteOffset": 0,
|
||||
"target": 34962
|
||||
},
|
||||
"bufferView_index": {
|
||||
"buffer": "buffer",
|
||||
"byteLength": 216,
|
||||
"byteOffset": 2304,
|
||||
"target": 34963
|
||||
}
|
||||
},
|
||||
"extensionsUsed": [
|
||||
"KHR_materials_common"
|
||||
],
|
||||
"images": {},
|
||||
"materials": {
|
||||
"Blue": {
|
||||
"extensions": {
|
||||
"KHR_materials_common": {
|
||||
"technique": "PHONG",
|
||||
"transparent": false,
|
||||
"doubleSided": false,
|
||||
"values": {
|
||||
"ambient": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"diffuse": [
|
||||
0,
|
||||
0,
|
||||
0.64,
|
||||
1
|
||||
],
|
||||
"emission": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"specular": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5,
|
||||
1
|
||||
],
|
||||
"shininess": 96.078431,
|
||||
"transparency": 1,
|
||||
"transparent": false,
|
||||
"doubleSided": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Green": {
|
||||
"extensions": {
|
||||
"KHR_materials_common": {
|
||||
"technique": "PHONG",
|
||||
"transparent": false,
|
||||
"doubleSided": false,
|
||||
"values": {
|
||||
"ambient": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"diffuse": [
|
||||
0,
|
||||
0.64,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"emission": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"specular": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5,
|
||||
1
|
||||
],
|
||||
"shininess": 96.078431,
|
||||
"transparency": 1,
|
||||
"transparent": false,
|
||||
"doubleSided": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Red": {
|
||||
"extensions": {
|
||||
"KHR_materials_common": {
|
||||
"technique": "PHONG",
|
||||
"transparent": false,
|
||||
"doubleSided": false,
|
||||
"values": {
|
||||
"ambient": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"diffuse": [
|
||||
0.64,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"emission": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"specular": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5,
|
||||
1
|
||||
],
|
||||
"shininess": 96.078431,
|
||||
"transparency": 1,
|
||||
"transparent": false,
|
||||
"doubleSided": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"meshes": {
|
||||
"CubeBlue_CubeBlue_Blue": {
|
||||
"name": "CubeBlue_CubeBlue_Blue",
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": "accessor_0",
|
||||
"NORMAL": "accessor_1",
|
||||
"TEXCOORD_0": "accessor_2"
|
||||
},
|
||||
"indices": "accessor_3",
|
||||
"material": "Blue",
|
||||
"mode": 4
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": "accessor_0",
|
||||
"NORMAL": "accessor_1",
|
||||
"TEXCOORD_0": "accessor_2"
|
||||
},
|
||||
"indices": "accessor_4",
|
||||
"material": "Green",
|
||||
"mode": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"CubeGreen_CubeGreen_Green": {
|
||||
"name": "CubeGreen_CubeGreen_Green",
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": "accessor_5",
|
||||
"NORMAL": "accessor_6",
|
||||
"TEXCOORD_0": "accessor_7"
|
||||
},
|
||||
"indices": "accessor_8",
|
||||
"material": "Green",
|
||||
"mode": 4
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": "accessor_5",
|
||||
"NORMAL": "accessor_6",
|
||||
"TEXCOORD_0": "accessor_7"
|
||||
},
|
||||
"indices": "accessor_9",
|
||||
"material": "Red",
|
||||
"mode": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"CubeRed_CubeRed_Red": {
|
||||
"name": "CubeRed_CubeRed_Red",
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": "accessor_10",
|
||||
"NORMAL": "accessor_11",
|
||||
"TEXCOORD_0": "accessor_12"
|
||||
},
|
||||
"indices": "accessor_13",
|
||||
"material": "Red",
|
||||
"mode": 4
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": "accessor_10",
|
||||
"NORMAL": "accessor_11",
|
||||
"TEXCOORD_0": "accessor_12"
|
||||
},
|
||||
"indices": "accessor_14",
|
||||
"material": "Blue",
|
||||
"mode": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"Cube": {
|
||||
"name": "Cube",
|
||||
"meshes": [
|
||||
"CubeBlue_CubeBlue_Blue",
|
||||
"CubeGreen_CubeGreen_Green",
|
||||
"CubeRed_CubeRed_Red"
|
||||
]
|
||||
}
|
||||
},
|
||||
"samplers": {},
|
||||
"scene": "scene",
|
||||
"scenes": {
|
||||
"scene": {
|
||||
"nodes": [
|
||||
"Cube"
|
||||
]
|
||||
}
|
||||
},
|
||||
"textures": {}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
# Blender MTL File: 'box-objects.blend'
|
||||
# Material Count: 3
|
||||
|
||||
newmtl Blue
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.000000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Green
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.640000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Red
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.000000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
@ -0,0 +1,133 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-objects.blend'
|
||||
# www.blender.org
|
||||
mtllib box-objects-groups-materials.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 -4.000000
|
||||
v -1.000000 1.000000 -4.000000
|
||||
v -1.000000 -1.000000 -6.000000
|
||||
v -1.000000 1.000000 -6.000000
|
||||
v 1.000000 -1.000000 -4.000000
|
||||
v 1.000000 1.000000 -4.000000
|
||||
v 1.000000 -1.000000 -6.000000
|
||||
v 1.000000 1.000000 -6.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
g CubeBlue_CubeBlue_Blue
|
||||
usemtl Blue
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
usemtl Green
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
||||
v 4.000000 -1.000000 1.000000
|
||||
v 4.000000 1.000000 1.000000
|
||||
v 4.000000 -1.000000 -1.000000
|
||||
v 4.000000 1.000000 -1.000000
|
||||
v 6.000000 -1.000000 1.000000
|
||||
v 6.000000 1.000000 1.000000
|
||||
v 6.000000 -1.000000 -1.000000
|
||||
v 6.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
g CubeGreen_CubeGreen_Green
|
||||
usemtl Green
|
||||
f 9/21/7 10/22/7 12/23/7 11/24/7
|
||||
f 11/25/8 12/26/8 16/27/8 15/28/8
|
||||
f 15/29/9 16/30/9 14/31/9 13/32/9
|
||||
usemtl Red
|
||||
f 13/33/10 14/34/10 10/35/10 9/36/10
|
||||
f 11/25/11 15/37/11 13/38/11 9/36/11
|
||||
f 16/39/12 12/26/12 10/35/12 14/40/12
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
g CubeRed_CubeRed_Red
|
||||
usemtl Red
|
||||
f 17/41/13 18/42/13 20/43/13 19/44/13
|
||||
f 19/45/14 20/46/14 24/47/14 23/48/14
|
||||
f 23/49/15 24/50/15 22/51/15 21/52/15
|
||||
usemtl Blue
|
||||
f 21/53/16 22/54/16 18/55/16 17/56/16
|
||||
f 19/45/17 23/57/17 21/58/17 17/56/17
|
||||
f 24/59/18 20/46/18 18/55/18 22/60/18
|
32
specs/data/box-objects-groups/box-objects-groups.mtl
Normal file
@ -0,0 +1,32 @@
|
||||
# Blender MTL File: 'box-objects.blend'
|
||||
# Material Count: 3
|
||||
|
||||
newmtl Blue
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.000000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Green
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.640000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Red
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.000000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
135
specs/data/box-objects-groups/box-objects-groups.obj
Normal file
@ -0,0 +1,135 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-objects.blend'
|
||||
# www.blender.org
|
||||
mtllib box-objects-groups.mtl
|
||||
o CubeBlue
|
||||
v -1.000000 -1.000000 -4.000000
|
||||
v -1.000000 1.000000 -4.000000
|
||||
v -1.000000 -1.000000 -6.000000
|
||||
v -1.000000 1.000000 -6.000000
|
||||
v 1.000000 -1.000000 -4.000000
|
||||
v 1.000000 1.000000 -4.000000
|
||||
v 1.000000 -1.000000 -6.000000
|
||||
v 1.000000 1.000000 -6.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
g CubeBlue_CubeBlue_Blue
|
||||
usemtl Blue
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
||||
o CubeGreen
|
||||
v 4.000000 -1.000000 1.000000
|
||||
v 4.000000 1.000000 1.000000
|
||||
v 4.000000 -1.000000 -1.000000
|
||||
v 4.000000 1.000000 -1.000000
|
||||
v 6.000000 -1.000000 1.000000
|
||||
v 6.000000 1.000000 1.000000
|
||||
v 6.000000 -1.000000 -1.000000
|
||||
v 6.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
g CubeGreen_CubeGreen_Green
|
||||
usemtl Green
|
||||
s off
|
||||
f 9/21/7 10/22/7 12/23/7 11/24/7
|
||||
f 11/25/8 12/26/8 16/27/8 15/28/8
|
||||
f 15/29/9 16/30/9 14/31/9 13/32/9
|
||||
f 13/33/10 14/34/10 10/35/10 9/36/10
|
||||
f 11/25/11 15/37/11 13/38/11 9/36/11
|
||||
f 16/39/12 12/26/12 10/35/12 14/40/12
|
||||
o CubeRed
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
g CubeRed_CubeRed_Red
|
||||
usemtl Red
|
||||
s off
|
||||
f 17/41/13 18/42/13 20/43/13 19/44/13
|
||||
f 19/45/14 20/46/14 24/47/14 23/48/14
|
||||
f 23/49/15 24/50/15 22/51/15 21/52/15
|
||||
f 21/53/16 22/54/16 18/55/16 17/56/16
|
||||
f 19/45/17 23/57/17 21/58/17 17/56/17
|
||||
f 24/59/18 20/46/18 18/55/18 22/60/18
|
32
specs/data/box-objects/box-objects.mtl
Normal file
@ -0,0 +1,32 @@
|
||||
# Blender MTL File: 'box-objects.blend'
|
||||
# Material Count: 3
|
||||
|
||||
newmtl Blue
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.000000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Green
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.640000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Red
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.000000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
132
specs/data/box-objects/box-objects.obj
Normal file
@ -0,0 +1,132 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-objects.blend'
|
||||
# www.blender.org
|
||||
mtllib box-objects.mtl
|
||||
o CubeBlue
|
||||
v -1.000000 -1.000000 -4.000000
|
||||
v -1.000000 1.000000 -4.000000
|
||||
v -1.000000 -1.000000 -6.000000
|
||||
v -1.000000 1.000000 -6.000000
|
||||
v 1.000000 -1.000000 -4.000000
|
||||
v 1.000000 1.000000 -4.000000
|
||||
v 1.000000 -1.000000 -6.000000
|
||||
v 1.000000 1.000000 -6.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Blue
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
||||
o CubeGreen
|
||||
v 4.000000 -1.000000 1.000000
|
||||
v 4.000000 1.000000 1.000000
|
||||
v 4.000000 -1.000000 -1.000000
|
||||
v 4.000000 1.000000 -1.000000
|
||||
v 6.000000 -1.000000 1.000000
|
||||
v 6.000000 1.000000 1.000000
|
||||
v 6.000000 -1.000000 -1.000000
|
||||
v 6.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Green
|
||||
s off
|
||||
f 9/21/7 10/22/7 12/23/7 11/24/7
|
||||
f 11/25/8 12/26/8 16/27/8 15/28/8
|
||||
f 15/29/9 16/30/9 14/31/9 13/32/9
|
||||
f 13/33/10 14/34/10 10/35/10 9/36/10
|
||||
f 11/25/11 15/37/11 13/38/11 9/36/11
|
||||
f 16/39/12 12/26/12 10/35/12 14/40/12
|
||||
o CubeRed
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Red
|
||||
s off
|
||||
f 17/41/13 18/42/13 20/43/13 19/44/13
|
||||
f 19/45/14 20/46/14 24/47/14 23/48/14
|
||||
f 23/49/15 24/50/15 22/51/15 21/52/15
|
||||
f 21/53/16 22/54/16 18/55/16 17/56/16
|
||||
f 19/45/17 23/57/17 21/58/17 17/56/17
|
||||
f 24/59/18 20/46/18 18/55/18 22/60/18
|
12
specs/data/box-positions-only/box-positions-only.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
20
specs/data/box-positions-only/box-positions-only.obj
Normal file
@ -0,0 +1,20 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
|
||||
# www.blender.org
|
||||
mtllib box-positions-only.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1 2 4 3
|
||||
f 3 4 8 7
|
||||
f 7 8 6 5
|
||||
f 5 6 2 1
|
||||
f 3 7 5 1
|
||||
f 8 4 2 6
|
10
specs/data/box-rotated/box-rotated.mtl
Normal file
@ -0,0 +1,10 @@
|
||||
# Blender MTL File: 'axis.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl None
|
||||
Ns 0
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.8 0.8 0.8
|
||||
Ks 0.8 0.8 0.8
|
||||
d 1
|
||||
illum 2
|
112
specs/data/box-rotated/box-rotated.obj
Normal file
@ -0,0 +1,112 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'axis.blend'
|
||||
# www.blender.org
|
||||
mtllib box-rotated.mtl
|
||||
o Cube.002_Cube
|
||||
v -1.707107 -0.292893 0.000000
|
||||
v -0.707107 0.707107 1.414214
|
||||
v -0.707107 0.707107 -1.414214
|
||||
v 0.292893 1.707107 0.000000
|
||||
v -0.292893 -1.707107 0.000000
|
||||
v 0.707107 -0.707107 1.414214
|
||||
v 0.707107 -0.707107 -1.414214
|
||||
v 1.707107 0.292893 0.000000
|
||||
vn -0.7071 0.7071 0.0000
|
||||
vn 0.5000 0.5000 -0.7071
|
||||
vn 0.7071 -0.7071 -0.0000
|
||||
vn -0.5000 -0.5000 0.7071
|
||||
vn -0.5000 -0.5000 -0.7071
|
||||
vn 0.5000 0.5000 0.7071
|
||||
usemtl None
|
||||
s off
|
||||
f 1//1 2//1 4//1 3//1
|
||||
f 3//2 4//2 8//2 7//2
|
||||
f 7//3 8//3 6//3 5//3
|
||||
f 5//4 6//4 2//4 1//4
|
||||
f 3//5 7//5 5//5 1//5
|
||||
f 8//6 4//6 2//6 6//6
|
||||
o Cube.001_Cube.002
|
||||
v -3.997752 -1.000000 3.997752
|
||||
v -3.997752 1.000000 3.997752
|
||||
v -3.997752 -1.000000 -3.997752
|
||||
v -3.997752 1.000000 -3.997752
|
||||
v 3.997752 -1.000000 3.997752
|
||||
v 3.997752 1.000000 3.997752
|
||||
v 3.997752 -1.000000 -3.997752
|
||||
v 3.997752 1.000000 -3.997752
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl None
|
||||
s off
|
||||
f 9//7 10//7 12//7 11//7
|
||||
f 11//8 12//8 16//8 15//8
|
||||
f 15//9 16//9 14//9 13//9
|
||||
f 13//10 14//10 10//10 9//10
|
||||
f 11//11 15//11 13//11 9//11
|
||||
f 16//12 12//12 10//12 14//12
|
||||
o Cube_Cube.001
|
||||
v -1.000000 4.235625 1.000000
|
||||
v -1.000000 6.235625 1.000000
|
||||
v -1.000000 4.235625 -1.000000
|
||||
v -1.000000 6.235625 -1.000000
|
||||
v 1.000000 4.235625 1.000000
|
||||
v 1.000000 6.235625 1.000000
|
||||
v 1.000000 4.235625 -1.000000
|
||||
v 1.000000 6.235625 -1.000000
|
||||
v 0.000000 9.029284 0.000000
|
||||
v 1.000000 4.663946 0.571679
|
||||
v 1.000000 5.807305 0.571679
|
||||
v 1.000000 4.663946 -0.571679
|
||||
v 1.000000 5.807305 -0.571679
|
||||
v 2.375958 4.663946 0.571679
|
||||
v 2.375958 5.807305 0.571679
|
||||
v 2.375958 4.663946 -0.571679
|
||||
v 2.375958 5.807305 -0.571679
|
||||
v -0.310735 4.924891 -1.000000
|
||||
v -0.310735 5.546360 -1.000000
|
||||
v 0.310735 4.924891 -1.000000
|
||||
v 0.310735 5.546360 -1.000000
|
||||
v 0.000000 5.235625 -1.538583
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 0.3370 -0.9415
|
||||
vn -0.9415 0.3370 0.0000
|
||||
vn 0.0000 0.3370 0.9415
|
||||
vn 0.9415 0.3370 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn 0.8662 0.0000 -0.4997
|
||||
vn 0.0000 -0.8662 -0.4997
|
||||
vn 0.0000 0.8662 -0.4997
|
||||
vn -0.8662 0.0000 -0.4997
|
||||
usemtl None
|
||||
s off
|
||||
f 17//13 18//13 20//13 19//13
|
||||
f 23//14 19//14 34//14 36//14
|
||||
f 22//15 21//15 26//15 27//15
|
||||
f 21//16 22//16 18//16 17//16
|
||||
f 19//17 23//17 21//17 17//17
|
||||
f 24//18 20//18 25//18
|
||||
f 20//19 18//19 25//19
|
||||
f 18//20 22//20 25//20
|
||||
f 22//21 24//21 25//21
|
||||
f 29//22 27//22 31//22 33//22
|
||||
f 21//15 23//15 28//15 26//15
|
||||
f 24//15 22//15 27//15 29//15
|
||||
f 23//15 24//15 29//15 28//15
|
||||
f 32//15 33//15 31//15 30//15
|
||||
f 28//14 29//14 33//14 32//14
|
||||
f 27//16 26//16 30//16 31//16
|
||||
f 26//17 28//17 32//17 30//17
|
||||
f 37//23 36//23 38//23
|
||||
f 20//14 24//14 37//14 35//14
|
||||
f 19//14 20//14 35//14 34//14
|
||||
f 24//14 23//14 36//14 37//14
|
||||
f 36//24 34//24 38//24
|
||||
f 35//25 37//25 38//25
|
||||
f 34//26 35//26 38//26
|
46
specs/data/box-subdirectories/box-textured.obj
Normal file
@ -0,0 +1,46 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
|
||||
# www.blender.org
|
||||
mtllib materials/box-textured.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
13
specs/data/box-subdirectories/materials/box-textured.mtl
Normal file
@ -0,0 +1,13 @@
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
map_Kd images/cesium.png
|
BIN
specs/data/box-subdirectories/materials/images/cesium.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
13
specs/data/box-textured/box-textured.mtl
Normal file
@ -0,0 +1,13 @@
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
map_Kd cesium.png
|
46
specs/data/box-textured/box-textured.obj
Normal file
@ -0,0 +1,46 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
|
||||
# www.blender.org
|
||||
mtllib box-textured.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
BIN
specs/data/box-textured/cesium.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
12
specs/data/box-triangles/box-triangles.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
46
specs/data/box-triangles/box-triangles.obj
Normal file
@ -0,0 +1,46 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
|
||||
# www.blender.org
|
||||
mtllib box-triangles.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
12
specs/data/box-uncleaned/box-uncleaned.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
52
specs/data/box-uncleaned/box-uncleaned.obj
Normal file
@ -0,0 +1,52 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib box-uncleaned.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
g Cube
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
o Cube
|
||||
g Cube
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
||||
g Cube
|
||||
usemtl Material
|
||||
o Cube
|
32
specs/data/box-usemtl/box-usemtl.mtl
Normal file
@ -0,0 +1,32 @@
|
||||
# Blender MTL File: 'box-objects.blend'
|
||||
# Material Count: 3
|
||||
|
||||
newmtl Blue
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.000000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Green
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.000000 0.640000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
|
||||
newmtl Red
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.000000 0.000000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
129
specs/data/box-usemtl/box-usemtl.obj
Normal file
@ -0,0 +1,129 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box-objects.blend'
|
||||
# www.blender.org
|
||||
mtllib box-usemtl.mtl
|
||||
v -1.000000 -1.000000 -4.000000
|
||||
v -1.000000 1.000000 -4.000000
|
||||
v -1.000000 -1.000000 -6.000000
|
||||
v -1.000000 1.000000 -6.000000
|
||||
v 1.000000 -1.000000 -4.000000
|
||||
v 1.000000 1.000000 -4.000000
|
||||
v 1.000000 -1.000000 -6.000000
|
||||
v 1.000000 1.000000 -6.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Blue
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/5/5 7/17/5 5/18/5 1/16/5
|
||||
f 8/19/6 4/6/6 2/15/6 6/20/6
|
||||
v 4.000000 -1.000000 1.000000
|
||||
v 4.000000 1.000000 1.000000
|
||||
v 4.000000 -1.000000 -1.000000
|
||||
v 4.000000 1.000000 -1.000000
|
||||
v 6.000000 -1.000000 1.000000
|
||||
v 6.000000 1.000000 1.000000
|
||||
v 6.000000 -1.000000 -1.000000
|
||||
v 6.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Green
|
||||
s off
|
||||
f 9/21/7 10/22/7 12/23/7 11/24/7
|
||||
f 11/25/8 12/26/8 16/27/8 15/28/8
|
||||
f 15/29/9 16/30/9 14/31/9 13/32/9
|
||||
f 13/33/10 14/34/10 10/35/10 9/36/10
|
||||
f 11/25/11 15/37/11 13/38/11 9/36/11
|
||||
f 16/39/12 12/26/12 10/35/12 14/40/12
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl Red
|
||||
s off
|
||||
f 17/41/13 18/42/13 20/43/13 19/44/13
|
||||
f 19/45/14 20/46/14 24/47/14 23/48/14
|
||||
f 23/49/15 24/50/15 22/51/15 21/52/15
|
||||
f 21/53/16 22/54/16 18/55/16 17/56/16
|
||||
f 19/45/17 23/57/17 21/58/17 17/56/17
|
||||
f 24/59/18 20/46/18 18/55/18 22/60/18
|
12
specs/data/box-uvs/box-uvs.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'box.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 96.078431
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.640000 0.640000 0.640000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
40
specs/data/box-uvs/box-uvs.obj
Normal file
@ -0,0 +1,40 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
|
||||
# www.blender.org
|
||||
mtllib box-uvs.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1 2/2 4/3 3/4
|
||||
f 3/5 4/6 8/7 7/8
|
||||
f 7/9 8/10 6/11 5/12
|
||||
f 5/13 6/14 2/15 1/16
|
||||
f 3/5 7/17 5/18 1/16
|
||||
f 8/19 4/6 2/15 6/20
|