897 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			897 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								const _object_pattern = /^[og]\s*(.+)?/;
							 | 
						||
| 
								 | 
							
								const _material_library_pattern = /^mtllib /;
							 | 
						||
| 
								 | 
							
								const _material_use_pattern = /^usemtl /;
							 | 
						||
| 
								 | 
							
								const _map_use_pattern = /^usemap /;
							 | 
						||
| 
								 | 
							
								const _face_vertex_data_separator_pattern = /\s+/;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const _color = new Cesium.Color();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function ParserState() {
							 | 
						||
| 
								 | 
							
								    const state = {
							 | 
						||
| 
								 | 
							
								        objects: [],
							 | 
						||
| 
								 | 
							
								        object: {},
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        vertices: [],
							 | 
						||
| 
								 | 
							
								        normals: [],
							 | 
						||
| 
								 | 
							
								        colors: [],
							 | 
						||
| 
								 | 
							
								        uvs: [],
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        materials: {},
							 | 
						||
| 
								 | 
							
								        materialLibraries: [],
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        startObject: function (name, fromDeclaration) {
							 | 
						||
| 
								 | 
							
								            if (this.object && this.object.fromDeclaration === false) {
							 | 
						||
| 
								 | 
							
								                this.object.name = name;
							 | 
						||
| 
								 | 
							
								                this.object.fromDeclaration = (fromDeclaration !== false);
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            const previousMaterial = (this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined);
							 | 
						||
| 
								 | 
							
								            if (this.object && typeof this.object._finalize === 'function') {
							 | 
						||
| 
								 | 
							
								                this.object._finalize(true);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            this.object = {
							 | 
						||
| 
								 | 
							
								                name: name || '',
							 | 
						||
| 
								 | 
							
								                fromDeclaration: (fromDeclaration !== false),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                geometry: {
							 | 
						||
| 
								 | 
							
								                    vertices: [],
							 | 
						||
| 
								 | 
							
								                    normals: [],
							 | 
						||
| 
								 | 
							
								                    colors: [],
							 | 
						||
| 
								 | 
							
								                    uvs: [],
							 | 
						||
| 
								 | 
							
								                    hasUVIndices: false
							 | 
						||
| 
								 | 
							
								                },
							 | 
						||
| 
								 | 
							
								                materials: [],
							 | 
						||
| 
								 | 
							
								                smooth: true,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                startMaterial: function (name, libraries) {
							 | 
						||
| 
								 | 
							
								                    const previous = this._finalize(false);
							 | 
						||
| 
								 | 
							
								                    if (previous && (previous.inherited || previous.groupCount <= 0)) {
							 | 
						||
| 
								 | 
							
								                        this.materials.splice(previous.index, 1);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    const material = {
							 | 
						||
| 
								 | 
							
								                        index: this.materials.length,
							 | 
						||
| 
								 | 
							
								                        name: name || '',
							 | 
						||
| 
								 | 
							
								                        mtllib: (Array.isArray(libraries) && libraries.length > 0 ? libraries[libraries.length - 1] : ''),
							 | 
						||
| 
								 | 
							
								                        smooth: (previous !== undefined ? previous.smooth : this.smooth),
							 | 
						||
| 
								 | 
							
								                        groupStart: (previous !== undefined ? previous.groupEnd : 0),
							 | 
						||
| 
								 | 
							
								                        groupEnd: -1,
							 | 
						||
| 
								 | 
							
								                        groupCount: -1,
							 | 
						||
| 
								 | 
							
								                        inherited: false,
							 | 
						||
| 
								 | 
							
								                        clone: function (index) {
							 | 
						||
| 
								 | 
							
								                            const cloned = {
							 | 
						||
| 
								 | 
							
								                                index: (typeof index === 'number' ? index : this.index),
							 | 
						||
| 
								 | 
							
								                                name: this.name,
							 | 
						||
| 
								 | 
							
								                                mtllib: this.mtllib,
							 | 
						||
| 
								 | 
							
								                                smooth: this.smooth,
							 | 
						||
| 
								 | 
							
								                                groupStart: 0,
							 | 
						||
| 
								 | 
							
								                                groupEnd: -1,
							 | 
						||
| 
								 | 
							
								                                groupCount: -1,
							 | 
						||
| 
								 | 
							
								                                inherited: false
							 | 
						||
| 
								 | 
							
								                            };
							 | 
						||
| 
								 | 
							
								                            cloned.clone = this.clone.bind(cloned);
							 | 
						||
| 
								 | 
							
								                            return cloned;
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                    };
							 | 
						||
| 
								 | 
							
								                    this.materials.push(material);
							 | 
						||
| 
								 | 
							
								                    return material;
							 | 
						||
| 
								 | 
							
								                },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                currentMaterial: function () {
							 | 
						||
| 
								 | 
							
								                    if (this.materials.length > 0) {
							 | 
						||
| 
								 | 
							
								                        return this.materials[this.materials.length - 1];
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    return undefined;
							 | 
						||
| 
								 | 
							
								                },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                _finalize: function (end) {
							 | 
						||
| 
								 | 
							
								                    const lastMultiMaterial = this.currentMaterial();
							 | 
						||
| 
								 | 
							
								                    if (lastMultiMaterial && lastMultiMaterial.groupEnd === -1) {
							 | 
						||
| 
								 | 
							
								                        lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
							 | 
						||
| 
								 | 
							
								                        lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
							 | 
						||
| 
								 | 
							
								                        lastMultiMaterial.inherited = false;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (end && this.materials.length > 1) {
							 | 
						||
| 
								 | 
							
								                        for (let mi = this.materials.length - 1; mi >= 0; mi--) {
							 | 
						||
| 
								 | 
							
								                            if (this.materials[mi].groupCount <= 0) {
							 | 
						||
| 
								 | 
							
								                                this.materials.splice(mi, 1);
							 | 
						||
| 
								 | 
							
								                            }
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (end && this.materials.length === 0) {
							 | 
						||
| 
								 | 
							
								                        this.materials.push({
							 | 
						||
| 
								 | 
							
								                            name: '',
							 | 
						||
| 
								 | 
							
								                            smooth: this.smooth
							 | 
						||
| 
								 | 
							
								                        });
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    return lastMultiMaterial;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function') {
							 | 
						||
| 
								 | 
							
								                const declared = previousMaterial.clone(0);
							 | 
						||
| 
								 | 
							
								                declared.inherited = true;
							 | 
						||
| 
								 | 
							
								                this.object.materials.push(declared);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            this.objects.push(this.object);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        finalize: function () {
							 | 
						||
| 
								 | 
							
								            if (this.object && typeof this.object._finalize === 'function') {
							 | 
						||
| 
								 | 
							
								                this.object._finalize(true);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        parseVertexIndex: function (value, len) {
							 | 
						||
| 
								 | 
							
								            const index = parseInt(value, 10);
							 | 
						||
| 
								 | 
							
								            return (index >= 0 ? index - 1 : index + len / 3) * 3;
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        parseNormalIndex: function (value, len) {
							 | 
						||
| 
								 | 
							
								            const index = parseInt(value, 10);
							 | 
						||
| 
								 | 
							
								            return (index >= 0 ? index - 1 : index + len / 3) * 3;
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        parseUVIndex: function (value, len) {
							 | 
						||
| 
								 | 
							
								            const index = parseInt(value, 10);
							 | 
						||
| 
								 | 
							
								            return (index >= 0 ? index - 1 : index + len / 2) * 2;
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addVertex: function (a, b, c) {
							 | 
						||
| 
								 | 
							
								            const src = this.vertices;
							 | 
						||
| 
								 | 
							
								            const dst = this.object.geometry.vertices;
							 | 
						||
| 
								 | 
							
								            dst.push(src[a + 0], src[a + 1], src[a + 2]);
							 | 
						||
| 
								 | 
							
								            dst.push(src[b + 0], src[b + 1], src[b + 2]);
							 | 
						||
| 
								 | 
							
								            dst.push(src[c + 0], src[c + 1], src[c + 2]);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addVertexPoint: function (a) {
							 | 
						||
| 
								 | 
							
								            const src = this.vertices;
							 | 
						||
| 
								 | 
							
								            const dst = this.object.geometry.vertices;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            dst.push(src[a + 0], src[a + 1], src[a + 2]);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addVertexLine: function (a) {
							 | 
						||
| 
								 | 
							
								            const src = this.vertices;
							 | 
						||
| 
								 | 
							
								            const dst = this.object.geometry.vertices;
							 | 
						||
| 
								 | 
							
								            dst.push(src[a + 0], src[a + 1], src[a + 2]);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addNormal: function (a, b, c) {
							 | 
						||
| 
								 | 
							
								            const src = this.normals;
							 | 
						||
| 
								 | 
							
								            const dst = this.object.geometry.normals;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            dst.push(src[a + 0], src[a + 1], src[a + 2]);
							 | 
						||
| 
								 | 
							
								            dst.push(src[b + 0], src[b + 1], src[b + 2]);
							 | 
						||
| 
								 | 
							
								            dst.push(src[c + 0], src[c + 1], src[c + 2]);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addFaceNormal: function (a, b, c) {
							 | 
						||
| 
								 | 
							
								            console.warn("addFaceNormal");
							 | 
						||
| 
								 | 
							
								            // const src = this.vertices;
							 | 
						||
| 
								 | 
							
								            // const dst = this.object.geometry.normals;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // _vA.fromArray( src, a );
							 | 
						||
| 
								 | 
							
								            // _vB.fromArray( src, b );
							 | 
						||
| 
								 | 
							
								            // _vC.fromArray( src, c );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // _cb.subVectors( _vC, _vB );
							 | 
						||
| 
								 | 
							
								            // _ab.subVectors( _vA, _vB );
							 | 
						||
| 
								 | 
							
								            // _cb.cross( _ab );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // _cb.normalize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // dst.push( _cb.x, _cb.y, _cb.z );
							 | 
						||
| 
								 | 
							
								            // dst.push( _cb.x, _cb.y, _cb.z );
							 | 
						||
| 
								 | 
							
								            // dst.push( _cb.x, _cb.y, _cb.z );
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addColor: function (a, b, c) {
							 | 
						||
| 
								 | 
							
								            const src = this.colors;
							 | 
						||
| 
								 | 
							
								            const dst = this.object.geometry.colors;
							 | 
						||
| 
								 | 
							
								            if (src[a] !== undefined) dst.push(src[a + 0], src[a + 1], src[a + 2]);
							 | 
						||
| 
								 | 
							
								            if (src[b] !== undefined) dst.push(src[b + 0], src[b + 1], src[b + 2]);
							 | 
						||
| 
								 | 
							
								            if (src[c] !== undefined) dst.push(src[c + 0], src[c + 1], src[c + 2]);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addUV: function (a, b, c) {
							 | 
						||
| 
								 | 
							
								            const src = this.uvs;
							 | 
						||
| 
								 | 
							
								            const dst = this.object.geometry.uvs;
							 | 
						||
| 
								 | 
							
								            dst.push(src[a + 0], src[a + 1]);
							 | 
						||
| 
								 | 
							
								            dst.push(src[b + 0], src[b + 1]);
							 | 
						||
| 
								 | 
							
								            dst.push(src[c + 0], src[c + 1]);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addDefaultUV: function () {
							 | 
						||
| 
								 | 
							
								            const dst = this.object.geometry.uvs;
							 | 
						||
| 
								 | 
							
								            dst.push(0, 0);
							 | 
						||
| 
								 | 
							
								            dst.push(0, 0);
							 | 
						||
| 
								 | 
							
								            dst.push(0, 0);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addUVLine: function (a) {
							 | 
						||
| 
								 | 
							
								            const src = this.uvs;
							 | 
						||
| 
								 | 
							
								            const dst = this.object.geometry.uvs;
							 | 
						||
| 
								 | 
							
								            dst.push(src[a + 0], src[a + 1]);
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addFace: function (a, b, c, ua, ub, uc, na, nb, nc) {
							 | 
						||
| 
								 | 
							
								            const vLen = this.vertices.length;
							 | 
						||
| 
								 | 
							
								            let ia = this.parseVertexIndex(a, vLen);
							 | 
						||
| 
								 | 
							
								            let ib = this.parseVertexIndex(b, vLen);
							 | 
						||
| 
								 | 
							
								            let ic = this.parseVertexIndex(c, vLen);
							 | 
						||
| 
								 | 
							
								            this.addVertex(ia, ib, ic);
							 | 
						||
| 
								 | 
							
								            this.addColor(ia, ib, ic);
							 | 
						||
| 
								 | 
							
								            if (na !== undefined && na !== '') {
							 | 
						||
| 
								 | 
							
								                const nLen = this.normals.length;
							 | 
						||
| 
								 | 
							
								                ia = this.parseNormalIndex(na, nLen);
							 | 
						||
| 
								 | 
							
								                ib = this.parseNormalIndex(nb, nLen);
							 | 
						||
| 
								 | 
							
								                ic = this.parseNormalIndex(nc, nLen);
							 | 
						||
| 
								 | 
							
								                this.addNormal(ia, ib, ic);
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                this.addFaceNormal(ia, ib, ic);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (ua !== undefined && ua !== '') {
							 | 
						||
| 
								 | 
							
								                const uvLen = this.uvs.length;
							 | 
						||
| 
								 | 
							
								                ia = this.parseUVIndex(ua, uvLen);
							 | 
						||
| 
								 | 
							
								                ib = this.parseUVIndex(ub, uvLen);
							 | 
						||
| 
								 | 
							
								                ic = this.parseUVIndex(uc, uvLen);
							 | 
						||
| 
								 | 
							
								                this.addUV(ia, ib, ic);
							 | 
						||
| 
								 | 
							
								                this.object.geometry.hasUVIndices = true;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                this.addDefaultUV();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addPointGeometry: function (vertices) {
							 | 
						||
| 
								 | 
							
								            this.object.geometry.type = 'Points';
							 | 
						||
| 
								 | 
							
								            const vLen = this.vertices.length;
							 | 
						||
| 
								 | 
							
								            for (let vi = 0, l = vertices.length; vi < l; vi++) {
							 | 
						||
| 
								 | 
							
								                const index = this.parseVertexIndex(vertices[vi], vLen);
							 | 
						||
| 
								 | 
							
								                this.addVertexPoint(index);
							 | 
						||
| 
								 | 
							
								                this.addColor(index);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        addLineGeometry: function (vertices, uvs) {
							 | 
						||
| 
								 | 
							
								            this.object.geometry.type = 'Line';
							 | 
						||
| 
								 | 
							
								            const vLen = this.vertices.length;
							 | 
						||
| 
								 | 
							
								            const uvLen = this.uvs.length;
							 | 
						||
| 
								 | 
							
								            for (let vi = 0, l = vertices.length; vi < l; vi++) {
							 | 
						||
| 
								 | 
							
								                this.addVertexLine(this.parseVertexIndex(vertices[vi], vLen));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            for (let uvi = 0, l = uvs.length; uvi < l; uvi++) {
							 | 
						||
| 
								 | 
							
								                this.addUVLine(this.parseUVIndex(uvs[uvi], uvLen));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    state.startObject('', false);
							 | 
						||
| 
								 | 
							
								    return state;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class AModelLoader {
							 | 
						||
| 
								 | 
							
								    constructor(context) {
							 | 
						||
| 
								 | 
							
								        this.context = context;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 异步调用
							 | 
						||
| 
								 | 
							
								     * @param {*} url
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    Load(url) {
							 | 
						||
| 
								 | 
							
								        //解析obj数据
							 | 
						||
| 
								 | 
							
								        return Cesium.Resource.fetchText(url).then((result) => {
							 | 
						||
| 
								 | 
							
								            return this.Parse(result, url.substring(0, url.lastIndexOf('/') + 1));
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Parse(text, path) {
							 | 
						||
| 
								 | 
							
								        const state = new ParserState();
							 | 
						||
| 
								 | 
							
								        if (text.indexOf('\r\n') !== -1) {
							 | 
						||
| 
								 | 
							
								            text = text.replace(/\r\n/g, '\n');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (text.indexOf('\\\n') !== -1) {
							 | 
						||
| 
								 | 
							
								            text = text.replace(/\\\n/g, '');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        const lines = text.split('\n');
							 | 
						||
| 
								 | 
							
								        let result = [];
							 | 
						||
| 
								 | 
							
								        for (let i = 0, l = lines.length; i < l; i++) {
							 | 
						||
| 
								 | 
							
								            const line = lines[i].trimStart();
							 | 
						||
| 
								 | 
							
								            if (line.length === 0) continue;
							 | 
						||
| 
								 | 
							
								            const lineFirstChar = line.charAt(0);
							 | 
						||
| 
								 | 
							
								            if (lineFirstChar === '#') continue;
							 | 
						||
| 
								 | 
							
								            if (lineFirstChar === 'v') {
							 | 
						||
| 
								 | 
							
								                const data = line.split(_face_vertex_data_separator_pattern);
							 | 
						||
| 
								 | 
							
								                switch (data[0]) {
							 | 
						||
| 
								 | 
							
								                    case 'v':
							 | 
						||
| 
								 | 
							
								                        state.vertices.push(
							 | 
						||
| 
								 | 
							
								                            parseFloat(data[1]),
							 | 
						||
| 
								 | 
							
								                            parseFloat(data[2]),
							 | 
						||
| 
								 | 
							
								                            parseFloat(data[3])
							 | 
						||
| 
								 | 
							
								                        );
							 | 
						||
| 
								 | 
							
								                        if (data.length >= 7) {
							 | 
						||
| 
								 | 
							
								                            Cesium.Color.fromBytes(
							 | 
						||
| 
								 | 
							
								                                parseFloat(data[4]),
							 | 
						||
| 
								 | 
							
								                                parseFloat(data[5]),
							 | 
						||
| 
								 | 
							
								                                parseFloat(data[6]),
							 | 
						||
| 
								 | 
							
								                                1,
							 | 
						||
| 
								 | 
							
								                                _color
							 | 
						||
| 
								 | 
							
								                            );
							 | 
						||
| 
								 | 
							
								                            state.colors.push(_color.red, _color.green, _color.blue);
							 | 
						||
| 
								 | 
							
								                        } else {
							 | 
						||
| 
								 | 
							
								                            state.colors.push(undefined, undefined, undefined);
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    case 'vn':
							 | 
						||
| 
								 | 
							
								                        state.normals.push(
							 | 
						||
| 
								 | 
							
								                            parseFloat(data[1]),
							 | 
						||
| 
								 | 
							
								                            parseFloat(data[2]),
							 | 
						||
| 
								 | 
							
								                            parseFloat(data[3])
							 | 
						||
| 
								 | 
							
								                        );
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    case 'vt':
							 | 
						||
| 
								 | 
							
								                        state.uvs.push(
							 | 
						||
| 
								 | 
							
								                            parseFloat(data[1]),
							 | 
						||
| 
								 | 
							
								                            parseFloat(data[2])
							 | 
						||
| 
								 | 
							
								                        );
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if (lineFirstChar === 'f') {
							 | 
						||
| 
								 | 
							
								                const lineData = line.slice(1).trim();
							 | 
						||
| 
								 | 
							
								                const vertexData = lineData.split(_face_vertex_data_separator_pattern);
							 | 
						||
| 
								 | 
							
								                const faceVertices = [];
							 | 
						||
| 
								 | 
							
								                for (let j = 0, jl = vertexData.length; j < jl; j++) {
							 | 
						||
| 
								 | 
							
								                    const vertex = vertexData[j];
							 | 
						||
| 
								 | 
							
								                    if (vertex.length > 0) {
							 | 
						||
| 
								 | 
							
								                        const vertexParts = vertex.split('/');
							 | 
						||
| 
								 | 
							
								                        faceVertices.push(vertexParts);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                const v1 = faceVertices[0];
							 | 
						||
| 
								 | 
							
								                for (let j = 1, jl = faceVertices.length - 1; j < jl; j++) {
							 | 
						||
| 
								 | 
							
								                    const v2 = faceVertices[j];
							 | 
						||
| 
								 | 
							
								                    const v3 = faceVertices[j + 1];
							 | 
						||
| 
								 | 
							
								                    state.addFace(
							 | 
						||
| 
								 | 
							
								                        v1[0], v2[0], v3[0],
							 | 
						||
| 
								 | 
							
								                        v1[1], v2[1], v3[1],
							 | 
						||
| 
								 | 
							
								                        v1[2], v2[2], v3[2]
							 | 
						||
| 
								 | 
							
								                    );
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } else if (lineFirstChar === 'l') {
							 | 
						||
| 
								 | 
							
								                const lineParts = line.substring(1).trim().split(' ');
							 | 
						||
| 
								 | 
							
								                let lineVertices = [];
							 | 
						||
| 
								 | 
							
								                const lineUVs = [];
							 | 
						||
| 
								 | 
							
								                if (line.indexOf('/') === -1) {
							 | 
						||
| 
								 | 
							
								                    lineVertices = lineParts;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    for (let li = 0, llen = lineParts.length; li < llen; li++) {
							 | 
						||
| 
								 | 
							
								                        const parts = lineParts[li].split('/');
							 | 
						||
| 
								 | 
							
								                        if (parts[0] !== '') lineVertices.push(parts[0]);
							 | 
						||
| 
								 | 
							
								                        if (parts[1] !== '') lineUVs.push(parts[1]);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                state.addLineGeometry(lineVertices, lineUVs);
							 | 
						||
| 
								 | 
							
								            } else if (lineFirstChar === 'p') {
							 | 
						||
| 
								 | 
							
								                const lineData = line.slice(1).trim();
							 | 
						||
| 
								 | 
							
								                const pointData = lineData.split(' ');
							 | 
						||
| 
								 | 
							
								                state.addPointGeometry(pointData);
							 | 
						||
| 
								 | 
							
								            } else if ((result = _object_pattern.exec(line)) !== null) {
							 | 
						||
| 
								 | 
							
								                const name = (' ' + result[0].slice(1).trim()).slice(1);
							 | 
						||
| 
								 | 
							
								                state.startObject(name);
							 | 
						||
| 
								 | 
							
								            } else if (_material_use_pattern.test(line)) {
							 | 
						||
| 
								 | 
							
								                state.object.startMaterial(line.substring(7).trim(), state.materialLibraries);
							 | 
						||
| 
								 | 
							
								            } else if (_material_library_pattern.test(line)) {
							 | 
						||
| 
								 | 
							
								                state.materialLibraries.push(line.substring(7).trim());
							 | 
						||
| 
								 | 
							
								            } else if (_map_use_pattern.test(line)) {
							 | 
						||
| 
								 | 
							
								                console.warn('Rendering identifier "usemap" not supported. Textures must be defined in MTL files.');
							 | 
						||
| 
								 | 
							
								            } else if (lineFirstChar === 's') {
							 | 
						||
| 
								 | 
							
								                result = line.split(' ');
							 | 
						||
| 
								 | 
							
								                if (result.length > 1) {
							 | 
						||
| 
								 | 
							
								                    const value = result[1].trim().toLowerCase();
							 | 
						||
| 
								 | 
							
								                    state.object.smooth = (value !== '0' && value !== 'off');
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    state.object.smooth = true;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                const material = state.object.currentMaterial();
							 | 
						||
| 
								 | 
							
								                if (material) material.smooth = state.object.smooth;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                if (line === '\0') continue;
							 | 
						||
| 
								 | 
							
								                console.warn('Unexpected line: "' + line + '"');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        state.finalize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const container = new Node();
							 | 
						||
| 
								 | 
							
								        const hasPrimitives = !(state.objects.length === 1 && state.objects[0].geometry.vertices.length === 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (hasPrimitives === true) {
							 | 
						||
| 
								 | 
							
								            for (let i = 0, l = state.objects.length; i < l; i++) {
							 | 
						||
| 
								 | 
							
								                const object = state.objects[i];
							 | 
						||
| 
								 | 
							
								                const geometry = object.geometry;
							 | 
						||
| 
								 | 
							
								                const materials = object.materials;
							 | 
						||
| 
								 | 
							
								                if (geometry.vertices.length === 0) continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                let mesh = new Mesh(this.context, geometry);
							 | 
						||
| 
								 | 
							
								                for (let mi = 0, miLen = materials.length; mi < miLen; mi++) {
							 | 
						||
| 
								 | 
							
								                    const sourceMaterial = materials[mi];
							 | 
						||
| 
								 | 
							
								                    const materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_';
							 | 
						||
| 
								 | 
							
								                    let material = state.materials[materialHash];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (this.materials !== null) {
							 | 
						||
| 
								 | 
							
								                        console.log("material");
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if (material === undefined) {
							 | 
						||
| 
								 | 
							
								                        material = new Material(this.context, geometry, path, sourceMaterial.mtllib);
							 | 
						||
| 
								 | 
							
								                        material.name = sourceMaterial.name;
							 | 
						||
| 
								 | 
							
								                        material.flatShading = sourceMaterial.smooth ? false : true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                        state.materials[materialHash] = material;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    mesh.setMaterial(material);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                mesh.name = object.name;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                container.add(mesh);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return container;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Material {
							 | 
						||
| 
								 | 
							
								    constructor(context, geometry, path, mtllib) {
							 | 
						||
| 
								 | 
							
								        this.context = context;
							 | 
						||
| 
								 | 
							
								        this.ready = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const canvas = document.createElement("canvas");
							 | 
						||
| 
								 | 
							
								        canvas.width = 512; //默认
							 | 
						||
| 
								 | 
							
								        canvas.height = 512; //默认
							 | 
						||
| 
								 | 
							
								        this.canvas = canvas;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        let promise = Cesium.Resource.fetchText(path + mtllib)
							 | 
						||
| 
								 | 
							
								            .then(async (text) => {
							 | 
						||
| 
								 | 
							
								                let result = [];
							 | 
						||
| 
								 | 
							
								                const lines = text.split('\n');
							 | 
						||
| 
								 | 
							
								                for (let i = 0, l = lines.length; i < l; i++) {
							 | 
						||
| 
								 | 
							
								                    const line = lines[i].trimStart();
							 | 
						||
| 
								 | 
							
								                    if (line.length === 0) continue;
							 | 
						||
| 
								 | 
							
								                    const t = line.split(' ')[0];
							 | 
						||
| 
								 | 
							
								                    if (t === "map_Kd") {
							 | 
						||
| 
								 | 
							
								                        let map = line.split(' ')[1];
							 | 
						||
| 
								 | 
							
								                        result.push({
							 | 
						||
| 
								 | 
							
								                            diffusemap: await this.loadTexture(path + map)
							 | 
						||
| 
								 | 
							
								                        })
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                return Promise.all(result);
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //创建shader
							 | 
						||
| 
								 | 
							
								        let vs = "attribute vec3 position;\n";
							 | 
						||
| 
								 | 
							
								        let fs = "";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        let outVS = "";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        let hasNormal = false;
							 | 
						||
| 
								 | 
							
								        let hasVertexColors = false;
							 | 
						||
| 
								 | 
							
								        let hasSt = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (geometry.normals.length > 0) {
							 | 
						||
| 
								 | 
							
								            hasNormal = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        //顶点色
							 | 
						||
| 
								 | 
							
								        if (geometry.colors.length > 0) {
							 | 
						||
| 
								 | 
							
								            hasVertexColors = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // UV
							 | 
						||
| 
								 | 
							
								        if (geometry.hasUVIndices === true) {
							 | 
						||
| 
								 | 
							
								            hasSt = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (hasNormal) {
							 | 
						||
| 
								 | 
							
								            vs += "attribute vec3 normal;\n";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            vs += "varying vec3 v_normal;\n";
							 | 
						||
| 
								 | 
							
								            fs += "varying vec3 v_normal;\n";
							 | 
						||
| 
								 | 
							
								            outVS += "v_normal = normal;\n";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (hasVertexColors) {
							 | 
						||
| 
								 | 
							
								            vs += "attribute vec3 color;\n";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            vs += "varying vec2 v_color;\n";
							 | 
						||
| 
								 | 
							
								            fs += "varying vec2 v_color;\n";
							 | 
						||
| 
								 | 
							
								            outVS += "v_color = color;\n";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (hasSt) {
							 | 
						||
| 
								 | 
							
								            vs += "attribute vec2 uv;\n";
							 | 
						||
| 
								 | 
							
								            vs += "varying vec2 v_uv;\n";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            fs += "varying vec2 v_uv;\n";
							 | 
						||
| 
								 | 
							
								            outVS += "v_uv = uv;\n";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        vs += `
							 | 
						||
| 
								 | 
							
								        void main() {
							 | 
						||
| 
								 | 
							
								            gl_Position = czm_modelViewProjection * vec4(position, 1.);
							 | 
						||
| 
								 | 
							
								            ${outVS}
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        `;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        fs += `
							 | 
						||
| 
								 | 
							
										uniform sampler2D colorTexture;
							 | 
						||
| 
								 | 
							
								        void main() {
							 | 
						||
| 
								 | 
							
											vec4 color = texture2D(colorTexture, v_uv);
							 | 
						||
| 
								 | 
							
								            gl_FragColor = color;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        `;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        this.program = Cesium.ShaderProgram.fromCache({
							 | 
						||
| 
								 | 
							
								            context: context,
							 | 
						||
| 
								 | 
							
								            vertexShaderSource: vs,
							 | 
						||
| 
								 | 
							
								            fragmentShaderSource: fs
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        this.uniformMap = {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        let that = this;
							 | 
						||
| 
								 | 
							
								        promise.then((images) => {
							 | 
						||
| 
								 | 
							
								            for (let i = 0; i < images.length; i++) {
							 | 
						||
| 
								 | 
							
								                const element = images[i];
							 | 
						||
| 
								 | 
							
								                let diffusemap = element.diffusemap;
							 | 
						||
| 
								 | 
							
								                this.uniformMap.colorTexture = () => {
							 | 
						||
| 
								 | 
							
								                    return diffusemap;
							 | 
						||
| 
								 | 
							
								                };
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            that.ready = true;
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    updateColorTexture(video, width, height) {
							 | 
						||
| 
								 | 
							
								        if (this.ready && Cesium.defined(video.videojs)) {
							 | 
						||
| 
								 | 
							
								            video.videojs.play();
							 | 
						||
| 
								 | 
							
								            let colorTexture = this.uniformMap.colorTexture();
							 | 
						||
| 
								 | 
							
								            if (video.playing && video.timeupdate) {
							 | 
						||
| 
								 | 
							
								                if (width !== colorTexture.width || height !== colorTexture.height) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    this.canvas.width = width;
							 | 
						||
| 
								 | 
							
								                    this.canvas.height = height;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    // 重新创建texture
							 | 
						||
| 
								 | 
							
								                    const canvasContext = this.canvas.getContext("2d");
							 | 
						||
| 
								 | 
							
								                    canvasContext.drawImage(
							 | 
						||
| 
								 | 
							
								                        video.dom,
							 | 
						||
| 
								 | 
							
								                        0,
							 | 
						||
| 
								 | 
							
								                        0,
							 | 
						||
| 
								 | 
							
								                        video.width,
							 | 
						||
| 
								 | 
							
								                        video.height,
							 | 
						||
| 
								 | 
							
								                        0,
							 | 
						||
| 
								 | 
							
								                        0,
							 | 
						||
| 
								 | 
							
								                        this.canvas.width,
							 | 
						||
| 
								 | 
							
								                        this.canvas.height
							 | 
						||
| 
								 | 
							
								                    );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    let texture = new Cesium.Texture({
							 | 
						||
| 
								 | 
							
								                        context: this.context,
							 | 
						||
| 
								 | 
							
								                        source: this.canvas
							 | 
						||
| 
								 | 
							
								                    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    this.uniformMap.colorTexture = () => {
							 | 
						||
| 
								 | 
							
								                        return texture;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                const canvasContext = this.canvas.getContext("2d");
							 | 
						||
| 
								 | 
							
								                canvasContext.drawImage(
							 | 
						||
| 
								 | 
							
								                    video.dom,
							 | 
						||
| 
								 | 
							
								                    0,
							 | 
						||
| 
								 | 
							
								                    0,
							 | 
						||
| 
								 | 
							
								                    video.width,
							 | 
						||
| 
								 | 
							
								                    video.height,
							 | 
						||
| 
								 | 
							
								                    0,
							 | 
						||
| 
								 | 
							
								                    0,
							 | 
						||
| 
								 | 
							
								                    this.canvas.width,
							 | 
						||
| 
								 | 
							
								                    this.canvas.height
							 | 
						||
| 
								 | 
							
								                );
							 | 
						||
| 
								 | 
							
								                this.uniformMap.colorTexture().copyFrom({
							 | 
						||
| 
								 | 
							
								                    source: this.canvas
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    setCommand(drawCommand) {
							 | 
						||
| 
								 | 
							
								        drawCommand.shaderProgram = this.program;
							 | 
						||
| 
								 | 
							
								        drawCommand.uniformMap = this.uniformMap;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    loadTexture(url) {
							 | 
						||
| 
								 | 
							
								        return Cesium.Resource.fetchImage(url)
							 | 
						||
| 
								 | 
							
								            .then((image) => {
							 | 
						||
| 
								 | 
							
								                this.canvas.width = image.width;
							 | 
						||
| 
								 | 
							
								                this.canvas.height = image.height;
							 | 
						||
| 
								 | 
							
								                const canvasContext = this.canvas.getContext("2d");
							 | 
						||
| 
								 | 
							
								                canvasContext.drawImage(
							 | 
						||
| 
								 | 
							
								                    image,
							 | 
						||
| 
								 | 
							
								                    0,
							 | 
						||
| 
								 | 
							
								                    0,
							 | 
						||
| 
								 | 
							
								                    image.width,
							 | 
						||
| 
								 | 
							
								                    image.height,
							 | 
						||
| 
								 | 
							
								                    0,
							 | 
						||
| 
								 | 
							
								                    0,
							 | 
						||
| 
								 | 
							
								                    this.canvas.width,
							 | 
						||
| 
								 | 
							
								                    this.canvas.height,
							 | 
						||
| 
								 | 
							
								                );
							 | 
						||
| 
								 | 
							
								                let texture = new Cesium.Texture({
							 | 
						||
| 
								 | 
							
								                    context: this.context,
							 | 
						||
| 
								 | 
							
								                    source: this.canvas,
							 | 
						||
| 
								 | 
							
								                    sampler: Cesium.Sampler.NEAREST
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								                return texture;
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Mesh {
							 | 
						||
| 
								 | 
							
								    constructor(context, geometry) {
							 | 
						||
| 
								 | 
							
								        this.name = undefined;
							 | 
						||
| 
								 | 
							
								        this.geometry = geometry;
							 | 
						||
| 
								 | 
							
								        const vaAttributes = [];
							 | 
						||
| 
								 | 
							
								        let index = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        this.material = undefined;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //创建顶点索引
							 | 
						||
| 
								 | 
							
								        const vertexBuffer = Cesium.Buffer.createVertexBuffer({
							 | 
						||
| 
								 | 
							
								            context: context,
							 | 
						||
| 
								 | 
							
								            typedArray: Cesium.ComponentDatatype.createTypedArray(Cesium.ComponentDatatype.FLOAT, geometry.vertices),
							 | 
						||
| 
								 | 
							
								            usage: Cesium.BufferUsage.STATIC_DRAW
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        vaAttributes.push({
							 | 
						||
| 
								 | 
							
								            index: index,
							 | 
						||
| 
								 | 
							
								            enabled: true,
							 | 
						||
| 
								 | 
							
								            vertexBuffer: vertexBuffer,
							 | 
						||
| 
								 | 
							
								            componentDatatype: Cesium.ComponentDatatype.FLOAT,
							 | 
						||
| 
								 | 
							
								            componentsPerAttribute: 3,
							 | 
						||
| 
								 | 
							
								            normalize: false
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        //法线
							 | 
						||
| 
								 | 
							
								        if (geometry.normals.length > 0) {
							 | 
						||
| 
								 | 
							
								            index++;
							 | 
						||
| 
								 | 
							
								            const normalBuffer = Cesium.Buffer.createVertexBuffer({
							 | 
						||
| 
								 | 
							
								                context: context,
							 | 
						||
| 
								 | 
							
								                typedArray: Cesium.ComponentDatatype.createTypedArray(Cesium.ComponentDatatype.FLOAT, geometry.normals),
							 | 
						||
| 
								 | 
							
								                usage: Cesium.BufferUsage.STATIC_DRAW
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            vaAttributes.push({
							 | 
						||
| 
								 | 
							
								                index: index,
							 | 
						||
| 
								 | 
							
								                enabled: true,
							 | 
						||
| 
								 | 
							
								                vertexBuffer: normalBuffer,
							 | 
						||
| 
								 | 
							
								                componentDatatype: Cesium.ComponentDatatype.FLOAT,
							 | 
						||
| 
								 | 
							
								                componentsPerAttribute: 3,
							 | 
						||
| 
								 | 
							
								                normalize: false
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        //顶点色
							 | 
						||
| 
								 | 
							
								        if (geometry.colors.length > 0) {
							 | 
						||
| 
								 | 
							
								            index++;
							 | 
						||
| 
								 | 
							
								            const colorBuffer = Cesium.Buffer.createVertexBuffer({
							 | 
						||
| 
								 | 
							
								                context: context,
							 | 
						||
| 
								 | 
							
								                typedArray: Cesium.ComponentDatatype.createTypedArray(Cesium.ComponentDatatype.FLOAT, geometry.colors),
							 | 
						||
| 
								 | 
							
								                usage: Cesium.BufferUsage.STATIC_DRAW
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            vaAttributes.push({
							 | 
						||
| 
								 | 
							
								                index: index,
							 | 
						||
| 
								 | 
							
								                enabled: true,
							 | 
						||
| 
								 | 
							
								                vertexBuffer: colorBuffer,
							 | 
						||
| 
								 | 
							
								                componentDatatype: Cesium.ComponentDatatype.FLOAT,
							 | 
						||
| 
								 | 
							
								                componentsPerAttribute: 3,
							 | 
						||
| 
								 | 
							
								                normalize: false
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // UV
							 | 
						||
| 
								 | 
							
								        if (geometry.hasUVIndices === true) {
							 | 
						||
| 
								 | 
							
								            index++;
							 | 
						||
| 
								 | 
							
								            const uvBuffer = Cesium.Buffer.createVertexBuffer({
							 | 
						||
| 
								 | 
							
								                context: context,
							 | 
						||
| 
								 | 
							
								                typedArray: Cesium.ComponentDatatype.createTypedArray(Cesium.ComponentDatatype.FLOAT, geometry.uvs),
							 | 
						||
| 
								 | 
							
								                usage: Cesium.BufferUsage.STATIC_DRAW
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            vaAttributes.push({
							 | 
						||
| 
								 | 
							
								                index: index,
							 | 
						||
| 
								 | 
							
								                enabled: true,
							 | 
						||
| 
								 | 
							
								                vertexBuffer: uvBuffer,
							 | 
						||
| 
								 | 
							
								                componentDatatype: Cesium.ComponentDatatype.FLOAT,
							 | 
						||
| 
								 | 
							
								                componentsPerAttribute: 2,
							 | 
						||
| 
								 | 
							
								                normalize: false
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const vertexArray = new Cesium.VertexArray({
							 | 
						||
| 
								 | 
							
								            context: context,
							 | 
						||
| 
								 | 
							
								            attributes: vaAttributes
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const renderState = Cesium.RenderState.fromCache({
							 | 
						||
| 
								 | 
							
								            cull: {
							 | 
						||
| 
								 | 
							
								                enabled: false
							 | 
						||
| 
								 | 
							
								            },
							 | 
						||
| 
								 | 
							
								            depthMask: true,
							 | 
						||
| 
								 | 
							
								            depthTest: {
							 | 
						||
| 
								 | 
							
								                enabled: true,
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        this.drawCommand = new Cesium.DrawCommand({
							 | 
						||
| 
								 | 
							
								            owner: this,
							 | 
						||
| 
								 | 
							
								            primitiveType: Cesium.PrimitiveType.TRIANGLES,
							 | 
						||
| 
								 | 
							
								            vertexArray: vertexArray,
							 | 
						||
| 
								 | 
							
								            renderState: renderState,
							 | 
						||
| 
								 | 
							
								            pass: Cesium.Pass.OPAQUE,
							 | 
						||
| 
								 | 
							
								            // debugShowBoundingVolume: true
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    setMaterial(material) {
							 | 
						||
| 
								 | 
							
								        this.material = material;
							 | 
						||
| 
								 | 
							
								        material.setCommand(this.drawCommand);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    update(frameState) {
							 | 
						||
| 
								 | 
							
								        if (Cesium.defined(this.material)) {
							 | 
						||
| 
								 | 
							
								            if (this.material.ready) {
							 | 
						||
| 
								 | 
							
								                frameState.commandList.push(this.drawCommand);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    updateVideo(camera, video, cullingVolume) {
							 | 
						||
| 
								 | 
							
								        if (Cesium.defined(this.material)) {
							 | 
						||
| 
								 | 
							
								            if (this.material.ready) {
							 | 
						||
| 
								 | 
							
								                const visibility = cullingVolume.computeVisibility(this.drawCommand.boundingVolume);
							 | 
						||
| 
								 | 
							
								                if (visibility >= 0 && this.material.ready) {
							 | 
						||
| 
								 | 
							
								                    //如果视频可见
							 | 
						||
| 
								 | 
							
								                    //计算level
							 | 
						||
| 
								 | 
							
								                    // cam
							 | 
						||
| 
								 | 
							
								                    let distance = camera.distanceToBoundingSphere(this.drawCommand.boundingVolume);
							 | 
						||
| 
								 | 
							
								                    let width = video.width;
							 | 
						||
| 
								 | 
							
								                    let height = video.height;
							 | 
						||
| 
								 | 
							
								                    if (distance >= 20 && distance < 100) {
							 | 
						||
| 
								 | 
							
								                        width = video.width / 2;
							 | 
						||
| 
								 | 
							
								                        height = video.height / 2;
							 | 
						||
| 
								 | 
							
								                    } else if (distance >= 100) {
							 | 
						||
| 
								 | 
							
								                        width = video.width / 10;
							 | 
						||
| 
								 | 
							
								                        height = video.height / 10;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    this.material.updateColorTexture(video, width, height)
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    if (video.videojs) {
							 | 
						||
| 
								 | 
							
								                        video.videojs.pause();
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Node {
							 | 
						||
| 
								 | 
							
								    constructor() {
							 | 
						||
| 
								 | 
							
								        this._modelMatrix = Cesium.Matrix4.IDENTITY;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        this.parent = null;
							 | 
						||
| 
								 | 
							
								        this.children = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        this.video = {
							 | 
						||
| 
								 | 
							
								            videojs: null,
							 | 
						||
| 
								 | 
							
								            dom: null,
							 | 
						||
| 
								 | 
							
								            playing: false,
							 | 
						||
| 
								 | 
							
								            timeupdate: false,
							 | 
						||
| 
								 | 
							
								            width: 0,
							 | 
						||
| 
								 | 
							
								            height: 0
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    get modelMatrix() {
							 | 
						||
| 
								 | 
							
								        return this._modelMatrix;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    set modelMatrix(matrix) {
							 | 
						||
| 
								 | 
							
								        this._modelMatrix = matrix.clone();
							 | 
						||
| 
								 | 
							
								        this.updateModelMatrix();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    updateModelMatrix() {
							 | 
						||
| 
								 | 
							
								        for (let i = 0; i < this.children.length; i++) {
							 | 
						||
| 
								 | 
							
								            const child = this.children[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            child.drawCommand.modelMatrix = this._modelMatrix;
							 | 
						||
| 
								 | 
							
								            //计算包围盒
							 | 
						||
| 
								 | 
							
								            const sphere = Cesium.BoundingSphere.fromVertices(child.geometry.vertices);
							 | 
						||
| 
								 | 
							
								            let newMat = Cesium.Matrix4.multiplyByTranslation(this._modelMatrix, sphere.center, new Cesium.Matrix4());
							 | 
						||
| 
								 | 
							
								            sphere.center = Cesium.Matrix4.getTranslation(newMat, new Cesium.Cartesian3());
							 | 
						||
| 
								 | 
							
								            child.drawCommand.boundingVolume = sphere;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    setPosition(position) {
							 | 
						||
| 
								 | 
							
								        Cesium.Matrix4.multiplyByTranslation(this._modelMatrix, position, this._modelMatrix);
							 | 
						||
| 
								 | 
							
								        this.updateModelMatrix();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    add(object) {
							 | 
						||
| 
								 | 
							
								        object.parent = this;
							 | 
						||
| 
								 | 
							
								        this.children.push(object);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    update(frameState) {
							 | 
						||
| 
								 | 
							
								        let camera = frameState.camera;
							 | 
						||
| 
								 | 
							
								        const cullingVolume = camera.frustum.computeCullingVolume(
							 | 
						||
| 
								 | 
							
								            camera.positionWC,
							 | 
						||
| 
								 | 
							
								            camera.directionWC,
							 | 
						||
| 
								 | 
							
								            camera.upWC
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (let i = 0; i < this.children.length; i++) {
							 | 
						||
| 
								 | 
							
								            const child = this.children[i];
							 | 
						||
| 
								 | 
							
								            child.update(frameState);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (Cesium.defined(this.video.videojs)) {
							 | 
						||
| 
								 | 
							
								                child.updateVideo(camera, this.video, cullingVolume);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 设置视频
							 | 
						||
| 
								 | 
							
								     * @param {*} url
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    setVideo(url) {
							 | 
						||
| 
								 | 
							
								        this.video.playing = false;
							 | 
						||
| 
								 | 
							
								        this.video.timeupdate = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        let videoType = /^.+\.m3u8$/.test(url) ? "application/x-mpegURL" : "video/mp4";
							 | 
						||
| 
								 | 
							
								        if (!Cesium.defined(this.video.videojs)) {
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            const video = document.createElement('video');
							 | 
						||
| 
								 | 
							
								            video.setAttribute("id", "video_" + Cesium.createGuid());
							 | 
						||
| 
								 | 
							
								            video.setAttribute('crossorigin', 'anonymous');
							 | 
						||
| 
								 | 
							
								            video.setAttribute('muted', '');
							 | 
						||
| 
								 | 
							
								            // video.muted = true;
							 | 
						||
| 
								 | 
							
								            video.autoplay = true;
							 | 
						||
| 
								 | 
							
								            video.loop = true;
							 | 
						||
| 
								 | 
							
								            video.preload = "auto";
							 | 
						||
| 
								 | 
							
								            video.style.display = 'none';
							 | 
						||
| 
								 | 
							
								            video.width = 512;
							 | 
						||
| 
								 | 
							
								            video.height = 512;
							 | 
						||
| 
								 | 
							
								            video.style.objectFit = 'fill'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            this.video.videojs = videojs(video, {
							 | 
						||
| 
								 | 
							
								                techOrder: ['html5']
							 | 
						||
| 
								 | 
							
								            }, () => {
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            video.addEventListener('playing', () => {
							 | 
						||
| 
								 | 
							
								                // console.log(video.videoWidth)
							 | 
						||
| 
								 | 
							
								                // //获取video 宽高
							 | 
						||
| 
								 | 
							
								                this.video.width = video.videoWidth;
							 | 
						||
| 
								 | 
							
								                this.video.height = video.videoHeight;
							 | 
						||
| 
								 | 
							
								                this.video.playing = true;
							 | 
						||
| 
								 | 
							
								            }, true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            video.addEventListener('timeupdate', () => {
							 | 
						||
| 
								 | 
							
								                this.video.timeupdate = true;
							 | 
						||
| 
								 | 
							
								            }, true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            this.video.dom = video;
							 | 
						||
| 
								 | 
							
								            // document.body.appendChild(video)
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        this.video.videojs.src([{
							 | 
						||
| 
								 | 
							
								            src: url,
							 | 
						||
| 
								 | 
							
								            type: videoType
							 | 
						||
| 
								 | 
							
								        }]);
							 | 
						||
| 
								 | 
							
								        this.video.videojs.play();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |