|
|
@@ -11,6 +11,27 @@ import {
|
|
|
Vector3,
|
|
|
} from 'three';
|
|
|
|
|
|
+/** @module BufferGeometryUtils */
|
|
|
+
|
|
|
+/**
|
|
|
+ * Computes vertex tangents using the MikkTSpace algorithm. MikkTSpace generates the same tangents consistently,
|
|
|
+ * and is used in most modelling tools and normal map bakers. Use MikkTSpace for materials with normal maps,
|
|
|
+ * because inconsistent tangents may lead to subtle visual issues in the normal map, particularly around mirrored
|
|
|
+ * UV seams.
|
|
|
+ *
|
|
|
+ * In comparison to this method, {@link BufferGeometry#computeTangents} (a custom algorithm) generates tangents that
|
|
|
+ * probably will not match the tangents in other software. The custom algorithm is sufficient for general use with a
|
|
|
+ * custom material, and may be faster than MikkTSpace.
|
|
|
+ *
|
|
|
+ * Returns the original BufferGeometry. Indexed geometries will be de-indexed. Requires position, normal, and uv attributes.
|
|
|
+ *
|
|
|
+ * @param {BufferGeometry} geometry - The geometry to compute tangents for.
|
|
|
+ * @param {Object} MikkTSpace - Instance of `examples/jsm/libs/mikktspace.module.js`, or `mikktspace` npm package.
|
|
|
+ * Aawait `MikkTSpace.ready` before use.
|
|
|
+ * @param {boolean} [negateSign=true] - Whether to negate the sign component (.w) of each tangent.
|
|
|
+ * Required for normal map conventions in some formats, including glTF.
|
|
|
+ * @return {BufferGeometry} The updated geometry.
|
|
|
+ */
|
|
|
function computeMikkTSpaceTangents( geometry, MikkTSpace, negateSign = true ) {
|
|
|
|
|
|
if ( ! MikkTSpace || ! MikkTSpace.isReady ) {
|
|
|
@@ -100,9 +121,11 @@ function computeMikkTSpaceTangents( geometry, MikkTSpace, negateSign = true ) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param {Array<BufferGeometry>} geometries
|
|
|
- * @param {boolean} useGroups
|
|
|
- * @return {?BufferGeometry}
|
|
|
+ * Merges a set of geometries into a single instance. All geometries must have compatible attributes.
|
|
|
+ *
|
|
|
+ * @param {Array<BufferGeometry>} geometries - The geometries to merge.
|
|
|
+ * @param {boolean} [useGroups=false] - Whether to use groups or not.
|
|
|
+ * @return {?BufferGeometry} The merged geometry. Returns `null` if the merge does not succeed.
|
|
|
*/
|
|
|
function mergeGeometries( geometries, useGroups = false ) {
|
|
|
|
|
|
@@ -296,8 +319,11 @@ function mergeGeometries( geometries, useGroups = false ) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param {Array<BufferAttribute>} attributes
|
|
|
- * @return {?BufferAttribute}
|
|
|
+ * Merges a set of attributes into a single instance. All attributes must have compatible properties and types.
|
|
|
+ * Instances of {@link InterleavedBufferAttribute} are not supported.
|
|
|
+ *
|
|
|
+ * @param {Array<BufferAttribute>} attributes - The attributes to merge.
|
|
|
+ * @return {?BufferAttribute} The merged attribute. Returns `null` if the merge does not succeed.
|
|
|
*/
|
|
|
function mergeAttributes( attributes ) {
|
|
|
|
|
|
@@ -389,10 +415,12 @@ function mergeAttributes( attributes ) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param {BufferAttribute} attribute
|
|
|
- * @return {BufferAttribute}
|
|
|
+ * Performs a deep clone of the given buffer attribute.
|
|
|
+ *
|
|
|
+ * @param {BufferAttribute} attribute - The attribute to clone.
|
|
|
+ * @return {BufferAttribute} The cloned attribute.
|
|
|
*/
|
|
|
-export function deepCloneAttribute( attribute ) {
|
|
|
+function deepCloneAttribute( attribute ) {
|
|
|
|
|
|
if ( attribute.isInstancedInterleavedBufferAttribute || attribute.isInterleavedBufferAttribute ) {
|
|
|
|
|
|
@@ -411,8 +439,11 @@ export function deepCloneAttribute( attribute ) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param {Array<BufferAttribute>} attributes
|
|
|
- * @return {Array<InterleavedBufferAttribute>}
|
|
|
+ * Interleaves a set of attributes and returns a new array of corresponding attributes that share a
|
|
|
+ * single {@link InterleavedBuffer} instance. All attributes must have compatible types.
|
|
|
+ *
|
|
|
+ * @param {Array<BufferAttribute>} attributes - The attributes to interleave.
|
|
|
+ * @return {Array<InterleavedBufferAttribute>} An array of interleaved attributes. If interleave does not succeed, the method returns `null`.
|
|
|
*/
|
|
|
function interleaveAttributes( attributes ) {
|
|
|
|
|
|
@@ -475,8 +506,13 @@ function interleaveAttributes( attributes ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-// returns a new, non-interleaved version of the provided attribute
|
|
|
-export function deinterleaveAttribute( attribute ) {
|
|
|
+/**
|
|
|
+ * Returns a new, non-interleaved version of the given attribute.
|
|
|
+ *
|
|
|
+ * @param {InterleavedBufferAttribute} attribute - The interleaved attribute.
|
|
|
+ * @return {BufferAttribute} The non-interleaved attribute.
|
|
|
+ */
|
|
|
+function deinterleaveAttribute( attribute ) {
|
|
|
|
|
|
const cons = attribute.data.array.constructor;
|
|
|
const count = attribute.count;
|
|
|
@@ -523,8 +559,12 @@ export function deinterleaveAttribute( attribute ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-// deinterleaves all attributes on the geometry
|
|
|
-export function deinterleaveGeometry( geometry ) {
|
|
|
+/**
|
|
|
+ * Deinterleaves all attributes on the given geometry.
|
|
|
+ *
|
|
|
+ * @param {BufferGeometry} geometry - The geometry to deinterleave.
|
|
|
+ */
|
|
|
+function deinterleaveGeometry( geometry ) {
|
|
|
|
|
|
const attributes = geometry.attributes;
|
|
|
const morphTargets = geometry.morphTargets;
|
|
|
@@ -567,8 +607,10 @@ export function deinterleaveGeometry( geometry ) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param {BufferGeometry} geometry
|
|
|
- * @return {number}
|
|
|
+ * Returns the amount of bytes used by all attributes to represent the geometry.
|
|
|
+ *
|
|
|
+ * @param {BufferGeometry} geometry - The geometry.
|
|
|
+ * @return {number} The estimate bytes used.
|
|
|
*/
|
|
|
function estimateBytesUsed( geometry ) {
|
|
|
|
|
|
@@ -590,9 +632,11 @@ function estimateBytesUsed( geometry ) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param {BufferGeometry} geometry
|
|
|
- * @param {number} tolerance
|
|
|
- * @return {BufferGeometry}
|
|
|
+ * Returns a new geometry with vertices for which all similar vertex attributes (within tolerance) are merged.
|
|
|
+ *
|
|
|
+ * @param {BufferGeometry} geometry - The geometry to merge vertices for.
|
|
|
+ * @param {number} [tolerance=1e-4] - The tolerance value.
|
|
|
+ * @return {BufferGeometry} - The new geometry with merged vertices.
|
|
|
*/
|
|
|
function mergeVertices( geometry, tolerance = 1e-4 ) {
|
|
|
|
|
|
@@ -753,9 +797,12 @@ function mergeVertices( geometry, tolerance = 1e-4 ) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param {BufferGeometry} geometry
|
|
|
- * @param {number} drawMode
|
|
|
- * @return {BufferGeometry}
|
|
|
+ * Returns a new indexed geometry based on `TrianglesDrawMode` draw mode.
|
|
|
+ * This mode corresponds to the `gl.TRIANGLES` primitive in WebGL.
|
|
|
+ *
|
|
|
+ * @param {BufferGeometry} geometry - The geometry to convert.
|
|
|
+ * @param {number} drawMode - The current draw mode.
|
|
|
+ * @return {BufferGeometry} The new geometry using `TrianglesDrawMode`.
|
|
|
*/
|
|
|
function toTrianglesDrawMode( geometry, drawMode ) {
|
|
|
|
|
|
@@ -864,9 +911,13 @@ function toTrianglesDrawMode( geometry, drawMode ) {
|
|
|
|
|
|
/**
|
|
|
* Calculates the morphed attributes of a morphed/skinned BufferGeometry.
|
|
|
- * Helpful for Raytracing or Decals.
|
|
|
- * @param {Mesh | Line | Points} object An instance of Mesh, Line or Points.
|
|
|
- * @return {Object} An Object with original position/normal attributes and morphed ones.
|
|
|
+ *
|
|
|
+ * Helpful for Raytracing or Decals (i.e. a `DecalGeometry` applied to a morphed Object with a `BufferGeometry`
|
|
|
+ * will use the original `BufferGeometry`, not the morphed/skinned one, generating an incorrect result.
|
|
|
+ * Using this function to create a shadow `Object3`D the `DecalGeometry` can be correctly generated).
|
|
|
+ *
|
|
|
+ * @param {Mesh|Line|Points} object - The 3D object tocompute morph attributes for.
|
|
|
+ * @return {Object} An object with original position/normal attributes and morphed ones.
|
|
|
*/
|
|
|
function computeMorphedAttributes( object ) {
|
|
|
|
|
|
@@ -1142,6 +1193,12 @@ function computeMorphedAttributes( object ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Merges the {@link BufferGeometry#groups} for the given geometry.
|
|
|
+ *
|
|
|
+ * @param {BufferGeometry} geometry - The geometry to modify.
|
|
|
+ * @return {BufferGeometry} - The updated geometry
|
|
|
+ */
|
|
|
function mergeGroups( geometry ) {
|
|
|
|
|
|
if ( geometry.groups.length === 0 ) {
|
|
|
@@ -1244,15 +1301,14 @@ function mergeGroups( geometry ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* Modifies the supplied geometry if it is non-indexed, otherwise creates a new,
|
|
|
* non-indexed geometry. Returns the geometry with smooth normals everywhere except
|
|
|
* faces that meet at an angle greater than the crease angle.
|
|
|
*
|
|
|
- * @param {BufferGeometry} geometry
|
|
|
- * @param {number} [creaseAngle]
|
|
|
- * @return {BufferGeometry}
|
|
|
+ * @param {BufferGeometry} geometry - The geometry to modify.
|
|
|
+ * @param {number} [creaseAngle=Math.PI/3] - The crease angle in radians.
|
|
|
+ * @return {BufferGeometry} - The updated geometry
|
|
|
*/
|
|
|
function toCreasedNormals( geometry, creaseAngle = Math.PI / 3 /* 60 degrees */ ) {
|
|
|
|
|
|
@@ -1363,6 +1419,9 @@ export {
|
|
|
computeMikkTSpaceTangents,
|
|
|
mergeGeometries,
|
|
|
mergeAttributes,
|
|
|
+ deepCloneAttribute,
|
|
|
+ deinterleaveAttribute,
|
|
|
+ deinterleaveGeometry,
|
|
|
interleaveAttributes,
|
|
|
estimateBytesUsed,
|
|
|
mergeVertices,
|