@google/model-viewer
Version:
Easily display interactive 3D models on the web and in AR!
140 lines • 4.87 kB
JavaScript
/*
* Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Math as ThreeMath } from 'three';
import { parseValues } from './parsers.js';
/**
* Converts a length-like ValueNode to meters expressed as a number. Currently,
* only ValueNodes that represent a metric value (m, cm, mm) are supported.
*
* If no unit is specified, assumes meters. Returns 0 for a ValueNode that
* cannot be parsed.
*/
const lengthValueNodeToMeters = (lengthValueNode) => {
const value = parseFloat(lengthValueNode.value);
if (self.isNaN(value)) {
return 0;
}
let scale;
switch (lengthValueNode.unit) {
default:
case 'm':
scale = 1;
break;
case 'cm':
scale = 1 / 100;
break;
case 'mm':
scale = 1 / 1000;
break;
}
return value * scale;
};
/**
* Converts an angle-like ValueNode to radians expressed as a number. Currently,
* only ValueNodes that represent an angle expressed in degrees (deg) or radians
* (rad) are supported.
*
* Assumes radians if unit is not specified or recognized. Returns 0 for a
* ValueNode that cannot be parsed.
*/
const convertAngleValueNode = (angleValueNode, desiredUnits = 'rad') => {
const value = parseFloat(angleValueNode.value);
if (self.isNaN(value)) {
return 0;
}
const inputUnits = angleValueNode.unit;
return inputUnits === 'deg' ?
desiredUnits === 'deg' ? value : ThreeMath.degToRad(value) :
desiredUnits === 'deg' ? ThreeMath.radToDeg(value) : value;
};
/**
* Spherical String => Spherical Values
*
* Converts a "spherical string" to values suitable for assigning to a Three.js
* Spherical object. Position strings are of the form "$theta $phi $radius".
* Accepted units for theta and phi are radians (rad) and degrees (deg).
* Accepted units for radius include meters (m), centimeters (cm) and
* millimeters (mm), or auto. If radius is set to auto, it implies that the
* consumer of the deserialized values has some idealized notion of the radius
* that should be applied.
*
* Returns null if the spherical string cannot be parsed.
*/
export const deserializeSpherical = (sphericalString) => {
try {
const sphericalValueNodes = parseValues(sphericalString);
if (sphericalValueNodes.length === 3) {
const [thetaNode, phiNode, radiusNode] = sphericalValueNodes;
const theta = convertAngleValueNode(thetaNode);
const phi = convertAngleValueNode(phiNode);
const radius = radiusNode.value === 'auto' ?
'auto' :
lengthValueNodeToMeters(radiusNode);
return [theta, phi, radius];
}
}
catch (_error) {
}
return null;
};
export const deserializeAngleToDeg = (angleString) => {
try {
const angleValueNode = parseValues(angleString);
if (angleValueNode.length === 1) {
return convertAngleValueNode(angleValueNode[0], 'deg');
}
}
catch (_error) {
}
return null;
};
/**
* For our purposes, an enumeration is a fixed set of CSS-expression-compatible
* names. When serialized, a selected subset of the members may be specified as
* whitespace-separated strings. An enumeration deserializer is a function that
* parses a serialized subset of an enumeration and returns any members that are
* found as a Set.
*
* The following example will produce a deserializer for the days of the
* week:
*
* const deserializeDaysOfTheWeek = enumerationDeserializer([
* 'Monday',
* 'Tuesday',
* 'Wednesday',
* 'Thursday',
* 'Friday',
* 'Saturday',
* 'Sunday'
* ]);
*/
export const enumerationDeserializer = (allowedNames) => (valueString) => {
try {
const names = parseValues(valueString)
.map(valueNode => valueNode.value)
.filter((name) => allowedNames.indexOf(name) > -1);
// NOTE(cdata): IE11 does not support constructing a Set directly from
// an iterable, so we need to manually add all the items:
const result = new Set();
for (const name of names) {
result.add(name);
}
return result;
}
catch (_error) {
}
return new Set();
};
//# sourceMappingURL=conversions.js.map