@realsee/five 5.0.0-alpha.13 → 5.0.0-alpha.130
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -11
- package/docs/.nojekyll +1 -0
- package/docs/assets/highlight.css +134 -0
- package/docs/assets/icons.css +1043 -0
- package/docs/assets/{images/icons.png → icons.png} +0 -0
- package/docs/assets/{images/icons@2x.png → icons@2x.png} +0 -0
- package/docs/assets/main.js +52 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1413 -0
- package/docs/assets/{images/widgets.png → widgets.png} +0 -0
- package/docs/assets/{images/widgets@2x.png → widgets@2x.png} +0 -0
- package/docs/classes/five.AnimationFrameLoop.html +15 -0
- package/docs/classes/five.BVH.html +10 -0
- package/docs/classes/five.BVHIntersect.html +1 -0
- package/docs/classes/five.BVHNode.html +7 -0
- package/docs/classes/five.BVHVector3.html +1 -0
- package/docs/classes/five.Camera.html +11 -0
- package/docs/classes/five.Five.html +303 -0
- package/docs/classes/five.InternalWebGLRenderer.html +1 -0
- package/docs/classes/five.IntersectMesh.html +1 -0
- package/docs/classes/five.LegacyPanoCircleMesh.html +5 -0
- package/docs/classes/five.Model.html +87 -0
- package/docs/classes/five.NetworkSubscribe.html +50 -0
- package/docs/classes/five.PBMContainer.html +17 -0
- package/docs/classes/five.PBMGroup.html +19 -0
- package/docs/classes/five.PBMMaterial.html +17 -0
- package/docs/classes/five.PBMMesh.html +7 -0
- package/docs/classes/five.PanoCircleMesh.html +7 -0
- package/docs/classes/five.Scene.html +3 -0
- package/docs/classes/five.Subscribe.html +56 -0
- package/docs/classes/five.Tile3DModel.html +15 -0
- package/docs/classes/five.Work.html +30 -0
- package/docs/classes/gltf_loader.GLTFLoader.html +17 -0
- package/docs/classes/gltf_loader.GLTFObject.html +7 -0
- package/docs/classes/line.Line.html +1 -0
- package/docs/classes/line.LineGeometry.html +1 -0
- package/docs/classes/line.LineMaterial.html +1 -0
- package/docs/classes/line.LineSegmentsGeometry.html +1 -0
- package/docs/classes/line.THREE_Line2.html +1 -0
- package/docs/classes/line.THREE_LineSegments2.html +1 -0
- package/docs/classes/react.Store.html +29 -0
- package/docs/classes/server.BVH.html +10 -0
- package/docs/classes/server.BVHIntersect.html +1 -0
- package/docs/classes/server.BVHNode.html +7 -0
- package/docs/classes/server.BVHVector3.html +1 -0
- package/docs/classes/server.Model.html +63 -0
- package/docs/classes/server.PBMGroup.html +9 -0
- package/docs/classes/server.PBMMesh.html +7 -0
- package/docs/classes/sticker.Sticker.html +32 -0
- package/docs/index.html +166 -422
- package/docs/interfaces/five.AddableObject.html +1 -0
- package/docs/interfaces/five.AnimationFrame.html +1 -0
- package/docs/interfaces/five.CameraPose.html +1 -0
- package/docs/interfaces/five.DepthPanoramaControllerCustomInitArgs.html +28 -0
- package/docs/interfaces/five.EventCallback.html +391 -0
- package/docs/interfaces/five.FiveInitArgs.html +100 -0
- package/docs/interfaces/five.FloorplanControllerCustomInitArgs.html +15 -0
- package/docs/interfaces/five.ImageOptions.html +18 -0
- package/docs/interfaces/five.ImageURLMappings.html +1 -0
- package/docs/interfaces/five.ImageURLOptions.html +17 -0
- package/docs/interfaces/five.IntersectMeshInterface.html +3 -0
- package/docs/interfaces/five.Intersection.html +7 -0
- package/docs/interfaces/five.MapviewControllerCustomInitArgs.html +15 -0
- package/docs/interfaces/five.ModelControllerCustomInitArgs.html +20 -0
- package/docs/interfaces/five.ModelEventCallback.html +22 -0
- package/docs/interfaces/five.MovePanoOptions.html +42 -0
- package/docs/interfaces/five.PBMPanoPicture.html +7 -0
- package/docs/interfaces/five.PBMParameters.html +17 -0
- package/docs/interfaces/five.PanoCircleMeshInterface.html +19 -0
- package/docs/interfaces/five.PanoramaControllerCustomInitArgs.html +28 -0
- package/docs/interfaces/five.PanoramaLikeControllerCustomInitArgs.html +20 -0
- package/docs/interfaces/five.Pose.html +37 -0
- package/docs/interfaces/five.Scissor.html +14 -0
- package/docs/interfaces/five.State.html +21 -0
- package/docs/interfaces/five.SubscribeMixinType.emit.html +1 -0
- package/docs/interfaces/five.SubscribeMixinType.hasListener.html +1 -0
- package/docs/interfaces/five.SubscribeMixinType.off.html +1 -0
- package/docs/interfaces/five.SubscribeMixinType.on.html +1 -0
- package/docs/interfaces/five.SubscribeMixinType.once.html +1 -0
- package/docs/interfaces/five.TextureOptions.html +20 -0
- package/docs/interfaces/five.TopviewControllerCustomInitArgs.html +7 -0
- package/docs/interfaces/five.VRPanoramaControllerCustomInitArgs.html +24 -0
- package/docs/interfaces/five.WorkCubeImage.html +13 -0
- package/docs/interfaces/five.WorkImage.html +21 -0
- package/docs/interfaces/five.WorkInitial.html +13 -0
- package/docs/interfaces/five.WorkModel.html +11 -0
- package/docs/interfaces/five.WorkModelTiles.html +3 -0
- package/docs/interfaces/five.WorkObserver.html +25 -0
- package/docs/interfaces/five.WorkTile.html +1 -0
- package/docs/interfaces/five.WorkVideo.html +9 -0
- package/docs/interfaces/gltf_loader.GLTF.html +7 -0
- package/docs/interfaces/react.FiveActionReactCallbacks.html +62 -0
- package/docs/interfaces/react.FiveInjectionTypes.html +191 -0
- package/docs/interfaces/react.PropTypeOfFiveFeatures.html +1 -0
- package/docs/interfaces/server.Intersection.html +7 -0
- package/docs/interfaces/server.ModelEventCallback.html +18 -0
- package/docs/interfaces/sticker.IntersectionLike.html +8 -0
- package/docs/interfaces/vue.FiveActionVueCallbacks.html +62 -0
- package/docs/modules/five.SubscribeMixinType.html +1 -0
- package/docs/modules/five.html +482 -0
- package/docs/modules/gltf_loader.html +1 -0
- package/docs/modules/line.html +1 -0
- package/docs/modules/react.html +130 -1178
- package/docs/modules/server.html +18 -0
- package/docs/modules/sticker.html +1 -0
- package/docs/modules/vue.html +112 -0
- package/docs/modules.html +1 -120
- package/exporters/staticify.js +210 -0
- package/{index.d.ts → five/index.d.ts} +1178 -322
- package/five/index.js +372 -0
- package/gltf-loader/index.d.ts +75 -0
- package/gltf-loader/index.js +260 -0
- package/line/index.d.ts +68 -0
- package/line/index.js +260 -0
- package/package.json +25 -17
- package/react/index.d.ts +160 -92
- package/react/index.js +260 -1
- package/resource/{basis_transcoder.js → basis/basis_transcoder.js} +0 -0
- package/resource/{basis_transcoder.wasm → basis/basis_transcoder.wasm} +0 -0
- package/resource/gltf/draco_decoder.js +31 -0
- package/resource/gltf/draco_decoder.wasm +0 -0
- package/resource/gltf/draco_wasm_wrapper.js +119 -0
- package/scripts/five-staticify.js +26 -0
- package/server/index.d.ts +194 -25
- package/server/index.js +367 -1
- package/sticker/index.d.ts +70 -0
- package/sticker/index.js +260 -0
- package/templates/quick-start/README.md +1 -1
- package/templates/quick-start/package.json +1 -1
- package/templates/react-component/lib/index.tsx +3 -3
- package/umd/five-gltf-loader.js +2 -0
- package/umd/five-gltf-loader.js.LICENSE.txt +14 -0
- package/umd/five-line.js +2 -0
- package/umd/five-line.js.LICENSE.txt +14 -0
- package/umd/five-react.js +2 -0
- package/umd/five-react.js.LICENSE.txt +14 -0
- package/umd/five-sticker.js +2 -0
- package/umd/five-sticker.js.LICENSE.txt +14 -0
- package/umd/five-vue.js +1 -0
- package/umd/five.js +2 -0
- package/umd/five.js.LICENSE.txt +116 -0
- package/vue/index.d.ts +433 -0
- package/vue/index.js +260 -0
- package/bundles/five.js +0 -2
- package/bundles/five.js.LICENSE.txt +0 -160
- package/docs/assets/css/main.css +0 -2660
- package/docs/assets/js/main.js +0 -248
- package/docs/assets/js/search.js +0 -1
- package/docs/classes/index.five.html +0 -2498
- package/docs/classes/index.fivecamera.html +0 -311
- package/docs/classes/index.fivehashcubetexture.html +0 -240
- package/docs/classes/index.fiveline.html +0 -342
- package/docs/classes/index.fivelinegeometry.html +0 -500
- package/docs/classes/index.fivelinematerial.html +0 -276
- package/docs/classes/index.fivelinesegmentsgeometry.html +0 -447
- package/docs/classes/index.fivescene.html +0 -186
- package/docs/classes/index.internalwebglrenderer.html +0 -200
- package/docs/classes/index.model.html +0 -883
- package/docs/classes/index.pbmgroup.html +0 -415
- package/docs/classes/index.pbmmaterial.html +0 -521
- package/docs/classes/index.pbmmesh.html +0 -242
- package/docs/classes/index.subscribe.html +0 -556
- package/docs/classes/react.store.html +0 -584
- package/docs/interfaces/index.depthpanoramacontrollercustominitargs.html +0 -408
- package/docs/interfaces/index.eventcallback.html +0 -2452
- package/docs/interfaces/index.fiveinitargs.html +0 -695
- package/docs/interfaces/index.floorplancontrollercustominitargs.html +0 -283
- package/docs/interfaces/index.imageoptions.html +0 -320
- package/docs/interfaces/index.intersection.html +0 -215
- package/docs/interfaces/index.intersectmeshinterface.html +0 -176
- package/docs/interfaces/index.modelcontrollercustominitargs.html +0 -354
- package/docs/interfaces/index.modeleventcallback.html +0 -316
- package/docs/interfaces/index.movepanooptions.html +0 -457
- package/docs/interfaces/index.panocirclemeshinterface.html +0 -349
- package/docs/interfaces/index.panoramacontrollercustominitargs.html +0 -433
- package/docs/interfaces/index.panoramalikecontrollercustominitargs.html +0 -352
- package/docs/interfaces/index.pbmparameters.html +0 -462
- package/docs/interfaces/index.pose.html +0 -258
- package/docs/interfaces/index.scissor.html +0 -240
- package/docs/interfaces/index.state.html +0 -288
- package/docs/interfaces/index.subscribemixintype.emit.html +0 -180
- package/docs/interfaces/index.subscribemixintype.haslistener.html +0 -171
- package/docs/interfaces/index.subscribemixintype.off.html +0 -198
- package/docs/interfaces/index.subscribemixintype.on.html +0 -213
- package/docs/interfaces/index.subscribemixintype.once.html +0 -210
- package/docs/interfaces/index.topviewcontrollercustominitargs.html +0 -214
- package/docs/interfaces/index.vrpanoramacontrollercustominitargs.html +0 -420
- package/docs/interfaces/react.fiveactionreactcallbacks.html +0 -559
- package/docs/interfaces/react.fiveinjectiontypes.html +0 -1473
- package/docs/interfaces/react.injectfivetoprops.html +0 -259
- package/docs/modules/index.html +0 -3027
- package/docs/modules/index.subscribemixintype.html +0 -143
- package/five.js.LICENSE.txt +0 -160
- package/index.js +0 -1
- package/scripts/export-five-resource/chfs.exe +0 -0
- package/scripts/export-five-resource/fileify.js +0 -192
- package/scripts/export-five-resource/format-work.js +0 -71
- package/scripts/export-five-resource/staticify.js +0 -327
- package/scripts/transcode-model/BufferGeometryUtils.js +0 -832
- package/scripts/transcode-model/LoaderSupport.js +0 -1545
- package/scripts/transcode-model/MTLLoader.js +0 -602
- package/scripts/transcode-model/OBJLoader2.js +0 -1470
- package/scripts/transcode-model/obj2pbm.js +0 -65
|
@@ -1,1470 +0,0 @@
|
|
|
1
|
-
var THREE = require('three')
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @author Kai Salmen / https://kaisalmen.de
|
|
5
|
-
* Development repository: https://github.com/kaisalmen/WWOBJLoader
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
if ( THREE.OBJLoader2 === undefined ) { THREE.OBJLoader2 = {} }
|
|
9
|
-
|
|
10
|
-
if ( THREE.LoaderSupport === undefined ) console.error( '"THREE.LoaderSupport" is not available. "THREE.OBJLoader2" requires it. Please include "LoaderSupport.js" in your HTML.' );
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Use this class to load OBJ data from files or to parse OBJ data from an arraybuffer
|
|
14
|
-
* @class
|
|
15
|
-
*
|
|
16
|
-
* @param {THREE.DefaultLoadingManager} [manager] The loadingManager for the loader to use. Default is {@link THREE.DefaultLoadingManager}
|
|
17
|
-
*/
|
|
18
|
-
THREE.OBJLoader2 = (function () {
|
|
19
|
-
|
|
20
|
-
var OBJLOADER2_VERSION = '2.4.2';
|
|
21
|
-
var Validator = THREE.LoaderSupport.Validator;
|
|
22
|
-
|
|
23
|
-
function OBJLoader2( manager ) {
|
|
24
|
-
// console.info( 'Using THREE.OBJLoader2 version: ' + OBJLOADER2_VERSION );
|
|
25
|
-
|
|
26
|
-
this.manager = Validator.verifyInput( manager, THREE.DefaultLoadingManager );
|
|
27
|
-
this.logging = {
|
|
28
|
-
enabled: true,
|
|
29
|
-
debug: false
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
this.modelName = '';
|
|
33
|
-
this.instanceNo = 0;
|
|
34
|
-
this.path = '';
|
|
35
|
-
this.resourcePath = '';
|
|
36
|
-
this.useIndices = false;
|
|
37
|
-
this.disregardNormals = false;
|
|
38
|
-
this.materialPerSmoothingGroup = false;
|
|
39
|
-
this.useOAsMesh = false;
|
|
40
|
-
this.loaderRootNode = new THREE.Group();
|
|
41
|
-
|
|
42
|
-
this.meshBuilder = new THREE.LoaderSupport.MeshBuilder();
|
|
43
|
-
this.callbacks = new THREE.LoaderSupport.Callbacks();
|
|
44
|
-
this.terminateWorkerOnLoad = true;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Enable or disable logging in general (except warn and error), plus enable or disable debug logging.
|
|
49
|
-
* @memberOf THREE.OBJLoader2
|
|
50
|
-
*
|
|
51
|
-
* @param {boolean} enabled True or false.
|
|
52
|
-
* @param {boolean} debug True or false.
|
|
53
|
-
*/
|
|
54
|
-
OBJLoader2.prototype.setLogging = function ( enabled, debug ) {
|
|
55
|
-
this.logging.enabled = enabled === true;
|
|
56
|
-
this.logging.debug = debug === true;
|
|
57
|
-
this.meshBuilder.setLogging( this.logging.enabled, this.logging.debug );
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Set the name of the model.
|
|
62
|
-
* @memberOf THREE.OBJLoader2
|
|
63
|
-
*
|
|
64
|
-
* @param {string} modelName
|
|
65
|
-
*/
|
|
66
|
-
OBJLoader2.prototype.setModelName = function ( modelName ) {
|
|
67
|
-
this.modelName = Validator.verifyInput( modelName, this.modelName );
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* The URL of the base path.
|
|
72
|
-
* @memberOf THREE.OBJLoader2
|
|
73
|
-
*
|
|
74
|
-
* @param {string} path URL
|
|
75
|
-
*/
|
|
76
|
-
OBJLoader2.prototype.setPath = function ( path ) {
|
|
77
|
-
this.path = Validator.verifyInput( path, this.path );
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* The URL of the resource path.
|
|
82
|
-
* @memberOf THREE.OBJLoader2
|
|
83
|
-
*
|
|
84
|
-
* @param {string} path URL
|
|
85
|
-
*/
|
|
86
|
-
OBJLoader2.prototype.setResourcePath = function ( resourcePath ) {
|
|
87
|
-
this.resourcePath = Validator.verifyInput( resourcePath, this.resourcePath );
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Set the node where the loaded objects will be attached directly.
|
|
92
|
-
* @memberOf THREE.OBJLoader2
|
|
93
|
-
*
|
|
94
|
-
* @param {THREE.Object3D} streamMeshesTo Object already attached to scenegraph where new meshes will be attached to
|
|
95
|
-
*/
|
|
96
|
-
OBJLoader2.prototype.setStreamMeshesTo = function ( streamMeshesTo ) {
|
|
97
|
-
this.loaderRootNode = Validator.verifyInput( streamMeshesTo, this.loaderRootNode );
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Set materials loaded by MTLLoader or any other supplier of an Array of {@link THREE.Material}.
|
|
102
|
-
* @memberOf THREE.OBJLoader2
|
|
103
|
-
*
|
|
104
|
-
* @param {THREE.Material[]} materials Array of {@link THREE.Material}
|
|
105
|
-
*/
|
|
106
|
-
OBJLoader2.prototype.setMaterials = function ( materials ) {
|
|
107
|
-
this.meshBuilder.setMaterials( materials );
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Instructs loaders to create indexed {@link THREE.BufferGeometry}.
|
|
112
|
-
* @memberOf THREE.OBJLoader2
|
|
113
|
-
*
|
|
114
|
-
* @param {boolean} useIndices=false
|
|
115
|
-
*/
|
|
116
|
-
OBJLoader2.prototype.setUseIndices = function ( useIndices ) {
|
|
117
|
-
this.useIndices = useIndices === true;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Tells whether normals should be completely disregarded and regenerated.
|
|
122
|
-
* @memberOf THREE.OBJLoader2
|
|
123
|
-
*
|
|
124
|
-
* @param {boolean} disregardNormals=false
|
|
125
|
-
*/
|
|
126
|
-
OBJLoader2.prototype.setDisregardNormals = function ( disregardNormals ) {
|
|
127
|
-
this.disregardNormals = disregardNormals === true;
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Tells whether a material shall be created per smoothing group.
|
|
132
|
-
* @memberOf THREE.OBJLoader2
|
|
133
|
-
*
|
|
134
|
-
* @param {boolean} materialPerSmoothingGroup=false
|
|
135
|
-
*/
|
|
136
|
-
OBJLoader2.prototype.setMaterialPerSmoothingGroup = function ( materialPerSmoothingGroup ) {
|
|
137
|
-
this.materialPerSmoothingGroup = materialPerSmoothingGroup === true;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Usually 'o' is meta-information and does not result in creation of new meshes, but mesh creation on occurrence of "o" can be enforced.
|
|
142
|
-
* @memberOf THREE.OBJLoader2
|
|
143
|
-
*
|
|
144
|
-
* @param {boolean} useOAsMesh=false
|
|
145
|
-
*/
|
|
146
|
-
OBJLoader2.prototype.setUseOAsMesh = function ( useOAsMesh ) {
|
|
147
|
-
this.useOAsMesh = useOAsMesh === true;
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
OBJLoader2.prototype._setCallbacks = function ( callbacks ) {
|
|
151
|
-
if ( Validator.isValid( callbacks.onProgress ) ) this.callbacks.setCallbackOnProgress( callbacks.onProgress );
|
|
152
|
-
if ( Validator.isValid( callbacks.onReportError ) ) this.callbacks.setCallbackOnReportError( callbacks.onReportError );
|
|
153
|
-
if ( Validator.isValid( callbacks.onMeshAlter ) ) this.callbacks.setCallbackOnMeshAlter( callbacks.onMeshAlter );
|
|
154
|
-
if ( Validator.isValid( callbacks.onLoad ) ) this.callbacks.setCallbackOnLoad( callbacks.onLoad );
|
|
155
|
-
if ( Validator.isValid( callbacks.onLoadMaterials ) ) this.callbacks.setCallbackOnLoadMaterials( callbacks.onLoadMaterials );
|
|
156
|
-
|
|
157
|
-
this.meshBuilder._setCallbacks( this.callbacks );
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Announce feedback which is give to the registered callbacks.
|
|
162
|
-
* @memberOf THREE.OBJLoader2
|
|
163
|
-
* @private
|
|
164
|
-
*
|
|
165
|
-
* @param {string} type The type of event
|
|
166
|
-
* @param {string} text Textual description of the event
|
|
167
|
-
* @param {number} numericalValue Numerical value describing the progress
|
|
168
|
-
*/
|
|
169
|
-
OBJLoader2.prototype.onProgress = function ( type, text, numericalValue ) {
|
|
170
|
-
var content = Validator.isValid( text ) ? text: '';
|
|
171
|
-
var event = {
|
|
172
|
-
detail: {
|
|
173
|
-
type: type,
|
|
174
|
-
modelName: this.modelName,
|
|
175
|
-
instanceNo: this.instanceNo,
|
|
176
|
-
text: content,
|
|
177
|
-
numericalValue: numericalValue
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
if ( Validator.isValid( this.callbacks.onProgress ) ) this.callbacks.onProgress( event );
|
|
182
|
-
|
|
183
|
-
if ( this.logging.enabled && this.logging.debug ) console.debug( content );
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
OBJLoader2.prototype._onError = function ( event ) {
|
|
187
|
-
var output = 'Error occurred while downloading!';
|
|
188
|
-
|
|
189
|
-
if ( event.currentTarget && event.currentTarget.statusText !== null ) {
|
|
190
|
-
|
|
191
|
-
output += '\nurl: ' + event.currentTarget.responseURL + '\nstatus: ' + event.currentTarget.statusText;
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
this.onProgress( 'error', output, -1 );
|
|
195
|
-
this._throwError( output );
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
OBJLoader2.prototype._throwError = function ( errorMessage ) {
|
|
199
|
-
if ( Validator.isValid( this.callbacks.onReportError ) ) {
|
|
200
|
-
|
|
201
|
-
this.callbacks.onReportError( errorMessage );
|
|
202
|
-
|
|
203
|
-
} else {
|
|
204
|
-
|
|
205
|
-
throw errorMessage;
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Use this convenient method to load a file at the given URL. By default the fileLoader uses an ArrayBuffer.
|
|
212
|
-
* @memberOf THREE.OBJLoader2
|
|
213
|
-
*
|
|
214
|
-
* @param {string} url A string containing the path/URL of the file to be loaded.
|
|
215
|
-
* @param {callback} onLoad A function to be called after loading is successfully completed. The function receives loaded Object3D as an argument.
|
|
216
|
-
* @param {callback} [onProgress] A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains total and Integer bytes.
|
|
217
|
-
* @param {callback} [onError] A function to be called if an error occurs during loading. The function receives the error as an argument.
|
|
218
|
-
* @param {callback} [onMeshAlter] A function to be called after a new mesh raw data becomes available for alteration.
|
|
219
|
-
* @param {boolean} [useAsync] If true, uses async loading with worker, if false loads data synchronously.
|
|
220
|
-
*/
|
|
221
|
-
OBJLoader2.prototype.load = function ( url, onLoad, onProgress, onError, onMeshAlter, useAsync ) {
|
|
222
|
-
var resource = new THREE.LoaderSupport.ResourceDescriptor( url, 'OBJ' );
|
|
223
|
-
this._loadObj( resource, onLoad, onProgress, onError, onMeshAlter, useAsync );
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
OBJLoader2.prototype._loadObj = function ( resource, onLoad, onProgress, onError, onMeshAlter, useAsync ) {
|
|
227
|
-
var scope = this;
|
|
228
|
-
if ( ! Validator.isValid( onError ) ) {
|
|
229
|
-
onError = function ( event ) {
|
|
230
|
-
scope._onError( event );
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// fast-fail
|
|
235
|
-
if ( ! Validator.isValid( resource ) ) onError( 'An invalid ResourceDescriptor was provided. Unable to continue!' );
|
|
236
|
-
var fileLoaderOnLoad = function ( content ) {
|
|
237
|
-
|
|
238
|
-
resource.content = content;
|
|
239
|
-
if ( useAsync ) {
|
|
240
|
-
|
|
241
|
-
scope.parseAsync( content, onLoad );
|
|
242
|
-
|
|
243
|
-
} else {
|
|
244
|
-
|
|
245
|
-
var callbacks = new THREE.LoaderSupport.Callbacks();
|
|
246
|
-
callbacks.setCallbackOnMeshAlter( onMeshAlter );
|
|
247
|
-
scope._setCallbacks( callbacks );
|
|
248
|
-
onLoad(
|
|
249
|
-
{
|
|
250
|
-
detail: {
|
|
251
|
-
loaderRootNode: scope.parse( content ),
|
|
252
|
-
modelName: scope.modelName,
|
|
253
|
-
instanceNo: scope.instanceNo
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
// fast-fail
|
|
262
|
-
if ( ! Validator.isValid( resource.url ) || Validator.isValid( resource.content ) ) {
|
|
263
|
-
|
|
264
|
-
fileLoaderOnLoad( Validator.isValid( resource.content ) ? resource.content : null );
|
|
265
|
-
|
|
266
|
-
} else {
|
|
267
|
-
|
|
268
|
-
if ( ! Validator.isValid( onProgress ) ) {
|
|
269
|
-
var numericalValueRef = 0;
|
|
270
|
-
var numericalValue = 0;
|
|
271
|
-
onProgress = function ( event ) {
|
|
272
|
-
if ( ! event.lengthComputable ) return;
|
|
273
|
-
|
|
274
|
-
numericalValue = event.loaded / event.total;
|
|
275
|
-
if ( numericalValue > numericalValueRef ) {
|
|
276
|
-
|
|
277
|
-
numericalValueRef = numericalValue;
|
|
278
|
-
var output = 'Download of "' + resource.url + '": ' + ( numericalValue * 100 ).toFixed( 2 ) + '%';
|
|
279
|
-
scope.onProgress( 'progressLoad', output, numericalValue );
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
var fileLoader = new THREE.FileLoader( this.manager );
|
|
287
|
-
fileLoader.setPath( this.path );
|
|
288
|
-
fileLoader.setResponseType( 'arraybuffer' );
|
|
289
|
-
fileLoader.load( resource.url, fileLoaderOnLoad, onProgress, onError );
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Run the loader according the provided instructions.
|
|
297
|
-
* @memberOf THREE.OBJLoader2
|
|
298
|
-
*
|
|
299
|
-
* @param {THREE.LoaderSupport.PrepData} prepData All parameters and resources required for execution
|
|
300
|
-
* @param {THREE.LoaderSupport.WorkerSupport} [workerSupportExternal] Use pre-existing WorkerSupport
|
|
301
|
-
*/
|
|
302
|
-
OBJLoader2.prototype.run = function ( prepData, workerSupportExternal ) {
|
|
303
|
-
this._applyPrepData( prepData );
|
|
304
|
-
var available = prepData.checkResourceDescriptorFiles( prepData.resources,
|
|
305
|
-
[
|
|
306
|
-
{ ext: "obj", type: "ArrayBuffer", ignore: false },
|
|
307
|
-
{ ext: "mtl", type: "String", ignore: false },
|
|
308
|
-
{ ext: "zip", type: "String", ignore: true }
|
|
309
|
-
]
|
|
310
|
-
);
|
|
311
|
-
if ( Validator.isValid( workerSupportExternal ) ) {
|
|
312
|
-
|
|
313
|
-
this.terminateWorkerOnLoad = false;
|
|
314
|
-
this.workerSupport = workerSupportExternal;
|
|
315
|
-
this.logging.enabled = this.workerSupport.logging.enabled;
|
|
316
|
-
this.logging.debug = this.workerSupport.logging.debug;
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
var scope = this;
|
|
320
|
-
var onMaterialsLoaded = function ( materials ) {
|
|
321
|
-
if ( materials !== null ) scope.meshBuilder.setMaterials( materials );
|
|
322
|
-
scope._loadObj( available.obj, scope.callbacks.onLoad, null, null, scope.callbacks.onMeshAlter, prepData.useAsync );
|
|
323
|
-
|
|
324
|
-
};
|
|
325
|
-
this._loadMtl( available.mtl, onMaterialsLoaded, null, null, prepData.crossOrigin, prepData.materialOptions );
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
OBJLoader2.prototype._applyPrepData = function ( prepData ) {
|
|
329
|
-
if ( Validator.isValid( prepData ) ) {
|
|
330
|
-
|
|
331
|
-
this.setLogging( prepData.logging.enabled, prepData.logging.debug );
|
|
332
|
-
this.setModelName( prepData.modelName );
|
|
333
|
-
this.setStreamMeshesTo( prepData.streamMeshesTo );
|
|
334
|
-
this.meshBuilder.setMaterials( prepData.materials );
|
|
335
|
-
this.setUseIndices( prepData.useIndices );
|
|
336
|
-
this.setDisregardNormals( prepData.disregardNormals );
|
|
337
|
-
this.setMaterialPerSmoothingGroup( prepData.materialPerSmoothingGroup );
|
|
338
|
-
this.setUseOAsMesh( prepData.useOAsMesh );
|
|
339
|
-
|
|
340
|
-
this._setCallbacks( prepData.getCallbacks() );
|
|
341
|
-
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Parses OBJ data synchronously from arraybuffer or string.
|
|
347
|
-
* @memberOf THREE.OBJLoader2
|
|
348
|
-
*
|
|
349
|
-
* @param {arraybuffer|string} content OBJ data as Uint8Array or String
|
|
350
|
-
*/
|
|
351
|
-
OBJLoader2.prototype.parse = function ( content ) {
|
|
352
|
-
// fast-fail in case of illegal data
|
|
353
|
-
if ( ! Validator.isValid( content ) ) {
|
|
354
|
-
|
|
355
|
-
console.warn( 'Provided content is not a valid ArrayBuffer or String.' );
|
|
356
|
-
return this.loaderRootNode;
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
if ( this.logging.enabled ) console.time( 'OBJLoader2 parse: ' + this.modelName );
|
|
360
|
-
this.meshBuilder.init();
|
|
361
|
-
|
|
362
|
-
var parser = new Parser();
|
|
363
|
-
parser.setLogging( this.logging.enabled, this.logging.debug );
|
|
364
|
-
parser.setMaterialPerSmoothingGroup( this.materialPerSmoothingGroup );
|
|
365
|
-
parser.setUseOAsMesh( this.useOAsMesh );
|
|
366
|
-
parser.setUseIndices( this.useIndices );
|
|
367
|
-
parser.setDisregardNormals( this.disregardNormals );
|
|
368
|
-
// sync code works directly on the material references
|
|
369
|
-
parser.setMaterials( this.meshBuilder.getMaterials() );
|
|
370
|
-
|
|
371
|
-
var scope = this;
|
|
372
|
-
var onMeshLoaded = function ( payload ) {
|
|
373
|
-
var meshes = scope.meshBuilder.processPayload( payload );
|
|
374
|
-
var mesh;
|
|
375
|
-
for ( var i in meshes ) {
|
|
376
|
-
mesh = meshes[ i ];
|
|
377
|
-
scope.loaderRootNode.add( mesh );
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
parser.setCallbackMeshBuilder( onMeshLoaded );
|
|
381
|
-
var onProgressScoped = function ( text, numericalValue ) {
|
|
382
|
-
scope.onProgress( 'progressParse', text, numericalValue );
|
|
383
|
-
};
|
|
384
|
-
parser.setCallbackProgress( onProgressScoped );
|
|
385
|
-
|
|
386
|
-
if ( content instanceof ArrayBuffer || content instanceof Uint8Array ) {
|
|
387
|
-
|
|
388
|
-
if ( this.logging.enabled ) console.info( 'Parsing arrayBuffer...' );
|
|
389
|
-
parser.parse( content );
|
|
390
|
-
|
|
391
|
-
} else if ( typeof( content ) === 'string' || content instanceof String ) {
|
|
392
|
-
|
|
393
|
-
if ( this.logging.enabled ) console.info( 'Parsing text...' );
|
|
394
|
-
parser.parseText( content );
|
|
395
|
-
|
|
396
|
-
} else {
|
|
397
|
-
|
|
398
|
-
this._throwError( 'Provided content was neither of type String nor Uint8Array! Aborting...' );
|
|
399
|
-
|
|
400
|
-
}
|
|
401
|
-
if ( this.logging.enabled ) console.timeEnd( 'OBJLoader2 parse: ' + this.modelName );
|
|
402
|
-
|
|
403
|
-
return this.loaderRootNode;
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Parses OBJ content asynchronously from arraybuffer.
|
|
408
|
-
* @memberOf THREE.OBJLoader2
|
|
409
|
-
*
|
|
410
|
-
* @param {arraybuffer} content OBJ data as Uint8Array
|
|
411
|
-
* @param {callback} onLoad Called after worker successfully completed loading
|
|
412
|
-
*/
|
|
413
|
-
OBJLoader2.prototype.parseAsync = function ( content, onLoad ) {
|
|
414
|
-
|
|
415
|
-
this.workerSupport = this.workerSupport || new THREE.LoaderSupport.WorkerSupport();
|
|
416
|
-
|
|
417
|
-
var scope = this;
|
|
418
|
-
var measureTime = false;
|
|
419
|
-
var scopedOnLoad = function () {
|
|
420
|
-
onLoad(
|
|
421
|
-
{
|
|
422
|
-
detail: {
|
|
423
|
-
loaderRootNode: scope.loaderRootNode,
|
|
424
|
-
modelName: scope.modelName,
|
|
425
|
-
instanceNo: scope.instanceNo
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
);
|
|
429
|
-
if ( measureTime && scope.logging.enabled ) console.timeEnd( 'OBJLoader2 parseAsync: ' + scope.modelName );
|
|
430
|
-
};
|
|
431
|
-
// fast-fail in case of illegal data
|
|
432
|
-
if ( ! Validator.isValid( content ) ) {
|
|
433
|
-
|
|
434
|
-
console.warn( 'Provided content is not a valid ArrayBuffer.' );
|
|
435
|
-
scopedOnLoad();
|
|
436
|
-
|
|
437
|
-
} else {
|
|
438
|
-
|
|
439
|
-
measureTime = true;
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
if ( measureTime && this.logging.enabled ) console.time( 'OBJLoader2 parseAsync: ' + this.modelName );
|
|
443
|
-
this.meshBuilder.init();
|
|
444
|
-
|
|
445
|
-
var scopedOnMeshLoaded = function ( payload ) {
|
|
446
|
-
var meshes = scope.meshBuilder.processPayload( payload );
|
|
447
|
-
var mesh;
|
|
448
|
-
for ( var i in meshes ) {
|
|
449
|
-
mesh = meshes[ i ];
|
|
450
|
-
scope.loaderRootNode.add( mesh );
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
var buildCode = function ( funcBuildObject, funcBuildSingleton ) {
|
|
454
|
-
var workerCode = '';
|
|
455
|
-
workerCode += '/**\n';
|
|
456
|
-
workerCode += ' * This code was constructed by OBJLoader2 buildCode.\n';
|
|
457
|
-
workerCode += ' */\n\n';
|
|
458
|
-
workerCode += 'THREE = { LoaderSupport: {} };\n\n';
|
|
459
|
-
workerCode += funcBuildObject( 'THREE.LoaderSupport.Validator', Validator );
|
|
460
|
-
workerCode += funcBuildSingleton( 'Parser', Parser );
|
|
461
|
-
|
|
462
|
-
return workerCode;
|
|
463
|
-
};
|
|
464
|
-
this.workerSupport.validate( buildCode, 'Parser' );
|
|
465
|
-
this.workerSupport.setCallbacks( scopedOnMeshLoaded, scopedOnLoad );
|
|
466
|
-
if ( scope.terminateWorkerOnLoad ) this.workerSupport.setTerminateRequested( true );
|
|
467
|
-
|
|
468
|
-
var materialNames = {};
|
|
469
|
-
var materials = this.meshBuilder.getMaterials();
|
|
470
|
-
for ( var materialName in materials ) {
|
|
471
|
-
|
|
472
|
-
materialNames[ materialName ] = materialName;
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
this.workerSupport.run(
|
|
476
|
-
{
|
|
477
|
-
params: {
|
|
478
|
-
useAsync: true,
|
|
479
|
-
materialPerSmoothingGroup: this.materialPerSmoothingGroup,
|
|
480
|
-
useOAsMesh: this.useOAsMesh,
|
|
481
|
-
useIndices: this.useIndices,
|
|
482
|
-
disregardNormals: this.disregardNormals
|
|
483
|
-
},
|
|
484
|
-
logging: {
|
|
485
|
-
enabled: this.logging.enabled,
|
|
486
|
-
debug: this.logging.debug
|
|
487
|
-
},
|
|
488
|
-
materials: {
|
|
489
|
-
// in async case only material names are supplied to parser
|
|
490
|
-
materials: materialNames
|
|
491
|
-
},
|
|
492
|
-
data: {
|
|
493
|
-
input: content,
|
|
494
|
-
options: null
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
);
|
|
498
|
-
};
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Parse OBJ data either from ArrayBuffer or string
|
|
503
|
-
* @class
|
|
504
|
-
*/
|
|
505
|
-
var Parser = (function () {
|
|
506
|
-
|
|
507
|
-
function Parser() {
|
|
508
|
-
this.callbackProgress = null;
|
|
509
|
-
this.callbackMeshBuilder = null;
|
|
510
|
-
this.contentRef = null;
|
|
511
|
-
this.legacyMode = false;
|
|
512
|
-
|
|
513
|
-
this.materials = {};
|
|
514
|
-
this.useAsync = false;
|
|
515
|
-
this.materialPerSmoothingGroup = false;
|
|
516
|
-
this.useOAsMesh = false;
|
|
517
|
-
this.useIndices = false;
|
|
518
|
-
this.disregardNormals = false;
|
|
519
|
-
|
|
520
|
-
this.vertices = [];
|
|
521
|
-
this.colors = [];
|
|
522
|
-
this.normals = [];
|
|
523
|
-
this.uvs = [];
|
|
524
|
-
|
|
525
|
-
this.rawMesh = {
|
|
526
|
-
objectName: '',
|
|
527
|
-
groupName: '',
|
|
528
|
-
activeMtlName: '',
|
|
529
|
-
mtllibName: '',
|
|
530
|
-
|
|
531
|
-
// reset with new mesh
|
|
532
|
-
faceType: -1,
|
|
533
|
-
subGroups: [],
|
|
534
|
-
subGroupInUse: null,
|
|
535
|
-
smoothingGroup: {
|
|
536
|
-
splitMaterials: false,
|
|
537
|
-
normalized: -1,
|
|
538
|
-
real: -1
|
|
539
|
-
},
|
|
540
|
-
counts: {
|
|
541
|
-
doubleIndicesCount: 0,
|
|
542
|
-
faceCount: 0,
|
|
543
|
-
mtlCount: 0,
|
|
544
|
-
smoothingGroupCount: 0
|
|
545
|
-
}
|
|
546
|
-
};
|
|
547
|
-
|
|
548
|
-
this.inputObjectCount = 1;
|
|
549
|
-
this.outputObjectCount = 1;
|
|
550
|
-
this.globalCounts = {
|
|
551
|
-
vertices: 0,
|
|
552
|
-
faces: 0,
|
|
553
|
-
doubleIndicesCount: 0,
|
|
554
|
-
lineByte: 0,
|
|
555
|
-
currentByte: 0,
|
|
556
|
-
totalBytes: 0
|
|
557
|
-
};
|
|
558
|
-
|
|
559
|
-
this.logging = {
|
|
560
|
-
enabled: true,
|
|
561
|
-
debug: false
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
Parser.prototype.resetRawMesh = function () {
|
|
566
|
-
// faces are stored according combined index of group, material and smoothingGroup (0 or not)
|
|
567
|
-
this.rawMesh.subGroups = [];
|
|
568
|
-
this.rawMesh.subGroupInUse = null;
|
|
569
|
-
this.rawMesh.smoothingGroup.normalized = -1;
|
|
570
|
-
this.rawMesh.smoothingGroup.real = -1;
|
|
571
|
-
|
|
572
|
-
// this default index is required as it is possible to define faces without 'g' or 'usemtl'
|
|
573
|
-
this.pushSmoothingGroup( 1 );
|
|
574
|
-
|
|
575
|
-
this.rawMesh.counts.doubleIndicesCount = 0;
|
|
576
|
-
this.rawMesh.counts.faceCount = 0;
|
|
577
|
-
this.rawMesh.counts.mtlCount = 0;
|
|
578
|
-
this.rawMesh.counts.smoothingGroupCount = 0;
|
|
579
|
-
};
|
|
580
|
-
|
|
581
|
-
Parser.prototype.setUseAsync = function ( useAsync ) {
|
|
582
|
-
this.useAsync = useAsync;
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
Parser.prototype.setMaterialPerSmoothingGroup = function ( materialPerSmoothingGroup ) {
|
|
586
|
-
this.materialPerSmoothingGroup = materialPerSmoothingGroup;
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
Parser.prototype.setUseOAsMesh = function ( useOAsMesh ) {
|
|
590
|
-
this.useOAsMesh = useOAsMesh;
|
|
591
|
-
};
|
|
592
|
-
|
|
593
|
-
Parser.prototype.setUseIndices = function ( useIndices ) {
|
|
594
|
-
this.useIndices = useIndices;
|
|
595
|
-
};
|
|
596
|
-
|
|
597
|
-
Parser.prototype.setDisregardNormals = function ( disregardNormals ) {
|
|
598
|
-
this.disregardNormals = disregardNormals;
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
Parser.prototype.setMaterials = function ( materials ) {
|
|
602
|
-
this.materials = THREE.LoaderSupport.Validator.verifyInput( materials, this.materials );
|
|
603
|
-
this.materials = THREE.LoaderSupport.Validator.verifyInput( this.materials, {} );
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
Parser.prototype.setCallbackMeshBuilder = function ( callbackMeshBuilder ) {
|
|
607
|
-
if ( ! THREE.LoaderSupport.Validator.isValid( callbackMeshBuilder ) ) {
|
|
608
|
-
|
|
609
|
-
this._throwError( 'Unable to run as no "MeshBuilder" callback is set.' );
|
|
610
|
-
|
|
611
|
-
}
|
|
612
|
-
this.callbackMeshBuilder = callbackMeshBuilder;
|
|
613
|
-
};
|
|
614
|
-
|
|
615
|
-
Parser.prototype.setCallbackProgress = function ( callbackProgress ) {
|
|
616
|
-
this.callbackProgress = callbackProgress;
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
Parser.prototype.setLogging = function ( enabled, debug ) {
|
|
620
|
-
this.logging.enabled = enabled === true;
|
|
621
|
-
this.logging.debug = debug === true;
|
|
622
|
-
};
|
|
623
|
-
|
|
624
|
-
Parser.prototype.configure = function () {
|
|
625
|
-
this.pushSmoothingGroup( 1 );
|
|
626
|
-
|
|
627
|
-
if ( this.logging.enabled ) {
|
|
628
|
-
|
|
629
|
-
var matKeys = Object.keys( this.materials );
|
|
630
|
-
var matNames = ( matKeys.length > 0 ) ? '\n\tmaterialNames:\n\t\t- ' + matKeys.join( '\n\t\t- ' ) : '\n\tmaterialNames: None';
|
|
631
|
-
var printedConfig = 'OBJLoader2.Parser configuration:'
|
|
632
|
-
+ matNames
|
|
633
|
-
+ '\n\tuseAsync: ' + this.useAsync
|
|
634
|
-
+ '\n\tmaterialPerSmoothingGroup: ' + this.materialPerSmoothingGroup
|
|
635
|
-
+ '\n\tuseOAsMesh: ' + this.useOAsMesh
|
|
636
|
-
+ '\n\tuseIndices: ' + this.useIndices
|
|
637
|
-
+ '\n\tdisregardNormals: ' + this.disregardNormals
|
|
638
|
-
+ '\n\tcallbackMeshBuilderName: ' + this.callbackMeshBuilder.name
|
|
639
|
-
+ '\n\tcallbackProgressName: ' + this.callbackProgress.name;
|
|
640
|
-
console.info( printedConfig );
|
|
641
|
-
}
|
|
642
|
-
};
|
|
643
|
-
|
|
644
|
-
/**
|
|
645
|
-
* Parse the provided arraybuffer
|
|
646
|
-
* @memberOf Parser
|
|
647
|
-
*
|
|
648
|
-
* @param {Uint8Array} arrayBuffer OBJ data as Uint8Array
|
|
649
|
-
*/
|
|
650
|
-
Parser.prototype.parse = function ( arrayBuffer ) {
|
|
651
|
-
if ( this.logging.enabled ) console.time( 'OBJLoader2.Parser.parse' );
|
|
652
|
-
this.configure();
|
|
653
|
-
|
|
654
|
-
var arrayBufferView = new Uint8Array( arrayBuffer );
|
|
655
|
-
this.contentRef = arrayBufferView;
|
|
656
|
-
var length = arrayBufferView.byteLength;
|
|
657
|
-
this.globalCounts.totalBytes = length;
|
|
658
|
-
var buffer = new Array( 128 );
|
|
659
|
-
|
|
660
|
-
for ( var code, word = '', bufferPointer = 0, slashesCount = 0, i = 0; i < length; i++ ) {
|
|
661
|
-
|
|
662
|
-
code = arrayBufferView[ i ];
|
|
663
|
-
switch ( code ) {
|
|
664
|
-
// space
|
|
665
|
-
case 32:
|
|
666
|
-
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
|
|
667
|
-
word = '';
|
|
668
|
-
break;
|
|
669
|
-
// slash
|
|
670
|
-
case 47:
|
|
671
|
-
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
|
|
672
|
-
slashesCount++;
|
|
673
|
-
word = '';
|
|
674
|
-
break;
|
|
675
|
-
|
|
676
|
-
// LF
|
|
677
|
-
case 10:
|
|
678
|
-
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
|
|
679
|
-
word = '';
|
|
680
|
-
this.globalCounts.lineByte = this.globalCounts.currentByte;
|
|
681
|
-
this.globalCounts.currentByte = i;
|
|
682
|
-
this.processLine( buffer, bufferPointer, slashesCount );
|
|
683
|
-
bufferPointer = 0;
|
|
684
|
-
slashesCount = 0;
|
|
685
|
-
break;
|
|
686
|
-
|
|
687
|
-
// CR
|
|
688
|
-
case 13:
|
|
689
|
-
break;
|
|
690
|
-
|
|
691
|
-
default:
|
|
692
|
-
word += String.fromCharCode( code );
|
|
693
|
-
break;
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
this.finalizeParsing();
|
|
697
|
-
if ( this.logging.enabled ) console.timeEnd( 'OBJLoader2.Parser.parse' );
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
/**
|
|
701
|
-
* Parse the provided text
|
|
702
|
-
* @memberOf Parser
|
|
703
|
-
*
|
|
704
|
-
* @param {string} text OBJ data as string
|
|
705
|
-
*/
|
|
706
|
-
Parser.prototype.parseText = function ( text ) {
|
|
707
|
-
if ( this.logging.enabled ) console.time( 'OBJLoader2.Parser.parseText' );
|
|
708
|
-
this.configure();
|
|
709
|
-
this.legacyMode = true;
|
|
710
|
-
this.contentRef = text;
|
|
711
|
-
var length = text.length;
|
|
712
|
-
this.globalCounts.totalBytes = length;
|
|
713
|
-
var buffer = new Array( 128 );
|
|
714
|
-
|
|
715
|
-
for ( var char, word = '', bufferPointer = 0, slashesCount = 0, i = 0; i < length; i++ ) {
|
|
716
|
-
|
|
717
|
-
char = text[ i ];
|
|
718
|
-
switch ( char ) {
|
|
719
|
-
case ' ':
|
|
720
|
-
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
|
|
721
|
-
word = '';
|
|
722
|
-
break;
|
|
723
|
-
|
|
724
|
-
case '/':
|
|
725
|
-
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
|
|
726
|
-
slashesCount++;
|
|
727
|
-
word = '';
|
|
728
|
-
break;
|
|
729
|
-
|
|
730
|
-
case '\n':
|
|
731
|
-
if ( word.length > 0 ) buffer[ bufferPointer++ ] = word;
|
|
732
|
-
word = '';
|
|
733
|
-
this.globalCounts.lineByte = this.globalCounts.currentByte;
|
|
734
|
-
this.globalCounts.currentByte = i;
|
|
735
|
-
this.processLine( buffer, bufferPointer, slashesCount );
|
|
736
|
-
bufferPointer = 0;
|
|
737
|
-
slashesCount = 0;
|
|
738
|
-
break;
|
|
739
|
-
|
|
740
|
-
case '\r':
|
|
741
|
-
break;
|
|
742
|
-
|
|
743
|
-
default:
|
|
744
|
-
word += char;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
this.finalizeParsing();
|
|
748
|
-
if ( this.logging.enabled ) console.timeEnd( 'OBJLoader2.Parser.parseText' );
|
|
749
|
-
};
|
|
750
|
-
|
|
751
|
-
Parser.prototype.processLine = function ( buffer, bufferPointer, slashesCount ) {
|
|
752
|
-
if ( bufferPointer < 1 ) return;
|
|
753
|
-
|
|
754
|
-
var reconstructString = function ( content, legacyMode, start, stop ) {
|
|
755
|
-
var line = '';
|
|
756
|
-
if ( stop > start ) {
|
|
757
|
-
|
|
758
|
-
var i;
|
|
759
|
-
if ( legacyMode ) {
|
|
760
|
-
|
|
761
|
-
for ( i = start; i < stop; i++ ) line += content[ i ];
|
|
762
|
-
|
|
763
|
-
} else {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
for ( i = start; i < stop; i++ ) line += String.fromCharCode( content[ i ] );
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
line = line.trim();
|
|
770
|
-
|
|
771
|
-
}
|
|
772
|
-
return line;
|
|
773
|
-
};
|
|
774
|
-
|
|
775
|
-
var bufferLength, length, i, lineDesignation;
|
|
776
|
-
lineDesignation = buffer [ 0 ];
|
|
777
|
-
switch ( lineDesignation ) {
|
|
778
|
-
case 'v':
|
|
779
|
-
this.vertices.push( parseFloat( buffer[ 1 ] ) );
|
|
780
|
-
this.vertices.push( parseFloat( buffer[ 2 ] ) );
|
|
781
|
-
this.vertices.push( parseFloat( buffer[ 3 ] ) );
|
|
782
|
-
if ( bufferPointer > 4 ) {
|
|
783
|
-
|
|
784
|
-
this.colors.push( parseFloat( buffer[ 4 ] ) );
|
|
785
|
-
this.colors.push( parseFloat( buffer[ 5 ] ) );
|
|
786
|
-
this.colors.push( parseFloat( buffer[ 6 ] ) );
|
|
787
|
-
|
|
788
|
-
}
|
|
789
|
-
break;
|
|
790
|
-
|
|
791
|
-
case 'vt':
|
|
792
|
-
this.uvs.push( parseFloat( buffer[ 1 ] ) );
|
|
793
|
-
this.uvs.push( parseFloat( buffer[ 2 ] ) );
|
|
794
|
-
break;
|
|
795
|
-
|
|
796
|
-
case 'vn':
|
|
797
|
-
this.normals.push( parseFloat( buffer[ 1 ] ) );
|
|
798
|
-
this.normals.push( parseFloat( buffer[ 2 ] ) );
|
|
799
|
-
this.normals.push( parseFloat( buffer[ 3 ] ) );
|
|
800
|
-
break;
|
|
801
|
-
|
|
802
|
-
case 'f':
|
|
803
|
-
bufferLength = bufferPointer - 1;
|
|
804
|
-
|
|
805
|
-
// "f vertex ..."
|
|
806
|
-
if ( slashesCount === 0 ) {
|
|
807
|
-
|
|
808
|
-
this.checkFaceType( 0 );
|
|
809
|
-
for ( i = 2, length = bufferLength; i < length; i ++ ) {
|
|
810
|
-
|
|
811
|
-
this.buildFace( buffer[ 1 ] );
|
|
812
|
-
this.buildFace( buffer[ i ] );
|
|
813
|
-
this.buildFace( buffer[ i + 1 ] );
|
|
814
|
-
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
// "f vertex/uv ..."
|
|
818
|
-
} else if ( bufferLength === slashesCount * 2 ) {
|
|
819
|
-
|
|
820
|
-
this.checkFaceType( 1 );
|
|
821
|
-
for ( i = 3, length = bufferLength - 2; i < length; i += 2 ) {
|
|
822
|
-
|
|
823
|
-
this.buildFace( buffer[ 1 ], buffer[ 2 ] );
|
|
824
|
-
this.buildFace( buffer[ i ], buffer[ i + 1 ] );
|
|
825
|
-
this.buildFace( buffer[ i + 2 ], buffer[ i + 3 ] );
|
|
826
|
-
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
// "f vertex/uv/normal ..."
|
|
830
|
-
} else if ( bufferLength * 2 === slashesCount * 3 ) {
|
|
831
|
-
|
|
832
|
-
this.checkFaceType( 2 );
|
|
833
|
-
for ( i = 4, length = bufferLength - 3; i < length; i += 3 ) {
|
|
834
|
-
|
|
835
|
-
this.buildFace( buffer[ 1 ], buffer[ 2 ], buffer[ 3 ] );
|
|
836
|
-
this.buildFace( buffer[ i ], buffer[ i + 1 ], buffer[ i + 2 ] );
|
|
837
|
-
this.buildFace( buffer[ i + 3 ], buffer[ i + 4 ], buffer[ i + 5 ] );
|
|
838
|
-
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
// "f vertex//normal ..."
|
|
842
|
-
} else {
|
|
843
|
-
|
|
844
|
-
this.checkFaceType( 3 );
|
|
845
|
-
for ( i = 3, length = bufferLength - 2; i < length; i += 2 ) {
|
|
846
|
-
|
|
847
|
-
this.buildFace( buffer[ 1 ], undefined, buffer[ 2 ] );
|
|
848
|
-
this.buildFace( buffer[ i ], undefined, buffer[ i + 1 ] );
|
|
849
|
-
this.buildFace( buffer[ i + 2 ], undefined, buffer[ i + 3 ] );
|
|
850
|
-
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
}
|
|
854
|
-
break;
|
|
855
|
-
|
|
856
|
-
case 'l':
|
|
857
|
-
case 'p':
|
|
858
|
-
bufferLength = bufferPointer - 1;
|
|
859
|
-
if ( bufferLength === slashesCount * 2 ) {
|
|
860
|
-
|
|
861
|
-
this.checkFaceType( 4 );
|
|
862
|
-
for ( i = 1, length = bufferLength + 1; i < length; i += 2 ) this.buildFace( buffer[ i ], buffer[ i + 1 ] );
|
|
863
|
-
|
|
864
|
-
} else {
|
|
865
|
-
|
|
866
|
-
this.checkFaceType( ( lineDesignation === 'l' ) ? 5 : 6 );
|
|
867
|
-
for ( i = 1, length = bufferLength + 1; i < length; i ++ ) this.buildFace( buffer[ i ] );
|
|
868
|
-
|
|
869
|
-
}
|
|
870
|
-
break;
|
|
871
|
-
|
|
872
|
-
case 's':
|
|
873
|
-
this.pushSmoothingGroup( buffer[ 1 ] );
|
|
874
|
-
break;
|
|
875
|
-
|
|
876
|
-
case 'g':
|
|
877
|
-
// 'g' leads to creation of mesh if valid data (faces declaration was done before), otherwise only groupName gets set
|
|
878
|
-
this.processCompletedMesh();
|
|
879
|
-
this.rawMesh.groupName = reconstructString( this.contentRef, this.legacyMode, this.globalCounts.lineByte + 2, this.globalCounts.currentByte );
|
|
880
|
-
break;
|
|
881
|
-
|
|
882
|
-
case 'o':
|
|
883
|
-
// 'o' is meta-information and usually does not result in creation of new meshes, but can be enforced with "useOAsMesh"
|
|
884
|
-
if ( this.useOAsMesh ) this.processCompletedMesh();
|
|
885
|
-
this.rawMesh.objectName = reconstructString( this.contentRef, this.legacyMode, this.globalCounts.lineByte + 2, this.globalCounts.currentByte );
|
|
886
|
-
break;
|
|
887
|
-
|
|
888
|
-
case 'mtllib':
|
|
889
|
-
this.rawMesh.mtllibName = reconstructString( this.contentRef, this.legacyMode, this.globalCounts.lineByte + 7, this.globalCounts.currentByte );
|
|
890
|
-
break;
|
|
891
|
-
|
|
892
|
-
case 'usemtl':
|
|
893
|
-
var mtlName = reconstructString( this.contentRef, this.legacyMode, this.globalCounts.lineByte + 7, this.globalCounts.currentByte );
|
|
894
|
-
if ( mtlName !== '' && this.rawMesh.activeMtlName !== mtlName ) {
|
|
895
|
-
|
|
896
|
-
this.rawMesh.activeMtlName = mtlName;
|
|
897
|
-
this.rawMesh.counts.mtlCount++;
|
|
898
|
-
this.checkSubGroup();
|
|
899
|
-
|
|
900
|
-
}
|
|
901
|
-
break;
|
|
902
|
-
|
|
903
|
-
default:
|
|
904
|
-
break;
|
|
905
|
-
}
|
|
906
|
-
};
|
|
907
|
-
|
|
908
|
-
Parser.prototype.pushSmoothingGroup = function ( smoothingGroup ) {
|
|
909
|
-
var smoothingGroupInt = parseInt( smoothingGroup );
|
|
910
|
-
if ( isNaN( smoothingGroupInt ) ) {
|
|
911
|
-
smoothingGroupInt = smoothingGroup === "off" ? 0 : 1;
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
var smoothCheck = this.rawMesh.smoothingGroup.normalized;
|
|
915
|
-
this.rawMesh.smoothingGroup.normalized = this.rawMesh.smoothingGroup.splitMaterials ? smoothingGroupInt : ( smoothingGroupInt === 0 ) ? 0 : 1;
|
|
916
|
-
this.rawMesh.smoothingGroup.real = smoothingGroupInt;
|
|
917
|
-
|
|
918
|
-
if ( smoothCheck !== smoothingGroupInt ) {
|
|
919
|
-
|
|
920
|
-
this.rawMesh.counts.smoothingGroupCount++;
|
|
921
|
-
this.checkSubGroup();
|
|
922
|
-
|
|
923
|
-
}
|
|
924
|
-
};
|
|
925
|
-
|
|
926
|
-
/**
|
|
927
|
-
* Expanded faceTypes include all four face types, both line types and the point type
|
|
928
|
-
* faceType = 0: "f vertex ..."
|
|
929
|
-
* faceType = 1: "f vertex/uv ..."
|
|
930
|
-
* faceType = 2: "f vertex/uv/normal ..."
|
|
931
|
-
* faceType = 3: "f vertex//normal ..."
|
|
932
|
-
* faceType = 4: "l vertex/uv ..." or "l vertex ..."
|
|
933
|
-
* faceType = 5: "l vertex ..."
|
|
934
|
-
* faceType = 6: "p vertex ..."
|
|
935
|
-
*/
|
|
936
|
-
Parser.prototype.checkFaceType = function ( faceType ) {
|
|
937
|
-
if ( this.rawMesh.faceType !== faceType ) {
|
|
938
|
-
|
|
939
|
-
this.processCompletedMesh();
|
|
940
|
-
this.rawMesh.faceType = faceType;
|
|
941
|
-
this.checkSubGroup();
|
|
942
|
-
|
|
943
|
-
}
|
|
944
|
-
};
|
|
945
|
-
|
|
946
|
-
Parser.prototype.checkSubGroup = function () {
|
|
947
|
-
var index = this.rawMesh.activeMtlName + '|' + this.rawMesh.smoothingGroup.normalized;
|
|
948
|
-
this.rawMesh.subGroupInUse = this.rawMesh.subGroups[ index ];
|
|
949
|
-
|
|
950
|
-
if ( ! THREE.LoaderSupport.Validator.isValid( this.rawMesh.subGroupInUse ) ) {
|
|
951
|
-
|
|
952
|
-
this.rawMesh.subGroupInUse = {
|
|
953
|
-
index: index,
|
|
954
|
-
objectName: this.rawMesh.objectName,
|
|
955
|
-
groupName: this.rawMesh.groupName,
|
|
956
|
-
materialName: this.rawMesh.activeMtlName,
|
|
957
|
-
smoothingGroup: this.rawMesh.smoothingGroup.normalized,
|
|
958
|
-
vertices: [],
|
|
959
|
-
indexMappingsCount: 0,
|
|
960
|
-
indexMappings: [],
|
|
961
|
-
indices: [],
|
|
962
|
-
colors: [],
|
|
963
|
-
uvs: [],
|
|
964
|
-
normals: []
|
|
965
|
-
};
|
|
966
|
-
this.rawMesh.subGroups[ index ] = this.rawMesh.subGroupInUse;
|
|
967
|
-
|
|
968
|
-
}
|
|
969
|
-
};
|
|
970
|
-
|
|
971
|
-
Parser.prototype.buildFace = function ( faceIndexV, faceIndexU, faceIndexN ) {
|
|
972
|
-
if ( this.disregardNormals ) faceIndexN = undefined;
|
|
973
|
-
var scope = this;
|
|
974
|
-
var updateSubGroupInUse = function () {
|
|
975
|
-
|
|
976
|
-
var faceIndexVi = parseInt( faceIndexV );
|
|
977
|
-
var indexPointerV = 3 * ( faceIndexVi > 0 ? faceIndexVi - 1 : faceIndexVi + scope.vertices.length / 3 );
|
|
978
|
-
|
|
979
|
-
var vertices = scope.rawMesh.subGroupInUse.vertices;
|
|
980
|
-
vertices.push( scope.vertices[ indexPointerV++ ] );
|
|
981
|
-
vertices.push( scope.vertices[ indexPointerV++ ] );
|
|
982
|
-
vertices.push( scope.vertices[ indexPointerV ] );
|
|
983
|
-
|
|
984
|
-
var indexPointerC = scope.colors.length > 0 ? indexPointerV + 1 : null;
|
|
985
|
-
if ( indexPointerC !== null ) {
|
|
986
|
-
|
|
987
|
-
var colors = scope.rawMesh.subGroupInUse.colors;
|
|
988
|
-
colors.push( scope.colors[ indexPointerC++ ] );
|
|
989
|
-
colors.push( scope.colors[ indexPointerC++ ] );
|
|
990
|
-
colors.push( scope.colors[ indexPointerC ] );
|
|
991
|
-
|
|
992
|
-
}
|
|
993
|
-
if ( faceIndexU ) {
|
|
994
|
-
|
|
995
|
-
var faceIndexUi = parseInt( faceIndexU );
|
|
996
|
-
var indexPointerU = 2 * ( faceIndexUi > 0 ? faceIndexUi - 1 : faceIndexUi + scope.uvs.length / 2 );
|
|
997
|
-
var uvs = scope.rawMesh.subGroupInUse.uvs;
|
|
998
|
-
uvs.push( scope.uvs[ indexPointerU++ ] );
|
|
999
|
-
uvs.push( scope.uvs[ indexPointerU ] );
|
|
1000
|
-
|
|
1001
|
-
}
|
|
1002
|
-
if ( faceIndexN ) {
|
|
1003
|
-
|
|
1004
|
-
var faceIndexNi = parseInt( faceIndexN );
|
|
1005
|
-
var indexPointerN = 3 * ( faceIndexNi > 0 ? faceIndexNi - 1 : faceIndexNi + scope.normals.length / 3 );
|
|
1006
|
-
var normals = scope.rawMesh.subGroupInUse.normals;
|
|
1007
|
-
normals.push( scope.normals[ indexPointerN++ ] );
|
|
1008
|
-
normals.push( scope.normals[ indexPointerN++ ] );
|
|
1009
|
-
normals.push( scope.normals[ indexPointerN ] );
|
|
1010
|
-
|
|
1011
|
-
}
|
|
1012
|
-
};
|
|
1013
|
-
|
|
1014
|
-
if ( this.useIndices ) {
|
|
1015
|
-
|
|
1016
|
-
var mappingName = faceIndexV + ( faceIndexU ? '_' + faceIndexU : '_n' ) + ( faceIndexN ? '_' + faceIndexN : '_n' );
|
|
1017
|
-
var indicesPointer = this.rawMesh.subGroupInUse.indexMappings[ mappingName ];
|
|
1018
|
-
if ( THREE.LoaderSupport.Validator.isValid( indicesPointer ) ) {
|
|
1019
|
-
|
|
1020
|
-
this.rawMesh.counts.doubleIndicesCount++;
|
|
1021
|
-
|
|
1022
|
-
} else {
|
|
1023
|
-
|
|
1024
|
-
indicesPointer = this.rawMesh.subGroupInUse.vertices.length / 3;
|
|
1025
|
-
updateSubGroupInUse();
|
|
1026
|
-
this.rawMesh.subGroupInUse.indexMappings[ mappingName ] = indicesPointer;
|
|
1027
|
-
this.rawMesh.subGroupInUse.indexMappingsCount++;
|
|
1028
|
-
|
|
1029
|
-
}
|
|
1030
|
-
this.rawMesh.subGroupInUse.indices.push( indicesPointer );
|
|
1031
|
-
|
|
1032
|
-
} else {
|
|
1033
|
-
|
|
1034
|
-
updateSubGroupInUse();
|
|
1035
|
-
|
|
1036
|
-
}
|
|
1037
|
-
this.rawMesh.counts.faceCount++;
|
|
1038
|
-
};
|
|
1039
|
-
|
|
1040
|
-
Parser.prototype.createRawMeshReport = function ( inputObjectCount ) {
|
|
1041
|
-
return 'Input Object number: ' + inputObjectCount +
|
|
1042
|
-
'\n\tObject name: ' + this.rawMesh.objectName +
|
|
1043
|
-
'\n\tGroup name: ' + this.rawMesh.groupName +
|
|
1044
|
-
'\n\tMtllib name: ' + this.rawMesh.mtllibName +
|
|
1045
|
-
'\n\tVertex count: ' + this.vertices.length / 3 +
|
|
1046
|
-
'\n\tNormal count: ' + this.normals.length / 3 +
|
|
1047
|
-
'\n\tUV count: ' + this.uvs.length / 2 +
|
|
1048
|
-
'\n\tSmoothingGroup count: ' + this.rawMesh.counts.smoothingGroupCount +
|
|
1049
|
-
'\n\tMaterial count: ' + this.rawMesh.counts.mtlCount +
|
|
1050
|
-
'\n\tReal MeshOutputGroup count: ' + this.rawMesh.subGroups.length;
|
|
1051
|
-
};
|
|
1052
|
-
|
|
1053
|
-
/**
|
|
1054
|
-
* Clear any empty subGroup and calculate absolute vertex, normal and uv counts
|
|
1055
|
-
*/
|
|
1056
|
-
Parser.prototype.finalizeRawMesh = function () {
|
|
1057
|
-
var meshOutputGroupTemp = [];
|
|
1058
|
-
var meshOutputGroup;
|
|
1059
|
-
var absoluteVertexCount = 0;
|
|
1060
|
-
var absoluteIndexMappingsCount = 0;
|
|
1061
|
-
var absoluteIndexCount = 0;
|
|
1062
|
-
var absoluteColorCount = 0;
|
|
1063
|
-
var absoluteNormalCount = 0;
|
|
1064
|
-
var absoluteUvCount = 0;
|
|
1065
|
-
var indices;
|
|
1066
|
-
for ( var name in this.rawMesh.subGroups ) {
|
|
1067
|
-
|
|
1068
|
-
meshOutputGroup = this.rawMesh.subGroups[ name ];
|
|
1069
|
-
if ( meshOutputGroup.vertices.length > 0 ) {
|
|
1070
|
-
|
|
1071
|
-
indices = meshOutputGroup.indices;
|
|
1072
|
-
if ( indices.length > 0 && absoluteIndexMappingsCount > 0 ) {
|
|
1073
|
-
|
|
1074
|
-
for ( var i in indices ) indices[ i ] = indices[ i ] + absoluteIndexMappingsCount;
|
|
1075
|
-
|
|
1076
|
-
}
|
|
1077
|
-
meshOutputGroupTemp.push( meshOutputGroup );
|
|
1078
|
-
absoluteVertexCount += meshOutputGroup.vertices.length;
|
|
1079
|
-
absoluteIndexMappingsCount += meshOutputGroup.indexMappingsCount;
|
|
1080
|
-
absoluteIndexCount += meshOutputGroup.indices.length;
|
|
1081
|
-
absoluteColorCount += meshOutputGroup.colors.length;
|
|
1082
|
-
absoluteUvCount += meshOutputGroup.uvs.length;
|
|
1083
|
-
absoluteNormalCount += meshOutputGroup.normals.length;
|
|
1084
|
-
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
// do not continue if no result
|
|
1089
|
-
var result = null;
|
|
1090
|
-
if ( meshOutputGroupTemp.length > 0 ) {
|
|
1091
|
-
|
|
1092
|
-
result = {
|
|
1093
|
-
name: this.rawMesh.groupName !== '' ? this.rawMesh.groupName : this.rawMesh.objectName,
|
|
1094
|
-
subGroups: meshOutputGroupTemp,
|
|
1095
|
-
absoluteVertexCount: absoluteVertexCount,
|
|
1096
|
-
absoluteIndexCount: absoluteIndexCount,
|
|
1097
|
-
absoluteColorCount: absoluteColorCount,
|
|
1098
|
-
absoluteNormalCount: absoluteNormalCount,
|
|
1099
|
-
absoluteUvCount: absoluteUvCount,
|
|
1100
|
-
faceCount: this.rawMesh.counts.faceCount,
|
|
1101
|
-
doubleIndicesCount: this.rawMesh.counts.doubleIndicesCount
|
|
1102
|
-
};
|
|
1103
|
-
|
|
1104
|
-
}
|
|
1105
|
-
return result;
|
|
1106
|
-
};
|
|
1107
|
-
|
|
1108
|
-
Parser.prototype.processCompletedMesh = function () {
|
|
1109
|
-
var result = this.finalizeRawMesh();
|
|
1110
|
-
if ( THREE.LoaderSupport.Validator.isValid( result ) ) {
|
|
1111
|
-
|
|
1112
|
-
if ( this.colors.length > 0 && this.colors.length !== this.vertices.length ) {
|
|
1113
|
-
|
|
1114
|
-
this._throwError( 'Vertex Colors were detected, but vertex count and color count do not match!' );
|
|
1115
|
-
|
|
1116
|
-
}
|
|
1117
|
-
if ( this.logging.enabled && this.logging.debug ) console.debug( this.createRawMeshReport( this.inputObjectCount ) );
|
|
1118
|
-
this.inputObjectCount++;
|
|
1119
|
-
|
|
1120
|
-
this.buildMesh( result );
|
|
1121
|
-
var progressBytesPercent = this.globalCounts.currentByte / this.globalCounts.totalBytes;
|
|
1122
|
-
this.callbackProgress( 'Completed [o: ' + this.rawMesh.objectName + ' g:' + this.rawMesh.groupName + '] Total progress: ' + ( progressBytesPercent * 100 ).toFixed( 2 ) + '%', progressBytesPercent );
|
|
1123
|
-
this.resetRawMesh();
|
|
1124
|
-
return true;
|
|
1125
|
-
|
|
1126
|
-
} else {
|
|
1127
|
-
|
|
1128
|
-
return false;
|
|
1129
|
-
}
|
|
1130
|
-
};
|
|
1131
|
-
|
|
1132
|
-
/**
|
|
1133
|
-
* SubGroups are transformed to too intermediate format that is forwarded to the MeshBuilder.
|
|
1134
|
-
* It is ensured that SubGroups only contain objects with vertices (no need to check).
|
|
1135
|
-
*
|
|
1136
|
-
* @param result
|
|
1137
|
-
*/
|
|
1138
|
-
Parser.prototype.buildMesh = function ( result ) {
|
|
1139
|
-
var meshOutputGroups = result.subGroups;
|
|
1140
|
-
|
|
1141
|
-
var vertexFA = new Float32Array( result.absoluteVertexCount );
|
|
1142
|
-
this.globalCounts.vertices += result.absoluteVertexCount / 3;
|
|
1143
|
-
this.globalCounts.faces += result.faceCount;
|
|
1144
|
-
this.globalCounts.doubleIndicesCount += result.doubleIndicesCount;
|
|
1145
|
-
var indexUA = ( result.absoluteIndexCount > 0 ) ? new Uint32Array( result.absoluteIndexCount ) : null;
|
|
1146
|
-
var colorFA = ( result.absoluteColorCount > 0 ) ? new Float32Array( result.absoluteColorCount ) : null;
|
|
1147
|
-
var normalFA = ( result.absoluteNormalCount > 0 ) ? new Float32Array( result.absoluteNormalCount ) : null;
|
|
1148
|
-
var uvFA = ( result.absoluteUvCount > 0 ) ? new Float32Array( result.absoluteUvCount ) : null;
|
|
1149
|
-
var haveVertexColors = THREE.LoaderSupport.Validator.isValid( colorFA );
|
|
1150
|
-
|
|
1151
|
-
var meshOutputGroup;
|
|
1152
|
-
var materialNames = [];
|
|
1153
|
-
|
|
1154
|
-
var createMultiMaterial = ( meshOutputGroups.length > 1 );
|
|
1155
|
-
var materialIndex = 0;
|
|
1156
|
-
var materialIndexMapping = [];
|
|
1157
|
-
var selectedMaterialIndex;
|
|
1158
|
-
var materialGroup;
|
|
1159
|
-
var materialGroups = [];
|
|
1160
|
-
|
|
1161
|
-
var vertexFAOffset = 0;
|
|
1162
|
-
var indexUAOffset = 0;
|
|
1163
|
-
var colorFAOffset = 0;
|
|
1164
|
-
var normalFAOffset = 0;
|
|
1165
|
-
var uvFAOffset = 0;
|
|
1166
|
-
var materialGroupOffset = 0;
|
|
1167
|
-
var materialGroupLength = 0;
|
|
1168
|
-
|
|
1169
|
-
var materialOrg, material, materialName, materialNameOrg;
|
|
1170
|
-
// only one specific face type
|
|
1171
|
-
for ( var oodIndex in meshOutputGroups ) {
|
|
1172
|
-
|
|
1173
|
-
if ( ! meshOutputGroups.hasOwnProperty( oodIndex ) ) continue;
|
|
1174
|
-
meshOutputGroup = meshOutputGroups[ oodIndex ];
|
|
1175
|
-
|
|
1176
|
-
materialNameOrg = meshOutputGroup.materialName;
|
|
1177
|
-
if ( this.rawMesh.faceType < 4 ) {
|
|
1178
|
-
|
|
1179
|
-
materialName = materialNameOrg + ( haveVertexColors ? '_vertexColor' : '' ) + ( meshOutputGroup.smoothingGroup === 0 ? '_flat' : '' );
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
} else {
|
|
1183
|
-
|
|
1184
|
-
materialName = this.rawMesh.faceType === 6 ? 'defaultPointMaterial' : 'defaultLineMaterial';
|
|
1185
|
-
|
|
1186
|
-
}
|
|
1187
|
-
materialOrg = this.materials[ materialNameOrg ];
|
|
1188
|
-
material = this.materials[ materialName ];
|
|
1189
|
-
|
|
1190
|
-
// both original and derived names do not lead to an existing material => need to use a default material
|
|
1191
|
-
if ( ! THREE.LoaderSupport.Validator.isValid( materialOrg ) && ! THREE.LoaderSupport.Validator.isValid( material ) ) {
|
|
1192
|
-
|
|
1193
|
-
var defaultMaterialName = haveVertexColors ? 'defaultVertexColorMaterial' : 'defaultMaterial';
|
|
1194
|
-
materialOrg = this.materials[ defaultMaterialName ];
|
|
1195
|
-
if ( this.logging.enabled ) console.warn( 'object_group "' + meshOutputGroup.objectName + '_' +
|
|
1196
|
-
meshOutputGroup.groupName + '" was defined with unresolvable material "' +
|
|
1197
|
-
materialNameOrg + '"! Assigning "' + defaultMaterialName + '".' );
|
|
1198
|
-
materialNameOrg = defaultMaterialName;
|
|
1199
|
-
|
|
1200
|
-
// if names are identical then there is no need for later manipulation
|
|
1201
|
-
if ( materialNameOrg === materialName ) {
|
|
1202
|
-
|
|
1203
|
-
material = materialOrg;
|
|
1204
|
-
materialName = defaultMaterialName;
|
|
1205
|
-
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
}
|
|
1209
|
-
if ( ! THREE.LoaderSupport.Validator.isValid( material ) ) {
|
|
1210
|
-
|
|
1211
|
-
var materialCloneInstructions = {
|
|
1212
|
-
materialNameOrg: materialNameOrg,
|
|
1213
|
-
materialName: materialName,
|
|
1214
|
-
materialProperties: {
|
|
1215
|
-
vertexColors: haveVertexColors ? 2 : 0,
|
|
1216
|
-
flatShading: meshOutputGroup.smoothingGroup === 0
|
|
1217
|
-
}
|
|
1218
|
-
};
|
|
1219
|
-
var payload = {
|
|
1220
|
-
cmd: 'materialData',
|
|
1221
|
-
materials: {
|
|
1222
|
-
materialCloneInstructions: materialCloneInstructions
|
|
1223
|
-
}
|
|
1224
|
-
};
|
|
1225
|
-
this.callbackMeshBuilder( payload );
|
|
1226
|
-
|
|
1227
|
-
// fake entry for async; sync Parser always works on material references (Builder update directly visible here)
|
|
1228
|
-
if ( this.useAsync ) this.materials[ materialName ] = materialCloneInstructions;
|
|
1229
|
-
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
if ( createMultiMaterial ) {
|
|
1233
|
-
|
|
1234
|
-
// re-use material if already used before. Reduces materials array size and eliminates duplicates
|
|
1235
|
-
selectedMaterialIndex = materialIndexMapping[ materialName ];
|
|
1236
|
-
if ( ! selectedMaterialIndex ) {
|
|
1237
|
-
|
|
1238
|
-
selectedMaterialIndex = materialIndex;
|
|
1239
|
-
materialIndexMapping[ materialName ] = materialIndex;
|
|
1240
|
-
materialNames.push( materialName );
|
|
1241
|
-
materialIndex++;
|
|
1242
|
-
|
|
1243
|
-
}
|
|
1244
|
-
materialGroupLength = this.useIndices ? meshOutputGroup.indices.length : meshOutputGroup.vertices.length / 3;
|
|
1245
|
-
materialGroup = {
|
|
1246
|
-
start: materialGroupOffset,
|
|
1247
|
-
count: materialGroupLength,
|
|
1248
|
-
index: selectedMaterialIndex
|
|
1249
|
-
};
|
|
1250
|
-
materialGroups.push( materialGroup );
|
|
1251
|
-
materialGroupOffset += materialGroupLength;
|
|
1252
|
-
|
|
1253
|
-
} else {
|
|
1254
|
-
|
|
1255
|
-
materialNames.push( materialName );
|
|
1256
|
-
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
vertexFA.set( meshOutputGroup.vertices, vertexFAOffset );
|
|
1260
|
-
vertexFAOffset += meshOutputGroup.vertices.length;
|
|
1261
|
-
|
|
1262
|
-
if ( indexUA ) {
|
|
1263
|
-
|
|
1264
|
-
indexUA.set( meshOutputGroup.indices, indexUAOffset );
|
|
1265
|
-
indexUAOffset += meshOutputGroup.indices.length;
|
|
1266
|
-
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
if ( colorFA ) {
|
|
1270
|
-
|
|
1271
|
-
colorFA.set( meshOutputGroup.colors, colorFAOffset );
|
|
1272
|
-
colorFAOffset += meshOutputGroup.colors.length;
|
|
1273
|
-
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
if ( normalFA ) {
|
|
1277
|
-
|
|
1278
|
-
normalFA.set( meshOutputGroup.normals, normalFAOffset );
|
|
1279
|
-
normalFAOffset += meshOutputGroup.normals.length;
|
|
1280
|
-
|
|
1281
|
-
}
|
|
1282
|
-
if ( uvFA ) {
|
|
1283
|
-
|
|
1284
|
-
uvFA.set( meshOutputGroup.uvs, uvFAOffset );
|
|
1285
|
-
uvFAOffset += meshOutputGroup.uvs.length;
|
|
1286
|
-
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
if ( this.logging.enabled && this.logging.debug ) {
|
|
1290
|
-
var materialIndexLine = THREE.LoaderSupport.Validator.isValid( selectedMaterialIndex ) ? '\n\t\tmaterialIndex: ' + selectedMaterialIndex : '';
|
|
1291
|
-
var createdReport = '\tOutput Object no.: ' + this.outputObjectCount +
|
|
1292
|
-
'\n\t\tgroupName: ' + meshOutputGroup.groupName +
|
|
1293
|
-
'\n\t\tIndex: ' + meshOutputGroup.index +
|
|
1294
|
-
'\n\t\tfaceType: ' + this.rawMesh.faceType +
|
|
1295
|
-
'\n\t\tmaterialName: ' + meshOutputGroup.materialName +
|
|
1296
|
-
'\n\t\tsmoothingGroup: ' + meshOutputGroup.smoothingGroup +
|
|
1297
|
-
materialIndexLine +
|
|
1298
|
-
'\n\t\tobjectName: ' + meshOutputGroup.objectName +
|
|
1299
|
-
'\n\t\t#vertices: ' + meshOutputGroup.vertices.length / 3 +
|
|
1300
|
-
'\n\t\t#indices: ' + meshOutputGroup.indices.length +
|
|
1301
|
-
'\n\t\t#colors: ' + meshOutputGroup.colors.length / 3 +
|
|
1302
|
-
'\n\t\t#uvs: ' + meshOutputGroup.uvs.length / 2 +
|
|
1303
|
-
'\n\t\t#normals: ' + meshOutputGroup.normals.length / 3;
|
|
1304
|
-
console.debug( createdReport );
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
this.outputObjectCount++;
|
|
1310
|
-
this.callbackMeshBuilder(
|
|
1311
|
-
{
|
|
1312
|
-
cmd: 'meshData',
|
|
1313
|
-
progress: {
|
|
1314
|
-
numericalValue: this.globalCounts.currentByte / this.globalCounts.totalBytes
|
|
1315
|
-
},
|
|
1316
|
-
params: {
|
|
1317
|
-
meshName: result.name
|
|
1318
|
-
},
|
|
1319
|
-
materials: {
|
|
1320
|
-
multiMaterial: createMultiMaterial,
|
|
1321
|
-
materialNames: materialNames,
|
|
1322
|
-
materialGroups: materialGroups
|
|
1323
|
-
},
|
|
1324
|
-
buffers: {
|
|
1325
|
-
vertices: vertexFA,
|
|
1326
|
-
indices: indexUA,
|
|
1327
|
-
colors: colorFA,
|
|
1328
|
-
normals: normalFA,
|
|
1329
|
-
uvs: uvFA
|
|
1330
|
-
},
|
|
1331
|
-
// 0: mesh, 1: line, 2: point
|
|
1332
|
-
geometryType: this.rawMesh.faceType < 4 ? 0 : ( this.rawMesh.faceType === 6 ) ? 2 : 1
|
|
1333
|
-
},
|
|
1334
|
-
[ vertexFA.buffer ],
|
|
1335
|
-
THREE.LoaderSupport.Validator.isValid( indexUA ) ? [ indexUA.buffer ] : null,
|
|
1336
|
-
THREE.LoaderSupport.Validator.isValid( colorFA ) ? [ colorFA.buffer ] : null,
|
|
1337
|
-
THREE.LoaderSupport.Validator.isValid( normalFA ) ? [ normalFA.buffer ] : null,
|
|
1338
|
-
THREE.LoaderSupport.Validator.isValid( uvFA ) ? [ uvFA.buffer ] : null
|
|
1339
|
-
);
|
|
1340
|
-
};
|
|
1341
|
-
|
|
1342
|
-
Parser.prototype.finalizeParsing = function () {
|
|
1343
|
-
if ( this.logging.enabled ) console.info( 'Global output object count: ' + this.outputObjectCount );
|
|
1344
|
-
if ( this.processCompletedMesh() && this.logging.enabled ) {
|
|
1345
|
-
|
|
1346
|
-
var parserFinalReport = 'Overall counts: ' +
|
|
1347
|
-
'\n\tVertices: ' + this.globalCounts.vertices +
|
|
1348
|
-
'\n\tFaces: ' + this.globalCounts.faces +
|
|
1349
|
-
'\n\tMultiple definitions: ' + this.globalCounts.doubleIndicesCount;
|
|
1350
|
-
console.info( parserFinalReport );
|
|
1351
|
-
|
|
1352
|
-
}
|
|
1353
|
-
};
|
|
1354
|
-
|
|
1355
|
-
return Parser;
|
|
1356
|
-
})();
|
|
1357
|
-
|
|
1358
|
-
/**
|
|
1359
|
-
* Utility method for loading an mtl file according resource description. Provide url or content.
|
|
1360
|
-
* @memberOf THREE.OBJLoader2
|
|
1361
|
-
*
|
|
1362
|
-
* @param {string} url URL to the file
|
|
1363
|
-
* @param {Object} content The file content as arraybuffer or text
|
|
1364
|
-
* @param {function} onLoad Callback to be called after successful load
|
|
1365
|
-
* @param {callback} [onProgress] A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains total and Integer bytes.
|
|
1366
|
-
* @param {callback} [onError] A function to be called if an error occurs during loading. The function receives the error as an argument.
|
|
1367
|
-
* @param {string} [crossOrigin] CORS value
|
|
1368
|
-
* @param {Object} [materialOptions] Set material loading options for MTLLoader
|
|
1369
|
-
*/
|
|
1370
|
-
OBJLoader2.prototype.loadMtl = function ( url, content, onLoad, onProgress, onError, crossOrigin, materialOptions ) {
|
|
1371
|
-
var resource = new THREE.LoaderSupport.ResourceDescriptor( url, 'MTL' );
|
|
1372
|
-
resource.setContent( content );
|
|
1373
|
-
this._loadMtl( resource, onLoad, onProgress, onError, crossOrigin, materialOptions );
|
|
1374
|
-
};
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
OBJLoader2.prototype._loadMtl = function ( resource, onLoad, onProgress, onError, crossOrigin, materialOptions ) {
|
|
1378
|
-
if ( THREE.MTLLoader === undefined ) console.error( '"THREE.MTLLoader" is not available. "THREE.OBJLoader2" requires it for loading MTL files.' );
|
|
1379
|
-
if ( Validator.isValid( resource ) && this.logging.enabled ) console.time( 'Loading MTL: ' + resource.name );
|
|
1380
|
-
|
|
1381
|
-
var materials = [];
|
|
1382
|
-
var scope = this;
|
|
1383
|
-
var processMaterials = function ( materialCreator ) {
|
|
1384
|
-
var materialCreatorMaterials = [];
|
|
1385
|
-
if ( Validator.isValid( materialCreator ) ) {
|
|
1386
|
-
|
|
1387
|
-
materialCreator.preload();
|
|
1388
|
-
materialCreatorMaterials = materialCreator.materials;
|
|
1389
|
-
for ( var materialName in materialCreatorMaterials ) {
|
|
1390
|
-
|
|
1391
|
-
if ( materialCreatorMaterials.hasOwnProperty( materialName ) ) {
|
|
1392
|
-
|
|
1393
|
-
materials[ materialName ] = materialCreatorMaterials[ materialName ];
|
|
1394
|
-
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
if ( Validator.isValid( resource ) && scope.logging.enabled ) console.timeEnd( 'Loading MTL: ' + resource.name );
|
|
1400
|
-
onLoad( materials, materialCreator );
|
|
1401
|
-
};
|
|
1402
|
-
|
|
1403
|
-
// fast-fail
|
|
1404
|
-
if ( ! Validator.isValid( resource ) || ( ! Validator.isValid( resource.content ) && ! Validator.isValid( resource.url ) ) ) {
|
|
1405
|
-
|
|
1406
|
-
processMaterials();
|
|
1407
|
-
|
|
1408
|
-
} else {
|
|
1409
|
-
|
|
1410
|
-
var mtlLoader = new THREE.MTLLoader( this.manager );
|
|
1411
|
-
crossOrigin = Validator.verifyInput( crossOrigin, 'anonymous' );
|
|
1412
|
-
mtlLoader.setCrossOrigin( crossOrigin );
|
|
1413
|
-
mtlLoader.setResourcePath( this.resourcePath || resource.path );
|
|
1414
|
-
mtlLoader.resourceURLHandle = this.resourceURLHandle;
|
|
1415
|
-
if ( Validator.isValid( materialOptions ) ) mtlLoader.setMaterialOptions( materialOptions );
|
|
1416
|
-
|
|
1417
|
-
var parseTextWithMtlLoader = function ( content ) {
|
|
1418
|
-
var contentAsText = content;
|
|
1419
|
-
if ( typeof( content ) !== 'string' && ! ( content instanceof String ) ) {
|
|
1420
|
-
|
|
1421
|
-
if ( content.length > 0 || content.byteLength > 0 ) {
|
|
1422
|
-
|
|
1423
|
-
contentAsText = THREE.LoaderUtils.decodeText( content );
|
|
1424
|
-
|
|
1425
|
-
} else {
|
|
1426
|
-
|
|
1427
|
-
this._throwError( 'Unable to parse mtl as it it seems to be neither a String, an Array or an ArrayBuffer!' );
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
}
|
|
1431
|
-
processMaterials( mtlLoader.parse( contentAsText ) );
|
|
1432
|
-
};
|
|
1433
|
-
|
|
1434
|
-
if ( Validator.isValid( resource.content ) ) {
|
|
1435
|
-
|
|
1436
|
-
parseTextWithMtlLoader( resource.content );
|
|
1437
|
-
|
|
1438
|
-
} else if ( Validator.isValid( resource.url ) ) {
|
|
1439
|
-
|
|
1440
|
-
var fileLoader = new THREE.FileLoader( this.manager );
|
|
1441
|
-
if ( ! Validator.isValid( onError ) ) {
|
|
1442
|
-
onError = function ( event ) {
|
|
1443
|
-
scope._onError( event );
|
|
1444
|
-
};
|
|
1445
|
-
}
|
|
1446
|
-
if ( ! Validator.isValid( onProgress ) ) {
|
|
1447
|
-
var numericalValueRef = 0;
|
|
1448
|
-
var numericalValue = 0;
|
|
1449
|
-
onProgress = function ( event ) {
|
|
1450
|
-
if ( ! event.lengthComputable ) return;
|
|
1451
|
-
|
|
1452
|
-
numericalValue = event.loaded / event.total;
|
|
1453
|
-
if ( numericalValue > numericalValueRef ) {
|
|
1454
|
-
|
|
1455
|
-
numericalValueRef = numericalValue;
|
|
1456
|
-
var output = 'Download of "' + resource.url + '": ' + ( numericalValue * 100 ).toFixed( 2 ) + '%';
|
|
1457
|
-
scope.onProgress( 'progressLoad', output, numericalValue );
|
|
1458
|
-
|
|
1459
|
-
}
|
|
1460
|
-
};
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
fileLoader.load( resource.url, parseTextWithMtlLoader, onProgress, onError );
|
|
1464
|
-
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
};
|
|
1468
|
-
|
|
1469
|
-
return OBJLoader2;
|
|
1470
|
-
})();
|