UNPKG

awv3

Version:
202 lines (174 loc) 7.77 kB
import * as THREE from 'three'; import Defaults from './defaults'; export function parseLine(data, context) { let { options } = context; let { id, line: { groups } } = data; // Create mesh let geom = new THREE.LineSegments(); geom.renderOrder = options.renderOrder.LineSegments; geom.userData = { id: 0, parentId: id, refs: groups.map(group => group.meta) }; // Create geometry geom.geometry = new THREE.BufferGeometry(); geom.geometry.addAttribute('position', new THREE.BufferAttribute(data.line.vertices, 3)); geom.geometry.groups = []; // lineDistances have to apply to the entire object if a single dashed material is among it, it can't be // set in a groups scope individually data.line.distances && geom.geometry.addAttribute('lineDistance', new THREE.BufferAttribute(data.line.distances, 1)); if (options.materials.multi) { geom.material = groups.map(group => { convertVectors(group.meta); geom.geometry.groups.push({ start: group.start / 3, count: group.count / 3, materialIndex: group.index, meta: group.meta, }); let lineShader = options.lineShader; let lineOptions = options.lineShaderOptions; if (group.meta.material.linetype === 'DASHED') { lineShader = THREE.LineDashedMaterial; lineOptions = { ...lineOptions, dashSize: 2, gapSize: 2, }; } group.meta.material.color = lineOptions.color || new THREE.Color(...group.meta.material.color); group.meta.material.opacity = typeof lineOptions.opacity !== 'undefined' ? lineOptions.opacity : group.meta.material.opacity; let material = new lineShader({ ...lineOptions, color: group.meta.material.color, opacity: group.meta.material.opacity, }); material.meta = group.meta; material.parent = geom; return material; }); } else { data.properties.material.color = options.lineShaderOptions.color || data.properties.material.color; data.properties.material.opacity = typeof options.lineShaderOptions.opacity !== 'undefined' ? options.lineShaderOptions.opacity : data.properties.material.opacity; geom.material = new options.lineShader({ ...options.lineShaderOptions, color: data.properties.material.color, opacity: data.properties.material.opacity, }); geom.material.parent = geom; } return finalize(geom, data, groups); } export function parseMesh(data, context) { let { options } = context; let { id, mesh: { groups } } = data; // Create mesh let geom = new THREE.Mesh(); if (options.materials.shadows) { geom.castShadow = true; geom.receiveShadow = true; } geom.renderOrder = options.renderOrder.Mesh; geom.userData = { id: 0, parentId: id, refs: groups.map(group => group.meta) }; // Create geometry if (options.materials.multi) { geom.geometry = new THREE.Geometry(); for (let index = 0, length = data.mesh.vertices.length / 3; index < length; index++) geom.geometry.vertices.push( new THREE.Vector3( data.mesh.vertices[index * 3 + 0], data.mesh.vertices[index * 3 + 1], data.mesh.vertices[index * 3 + 2], ), ); let i1, i2, i3, normal, groupCount = 0; let group = groups[groupCount++]; for (let index = 0, length = data.mesh.indices.length / 3; index < length; index++) { if (group.start + group.count <= index * 3) group = groups[groupCount++]; i1 = data.mesh.indices[index * 3 + 0]; i2 = data.mesh.indices[index * 3 + 1]; i3 = data.mesh.indices[index * 3 + 2]; normal = data.mesh.normals ? [ new THREE.Vector3( data.mesh.normals[i1 * 3 + 0], data.mesh.normals[i1 * 3 + 1], data.mesh.normals[i1 * 3 + 2], ), new THREE.Vector3( data.mesh.normals[i2 * 3 + 0], data.mesh.normals[i2 * 3 + 1], data.mesh.normals[i2 * 3 + 2], ), new THREE.Vector3( data.mesh.normals[i3 * 3 + 0], data.mesh.normals[i3 * 3 + 1], data.mesh.normals[i3 * 3 + 2], ), ] : undefined; geom.geometry.faces.push(new THREE.Face3(i1, i2, i3, normal, undefined, group.index)); } if (!data.mesh.normals) geom.geometry.computeVertexNormals(); } else { geom.geometry = new THREE.BufferGeometry(); geom.geometry.addAttribute('position', new THREE.BufferAttribute(data.mesh.vertices, 3)); geom.geometry.setIndex(new THREE.BufferAttribute(data.mesh.indices, 1)); if (!!data.mesh.normals) geom.geometry.addAttribute('normal', new THREE.BufferAttribute(data.mesh.normals, 3)); else geom.geometry.computeVertexNormals(); !!data.mesh.uvs && geom.geometry.addAttribute('uv', new THREE.BufferAttribute(data.mesh.uvs, 2)); } // Create materials if (options.materials.multi) { geom.material = groups.map(group => { convertVectors(group.meta); group.meta.material.color = options.meshShaderOptions.color || new THREE.Color(...group.meta.material.color); group.meta.material.opacity = typeof options.meshShaderOptions.opacity !== 'undefined' ? options.meshShaderOptions.opacity : group.meta.material.opacity; let material = new options.meshShader({ ...options.meshShaderOptions, color: group.meta.material.color, opacity: group.meta.material.opacity, }); material.meta = group.meta; material.parent = geom; return material; }); } else { data.properties.material.color = options.meshShaderOptions.color || data.properties.material.color; data.properties.material.opacity = typeof options.meshShaderOptions.opacity !== 'undefined' ? options.meshShaderOptions.opacity : data.properties.material.opacity; geom.material = new options.meshShader({ ...options.meshShaderOptions, ...data.properties.material, color: data.properties.material.color, opacity: data.properties.material.opacity, }); geom.material.parent = geom; } return finalize(geom, data, groups); } function convertVectors(meta) { meta.box = new THREE.Box3(new THREE.Vector3(...meta.min), new THREE.Vector3(...meta.max)); delete meta.min; delete meta.max; for (let key in meta) { let item = meta[key]; if (Array.isArray(item) && item.length == 3) meta[key] = new THREE.Vector3().fromArray(item); } } function finalize(geom, data, groups) { if (!!data.properties.box) { geom.geometry.boundingBox = data.properties.box; geom.geometry.boundingSphere = data.properties.sphere; } else { geom.geometry.computeBoundingBox(); geom.geometry.computeBoundingSphere(); } return geom; }