first commit
This commit is contained in:
		
							
								
								
									
										373
									
								
								public/sdk/three/jsm/loaders/lwo/LWO3Parser.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										373
									
								
								public/sdk/three/jsm/loaders/lwo/LWO3Parser.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,373 @@ | ||||
| class LWO3Parser { | ||||
|  | ||||
| 	constructor( IFFParser ) { | ||||
|  | ||||
| 		this.IFF = IFFParser; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	parseBlock() { | ||||
|  | ||||
| 		this.IFF.debugger.offset = this.IFF.reader.offset; | ||||
| 		this.IFF.debugger.closeForms(); | ||||
|  | ||||
| 		const blockID = this.IFF.reader.getIDTag(); | ||||
| 		const length = this.IFF.reader.getUint32(); // size of data in bytes | ||||
|  | ||||
| 		this.IFF.debugger.dataOffset = this.IFF.reader.offset; | ||||
| 		this.IFF.debugger.length = length; | ||||
|  | ||||
| 		// Data types may be found in either LWO2 OR LWO3 spec | ||||
| 		switch ( blockID ) { | ||||
|  | ||||
| 			case 'FORM': // form blocks may consist of sub -chunks or sub-forms | ||||
| 				this.IFF.parseForm( length ); | ||||
| 				break; | ||||
|  | ||||
| 			// SKIPPED CHUNKS | ||||
| 			// MISC skipped | ||||
| 			case 'ICON': // Thumbnail Icon Image | ||||
| 			case 'VMPA': // Vertex Map Parameter | ||||
| 			case 'BBOX': // bounding box | ||||
| 			// case 'VMMD': | ||||
| 			// case 'VTYP': | ||||
|  | ||||
| 			// normal maps can be specified, normally on models imported from other applications. Currently ignored | ||||
| 			case 'NORM': | ||||
|  | ||||
| 			// ENVL FORM skipped | ||||
| 			case 'PRE ': // Pre-loop behavior for the keyframe | ||||
| 			case 'POST': // Post-loop behavior for the keyframe | ||||
| 			case 'KEY ': | ||||
| 			case 'SPAN': | ||||
|  | ||||
| 			// CLIP FORM skipped | ||||
| 			case 'TIME': | ||||
| 			case 'CLRS': | ||||
| 			case 'CLRA': | ||||
| 			case 'FILT': | ||||
| 			case 'DITH': | ||||
| 			case 'CONT': | ||||
| 			case 'BRIT': | ||||
| 			case 'SATR': | ||||
| 			case 'HUE ': | ||||
| 			case 'GAMM': | ||||
| 			case 'NEGA': | ||||
| 			case 'IFLT': | ||||
| 			case 'PFLT': | ||||
|  | ||||
| 			// Image Map Layer skipped | ||||
| 			case 'PROJ': | ||||
| 			case 'AXIS': | ||||
| 			case 'AAST': | ||||
| 			case 'PIXB': | ||||
| 			case 'STCK': | ||||
|  | ||||
| 			// Procedural Textures skipped | ||||
| 			case 'VALU': | ||||
|  | ||||
| 			// Gradient Textures skipped | ||||
| 			case 'PNAM': | ||||
| 			case 'INAM': | ||||
| 			case 'GRST': | ||||
| 			case 'GREN': | ||||
| 			case 'GRPT': | ||||
| 			case 'FKEY': | ||||
| 			case 'IKEY': | ||||
|  | ||||
| 			// Texture Mapping Form skipped | ||||
| 			case 'CSYS': | ||||
|  | ||||
| 				// Surface CHUNKs skipped | ||||
| 			case 'OPAQ': // top level 'opacity' checkbox | ||||
| 			case 'CMAP': // clip map | ||||
|  | ||||
| 			// Surface node CHUNKS skipped | ||||
| 			// These mainly specify the node editor setup in LW | ||||
| 			case 'NLOC': | ||||
| 			case 'NZOM': | ||||
| 			case 'NVER': | ||||
| 			case 'NSRV': | ||||
| 			case 'NCRD': | ||||
| 			case 'NMOD': | ||||
| 			case 'NSEL': | ||||
| 			case 'NPRW': | ||||
| 			case 'NPLA': | ||||
| 			case 'VERS': | ||||
| 			case 'ENUM': | ||||
| 			case 'TAG ': | ||||
|  | ||||
| 			// Car Material CHUNKS | ||||
| 			case 'CGMD': | ||||
| 			case 'CGTY': | ||||
| 			case 'CGST': | ||||
| 			case 'CGEN': | ||||
| 			case 'CGTS': | ||||
| 			case 'CGTE': | ||||
| 			case 'OSMP': | ||||
| 			case 'OMDE': | ||||
| 			case 'OUTR': | ||||
| 			case 'FLAG': | ||||
|  | ||||
| 			case 'TRNL': | ||||
| 			case 'SHRP': | ||||
| 			case 'RFOP': | ||||
| 			case 'RSAN': | ||||
| 			case 'TROP': | ||||
| 			case 'RBLR': | ||||
| 			case 'TBLR': | ||||
| 			case 'CLRH': | ||||
| 			case 'CLRF': | ||||
| 			case 'ADTR': | ||||
| 			case 'GLOW': | ||||
| 			case 'LINE': | ||||
| 			case 'ALPH': | ||||
| 			case 'VCOL': | ||||
| 			case 'ENAB': | ||||
| 				this.IFF.debugger.skipped = true; | ||||
| 				this.IFF.reader.skip( length ); | ||||
| 				break; | ||||
|  | ||||
| 			// Texture node chunks (not in spec) | ||||
| 			case 'IPIX': // usePixelBlending | ||||
| 			case 'IMIP': // useMipMaps | ||||
| 			case 'IMOD': // imageBlendingMode | ||||
| 			case 'AMOD': // unknown | ||||
| 			case 'IINV': // imageInvertAlpha | ||||
| 			case 'INCR': // imageInvertColor | ||||
| 			case 'IAXS': // imageAxis ( for non-UV maps) | ||||
| 			case 'IFOT': // imageFallofType | ||||
| 			case 'ITIM': // timing for animated textures | ||||
| 			case 'IWRL': | ||||
| 			case 'IUTI': | ||||
| 			case 'IINX': | ||||
| 			case 'IINY': | ||||
| 			case 'IINZ': | ||||
| 			case 'IREF': // possibly a VX for reused texture nodes | ||||
| 				if ( length === 4 ) this.IFF.currentNode[ blockID ] = this.IFF.reader.getInt32(); | ||||
| 				else this.IFF.reader.skip( length ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'OTAG': | ||||
| 				this.IFF.parseObjectTag(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'LAYR': | ||||
| 				this.IFF.parseLayer( length ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'PNTS': | ||||
| 				this.IFF.parsePoints( length ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'VMAP': | ||||
| 				this.IFF.parseVertexMapping( length ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'POLS': | ||||
| 				this.IFF.parsePolygonList( length ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'TAGS': | ||||
| 				this.IFF.parseTagStrings( length ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'PTAG': | ||||
| 				this.IFF.parsePolygonTagMapping( length ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'VMAD': | ||||
| 				this.IFF.parseVertexMapping( length, true ); | ||||
| 				break; | ||||
|  | ||||
| 			// Misc CHUNKS | ||||
| 			case 'DESC': // Description Line | ||||
| 				this.IFF.currentForm.description = this.IFF.reader.getString(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'TEXT': | ||||
| 			case 'CMNT': | ||||
| 			case 'NCOM': | ||||
| 				this.IFF.currentForm.comment = this.IFF.reader.getString(); | ||||
| 				break; | ||||
|  | ||||
| 			// Envelope Form | ||||
| 			case 'NAME': | ||||
| 				this.IFF.currentForm.channelName = this.IFF.reader.getString(); | ||||
| 				break; | ||||
|  | ||||
| 			// Image Map Layer | ||||
| 			case 'WRAP': | ||||
| 				this.IFF.currentForm.wrap = { w: this.IFF.reader.getUint16(), h: this.IFF.reader.getUint16() }; | ||||
| 				break; | ||||
|  | ||||
| 			case 'IMAG': | ||||
| 				const index = this.IFF.reader.getVariableLengthIndex(); | ||||
| 				this.IFF.currentForm.imageIndex = index; | ||||
| 				break; | ||||
|  | ||||
| 			// Texture Mapping Form | ||||
| 			case 'OREF': | ||||
| 				this.IFF.currentForm.referenceObject = this.IFF.reader.getString(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'ROID': | ||||
| 				this.IFF.currentForm.referenceObjectID = this.IFF.reader.getUint32(); | ||||
| 				break; | ||||
|  | ||||
| 			// Surface Blocks | ||||
| 			case 'SSHN': | ||||
| 				this.IFF.currentSurface.surfaceShaderName = this.IFF.reader.getString(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'AOVN': | ||||
| 				this.IFF.currentSurface.surfaceCustomAOVName = this.IFF.reader.getString(); | ||||
| 				break; | ||||
|  | ||||
| 			// Nodal Blocks | ||||
| 			case 'NSTA': | ||||
| 				this.IFF.currentForm.disabled = this.IFF.reader.getUint16(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'NRNM': | ||||
| 				this.IFF.currentForm.realName = this.IFF.reader.getString(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'NNME': | ||||
| 				this.IFF.currentForm.refName = this.IFF.reader.getString(); | ||||
| 				this.IFF.currentSurface.nodes[ this.IFF.currentForm.refName ] = this.IFF.currentForm; | ||||
| 				break; | ||||
|  | ||||
| 			// Nodal Blocks : connections | ||||
| 			case 'INME': | ||||
| 				if ( ! this.IFF.currentForm.nodeName ) this.IFF.currentForm.nodeName = []; | ||||
| 				this.IFF.currentForm.nodeName.push( this.IFF.reader.getString() ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'IINN': | ||||
| 				if ( ! this.IFF.currentForm.inputNodeName ) this.IFF.currentForm.inputNodeName = []; | ||||
| 				this.IFF.currentForm.inputNodeName.push( this.IFF.reader.getString() ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'IINM': | ||||
| 				if ( ! this.IFF.currentForm.inputName ) this.IFF.currentForm.inputName = []; | ||||
| 				this.IFF.currentForm.inputName.push( this.IFF.reader.getString() ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'IONM': | ||||
| 				if ( ! this.IFF.currentForm.inputOutputName ) this.IFF.currentForm.inputOutputName = []; | ||||
| 				this.IFF.currentForm.inputOutputName.push( this.IFF.reader.getString() ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'FNAM': | ||||
| 				this.IFF.currentForm.fileName = this.IFF.reader.getString(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'CHAN': // NOTE: ENVL Forms may also have CHAN chunk, however ENVL is currently ignored | ||||
| 				if ( length === 4 ) this.IFF.currentForm.textureChannel = this.IFF.reader.getIDTag(); | ||||
| 				else this.IFF.reader.skip( length ); | ||||
| 				break; | ||||
|  | ||||
| 			// LWO2 Spec chunks: these are needed since the SURF FORMs are often in LWO2 format | ||||
| 			case 'SMAN': | ||||
| 				const maxSmoothingAngle = this.IFF.reader.getFloat32(); | ||||
| 				this.IFF.currentSurface.attributes.smooth = ( maxSmoothingAngle < 0 ) ? false : true; | ||||
| 				break; | ||||
|  | ||||
| 			// LWO2: Basic Surface Parameters | ||||
| 			case 'COLR': | ||||
| 				this.IFF.currentSurface.attributes.Color = { value: this.IFF.reader.getFloat32Array( 3 ) }; | ||||
| 				this.IFF.reader.skip( 2 ); // VX: envelope | ||||
| 				break; | ||||
|  | ||||
| 			case 'LUMI': | ||||
| 				this.IFF.currentSurface.attributes.Luminosity = { value: this.IFF.reader.getFloat32() }; | ||||
| 				this.IFF.reader.skip( 2 ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'SPEC': | ||||
| 				this.IFF.currentSurface.attributes.Specular = { value: this.IFF.reader.getFloat32() }; | ||||
| 				this.IFF.reader.skip( 2 ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'DIFF': | ||||
| 				this.IFF.currentSurface.attributes.Diffuse = { value: this.IFF.reader.getFloat32() }; | ||||
| 				this.IFF.reader.skip( 2 ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'REFL': | ||||
| 				this.IFF.currentSurface.attributes.Reflection = { value: this.IFF.reader.getFloat32() }; | ||||
| 				this.IFF.reader.skip( 2 ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'GLOS': | ||||
| 				this.IFF.currentSurface.attributes.Glossiness = { value: this.IFF.reader.getFloat32() }; | ||||
| 				this.IFF.reader.skip( 2 ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'TRAN': | ||||
| 				this.IFF.currentSurface.attributes.opacity = this.IFF.reader.getFloat32(); | ||||
| 				this.IFF.reader.skip( 2 ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'BUMP': | ||||
| 				this.IFF.currentSurface.attributes.bumpStrength = this.IFF.reader.getFloat32(); | ||||
| 				this.IFF.reader.skip( 2 ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'SIDE': | ||||
| 				this.IFF.currentSurface.attributes.side = this.IFF.reader.getUint16(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'RIMG': | ||||
| 				this.IFF.currentSurface.attributes.reflectionMap = this.IFF.reader.getVariableLengthIndex(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'RIND': | ||||
| 				this.IFF.currentSurface.attributes.refractiveIndex = this.IFF.reader.getFloat32(); | ||||
| 				this.IFF.reader.skip( 2 ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'TIMG': | ||||
| 				this.IFF.currentSurface.attributes.refractionMap = this.IFF.reader.getVariableLengthIndex(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'IMAP': | ||||
| 				this.IFF.currentSurface.attributes.imageMapIndex = this.IFF.reader.getUint32(); | ||||
| 				break; | ||||
|  | ||||
| 			case 'IUVI': // uv channel name | ||||
| 				this.IFF.currentNode.UVChannel = this.IFF.reader.getString( length ); | ||||
| 				break; | ||||
|  | ||||
| 			case 'IUTL': // widthWrappingMode: 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge | ||||
| 				this.IFF.currentNode.widthWrappingMode = this.IFF.reader.getUint32(); | ||||
| 				break; | ||||
| 			case 'IVTL': // heightWrappingMode | ||||
| 				this.IFF.currentNode.heightWrappingMode = this.IFF.reader.getUint32(); | ||||
| 				break; | ||||
|  | ||||
| 			default: | ||||
| 				this.IFF.parseUnknownCHUNK( blockID, length ); | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		if ( blockID != 'FORM' ) { | ||||
|  | ||||
| 			this.IFF.debugger.node = 1; | ||||
| 			this.IFF.debugger.nodeID = blockID; | ||||
| 			this.IFF.debugger.log(); | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		if ( this.IFF.reader.offset >= this.IFF.currentFormEnd ) { | ||||
|  | ||||
| 			this.IFF.currentForm = this.IFF.parentForm; | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| export { LWO3Parser }; | ||||
		Reference in New Issue
	
	Block a user