📄 Geometries.js
¶
📊 Analysis Summary¶
Metric | Count |
---|---|
🔧 Functions | 10 |
🧱 Classes | 1 |
📦 Imports | 5 |
📊 Variables & Constants | 19 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 src/renderers/common/Geometries.js
📦 Imports¶
Name | Source |
---|---|
DataMap |
./DataMap.js |
AttributeType |
./Constants.js |
arrayNeedsUint32 |
../../utils.js |
Uint16BufferAttribute |
../../core/BufferAttribute.js |
Uint32BufferAttribute |
../../core/BufferAttribute.js |
Variables & Constants¶
Name | Type | Kind | Value | Exported |
---|---|---|---|---|
indices |
any[] |
let/var | [] |
✗ |
geometryIndex |
any |
let/var | geometry.index |
✗ |
geometryPosition |
any |
let/var | geometry.attributes.position |
✗ |
array |
any |
let/var | geometryIndex.array |
✗ |
a |
any |
let/var | array[ i + 0 ] |
✗ |
b |
any |
let/var | array[ i + 1 ] |
✗ |
c |
any |
let/var | array[ i + 2 ] |
✗ |
array |
any |
let/var | geometryPosition.array |
✗ |
a |
number |
let/var | i + 0 |
✗ |
b |
number |
let/var | i + 1 |
✗ |
c |
number |
let/var | i + 2 |
✗ |
attribute |
Uint32BufferAttribute \| Uint16Buffer... |
let/var | new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttri... |
✗ |
geometry |
any |
let/var | renderObject.geometry |
✗ |
geometry |
any |
let/var | renderObject.geometry |
✗ |
index |
any |
let/var | geometry.index |
✗ |
indirect |
any |
let/var | renderObject.geometry.indirect |
✗ |
callId |
any |
let/var | this.info.render.calls |
✗ |
index |
any |
let/var | geometry.index |
✗ |
wireframes |
WeakMap<BufferGeometry, BufferAttribute> |
let/var | this.wireframes |
✗ |
Functions¶
getWireframeVersion(geometry: BufferGeometry): number
¶
JSDoc:
/**
* Returns the wireframe version for the given geometry.
*
* @private
* @function
* @param {BufferGeometry} geometry - The geometry.
* @return {number} The version.
*/
Parameters:
geometry
BufferGeometry
Returns: number
Code
getWireframeIndex(geometry: BufferGeometry): BufferAttribute
¶
JSDoc:
/**
* Returns a wireframe index attribute for the given geometry.
*
* @private
* @function
* @param {BufferGeometry} geometry - The geometry.
* @return {BufferAttribute} The wireframe index attribute.
*/
Parameters:
geometry
BufferGeometry
Returns: BufferAttribute
Calls:
indices.push
arrayNeedsUint32 (from ../../utils.js)
getWireframeVersion
Code
function getWireframeIndex( geometry ) {
const indices = [];
const geometryIndex = geometry.index;
const geometryPosition = geometry.attributes.position;
if ( geometryIndex !== null ) {
const array = geometryIndex.array;
for ( let i = 0, l = array.length; i < l; i += 3 ) {
const a = array[ i + 0 ];
const b = array[ i + 1 ];
const c = array[ i + 2 ];
indices.push( a, b, b, c, c, a );
}
} else {
const array = geometryPosition.array;
for ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
const a = i + 0;
const b = i + 1;
const c = i + 2;
indices.push( a, b, b, c, c, a );
}
}
const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
attribute.version = getWireframeVersion( geometry );
return attribute;
}
Geometries.has(renderObject: RenderObject): boolean
¶
JSDoc:
/**
* Returns `true` if the given render object has an initialized geometry.
*
* @param {RenderObject} renderObject - The render object.
* @return {boolean} Whether if the given render object has an initialized geometry or not.
*/
Parameters:
renderObject
RenderObject
Returns: boolean
Calls:
super.has
this.get
Code
Geometries.updateForRender(renderObject: RenderObject): void
¶
JSDoc:
/**
* Prepares the geometry of the given render object for rendering.
*
* @param {RenderObject} renderObject - The render object.
*/
Parameters:
renderObject
RenderObject
Returns: void
Calls:
this.has
this.initGeometry
this.updateAttributes
Code
Geometries.initGeometry(renderObject: RenderObject): void
¶
JSDoc:
/**
* Initializes the geometry of the given render object.
*
* @param {RenderObject} renderObject - The render object.
*/
Parameters:
renderObject
RenderObject
Returns: void
Calls:
this.get
renderObject.getAttributes
this.attributes.delete
this.wireframes.get
geometry.removeEventListener
geometry.addEventListener
Code
initGeometry( renderObject ) {
const geometry = renderObject.geometry;
const geometryData = this.get( geometry );
geometryData.initialized = true;
this.info.memory.geometries ++;
const onDispose = () => {
this.info.memory.geometries --;
const index = geometry.index;
const geometryAttributes = renderObject.getAttributes();
if ( index !== null ) {
this.attributes.delete( index );
}
for ( const geometryAttribute of geometryAttributes ) {
this.attributes.delete( geometryAttribute );
}
const wireframeAttribute = this.wireframes.get( geometry );
if ( wireframeAttribute !== undefined ) {
this.attributes.delete( wireframeAttribute );
}
geometry.removeEventListener( 'dispose', onDispose );
};
geometry.addEventListener( 'dispose', onDispose );
}
Geometries.updateAttributes(renderObject: RenderObject): void
¶
JSDoc:
/**
* Updates the geometry attributes of the given render object.
*
* @param {RenderObject} renderObject - The render object.
*/
Parameters:
renderObject
RenderObject
Returns: void
Calls:
renderObject.getAttributes
this.updateAttribute
this.getIndex
Internal Comments:
Code
updateAttributes( renderObject ) {
// attributes
const attributes = renderObject.getAttributes();
for ( const attribute of attributes ) {
if ( attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute ) {
this.updateAttribute( attribute, AttributeType.STORAGE );
} else {
this.updateAttribute( attribute, AttributeType.VERTEX );
}
}
// indexes
const index = this.getIndex( renderObject );
if ( index !== null ) {
this.updateAttribute( index, AttributeType.INDEX );
}
// indirect
const indirect = renderObject.geometry.indirect;
if ( indirect !== null ) {
this.updateAttribute( indirect, AttributeType.INDIRECT );
}
}
Geometries.updateAttribute(attribute: BufferAttribute, type: number): void
¶
JSDoc:
/**
* Updates the given attribute.
*
* @param {BufferAttribute} attribute - The attribute to update.
* @param {number} type - The attribute type.
*/
Parameters:
attribute
BufferAttribute
type
number
Returns: void
Calls:
this.attributeCall.get
this.attributes.update
this.attributeCall.set
Code
updateAttribute( attribute, type ) {
const callId = this.info.render.calls;
if ( ! attribute.isInterleavedBufferAttribute ) {
if ( this.attributeCall.get( attribute ) !== callId ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute, callId );
}
} else {
if ( this.attributeCall.get( attribute ) === undefined ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute, callId );
} else if ( this.attributeCall.get( attribute.data ) !== callId ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute.data, callId );
this.attributeCall.set( attribute, callId );
}
}
}
Geometries.getIndirect(renderObject: RenderObject): BufferAttribute
¶
JSDoc:
/**
* Returns the indirect buffer attribute of the given render object.
*
* @param {RenderObject} renderObject - The render object.
* @return {?BufferAttribute} The indirect attribute. `null` if no indirect drawing is used.
*/
Parameters:
renderObject
RenderObject
Returns: BufferAttribute
Geometries.getIndex(renderObject: RenderObject): BufferAttribute
¶
JSDoc:
/**
* Returns the index of the given render object's geometry. This is implemented
* in a method to return a wireframe index if necessary.
*
* @param {RenderObject} renderObject - The render object.
* @return {?BufferAttribute} The index. Returns `null` for non-indexed geometries.
*/
Parameters:
renderObject
RenderObject
Returns: BufferAttribute
Calls:
wireframes.get
getWireframeIndex
wireframes.set
getWireframeVersion
this.attributes.delete
Code
getIndex( renderObject ) {
const { geometry, material } = renderObject;
let index = geometry.index;
if ( material.wireframe === true ) {
const wireframes = this.wireframes;
let wireframeAttribute = wireframes.get( geometry );
if ( wireframeAttribute === undefined ) {
wireframeAttribute = getWireframeIndex( geometry );
wireframes.set( geometry, wireframeAttribute );
} else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) ) {
this.attributes.delete( wireframeAttribute );
wireframeAttribute = getWireframeIndex( geometry );
wireframes.set( geometry, wireframeAttribute );
}
index = wireframeAttribute;
}
return index;
}
onDispose(): void
¶
Returns: void
Calls:
renderObject.getAttributes
this.attributes.delete
this.wireframes.get
geometry.removeEventListener
Code
() => {
this.info.memory.geometries --;
const index = geometry.index;
const geometryAttributes = renderObject.getAttributes();
if ( index !== null ) {
this.attributes.delete( index );
}
for ( const geometryAttribute of geometryAttributes ) {
this.attributes.delete( geometryAttribute );
}
const wireframeAttribute = this.wireframes.get( geometry );
if ( wireframeAttribute !== undefined ) {
this.attributes.delete( wireframeAttribute );
}
geometry.removeEventListener( 'dispose', onDispose );
}
Classes¶
Geometries
¶
Class Code
class Geometries extends DataMap {
/**
* Constructs a new geometry management component.
*
* @param {Attributes} attributes - Renderer component for managing attributes.
* @param {Info} info - Renderer component for managing metrics and monitoring data.
*/
constructor( attributes, info ) {
super();
/**
* Renderer component for managing attributes.
*
* @type {Attributes}
*/
this.attributes = attributes;
/**
* Renderer component for managing metrics and monitoring data.
*
* @type {Info}
*/
this.info = info;
/**
* Weak Map for managing attributes for wireframe rendering.
*
* @type {WeakMap<BufferGeometry,BufferAttribute>}
*/
this.wireframes = new WeakMap();
/**
* This Weak Map is used to make sure buffer attributes are
* updated only once per render call.
*
* @type {WeakMap<BufferAttribute,number>}
*/
this.attributeCall = new WeakMap();
}
/**
* Returns `true` if the given render object has an initialized geometry.
*
* @param {RenderObject} renderObject - The render object.
* @return {boolean} Whether if the given render object has an initialized geometry or not.
*/
has( renderObject ) {
const geometry = renderObject.geometry;
return super.has( geometry ) && this.get( geometry ).initialized === true;
}
/**
* Prepares the geometry of the given render object for rendering.
*
* @param {RenderObject} renderObject - The render object.
*/
updateForRender( renderObject ) {
if ( this.has( renderObject ) === false ) this.initGeometry( renderObject );
this.updateAttributes( renderObject );
}
/**
* Initializes the geometry of the given render object.
*
* @param {RenderObject} renderObject - The render object.
*/
initGeometry( renderObject ) {
const geometry = renderObject.geometry;
const geometryData = this.get( geometry );
geometryData.initialized = true;
this.info.memory.geometries ++;
const onDispose = () => {
this.info.memory.geometries --;
const index = geometry.index;
const geometryAttributes = renderObject.getAttributes();
if ( index !== null ) {
this.attributes.delete( index );
}
for ( const geometryAttribute of geometryAttributes ) {
this.attributes.delete( geometryAttribute );
}
const wireframeAttribute = this.wireframes.get( geometry );
if ( wireframeAttribute !== undefined ) {
this.attributes.delete( wireframeAttribute );
}
geometry.removeEventListener( 'dispose', onDispose );
};
geometry.addEventListener( 'dispose', onDispose );
}
/**
* Updates the geometry attributes of the given render object.
*
* @param {RenderObject} renderObject - The render object.
*/
updateAttributes( renderObject ) {
// attributes
const attributes = renderObject.getAttributes();
for ( const attribute of attributes ) {
if ( attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute ) {
this.updateAttribute( attribute, AttributeType.STORAGE );
} else {
this.updateAttribute( attribute, AttributeType.VERTEX );
}
}
// indexes
const index = this.getIndex( renderObject );
if ( index !== null ) {
this.updateAttribute( index, AttributeType.INDEX );
}
// indirect
const indirect = renderObject.geometry.indirect;
if ( indirect !== null ) {
this.updateAttribute( indirect, AttributeType.INDIRECT );
}
}
/**
* Updates the given attribute.
*
* @param {BufferAttribute} attribute - The attribute to update.
* @param {number} type - The attribute type.
*/
updateAttribute( attribute, type ) {
const callId = this.info.render.calls;
if ( ! attribute.isInterleavedBufferAttribute ) {
if ( this.attributeCall.get( attribute ) !== callId ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute, callId );
}
} else {
if ( this.attributeCall.get( attribute ) === undefined ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute, callId );
} else if ( this.attributeCall.get( attribute.data ) !== callId ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute.data, callId );
this.attributeCall.set( attribute, callId );
}
}
}
/**
* Returns the indirect buffer attribute of the given render object.
*
* @param {RenderObject} renderObject - The render object.
* @return {?BufferAttribute} The indirect attribute. `null` if no indirect drawing is used.
*/
getIndirect( renderObject ) {
return renderObject.geometry.indirect;
}
/**
* Returns the index of the given render object's geometry. This is implemented
* in a method to return a wireframe index if necessary.
*
* @param {RenderObject} renderObject - The render object.
* @return {?BufferAttribute} The index. Returns `null` for non-indexed geometries.
*/
getIndex( renderObject ) {
const { geometry, material } = renderObject;
let index = geometry.index;
if ( material.wireframe === true ) {
const wireframes = this.wireframes;
let wireframeAttribute = wireframes.get( geometry );
if ( wireframeAttribute === undefined ) {
wireframeAttribute = getWireframeIndex( geometry );
wireframes.set( geometry, wireframeAttribute );
} else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) ) {
this.attributes.delete( wireframeAttribute );
wireframeAttribute = getWireframeIndex( geometry );
wireframes.set( geometry, wireframeAttribute );
}
index = wireframeAttribute;
}
return index;
}
}
Methods¶
has(renderObject: RenderObject): boolean
¶
Code
updateForRender(renderObject: RenderObject): void
¶
Code
initGeometry(renderObject: RenderObject): void
¶
Code
initGeometry( renderObject ) {
const geometry = renderObject.geometry;
const geometryData = this.get( geometry );
geometryData.initialized = true;
this.info.memory.geometries ++;
const onDispose = () => {
this.info.memory.geometries --;
const index = geometry.index;
const geometryAttributes = renderObject.getAttributes();
if ( index !== null ) {
this.attributes.delete( index );
}
for ( const geometryAttribute of geometryAttributes ) {
this.attributes.delete( geometryAttribute );
}
const wireframeAttribute = this.wireframes.get( geometry );
if ( wireframeAttribute !== undefined ) {
this.attributes.delete( wireframeAttribute );
}
geometry.removeEventListener( 'dispose', onDispose );
};
geometry.addEventListener( 'dispose', onDispose );
}
updateAttributes(renderObject: RenderObject): void
¶
Code
updateAttributes( renderObject ) {
// attributes
const attributes = renderObject.getAttributes();
for ( const attribute of attributes ) {
if ( attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute ) {
this.updateAttribute( attribute, AttributeType.STORAGE );
} else {
this.updateAttribute( attribute, AttributeType.VERTEX );
}
}
// indexes
const index = this.getIndex( renderObject );
if ( index !== null ) {
this.updateAttribute( index, AttributeType.INDEX );
}
// indirect
const indirect = renderObject.geometry.indirect;
if ( indirect !== null ) {
this.updateAttribute( indirect, AttributeType.INDIRECT );
}
}
updateAttribute(attribute: BufferAttribute, type: number): void
¶
Code
updateAttribute( attribute, type ) {
const callId = this.info.render.calls;
if ( ! attribute.isInterleavedBufferAttribute ) {
if ( this.attributeCall.get( attribute ) !== callId ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute, callId );
}
} else {
if ( this.attributeCall.get( attribute ) === undefined ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute, callId );
} else if ( this.attributeCall.get( attribute.data ) !== callId ) {
this.attributes.update( attribute, type );
this.attributeCall.set( attribute.data, callId );
this.attributeCall.set( attribute, callId );
}
}
}
getIndirect(renderObject: RenderObject): BufferAttribute
¶
getIndex(renderObject: RenderObject): BufferAttribute
¶
Code
getIndex( renderObject ) {
const { geometry, material } = renderObject;
let index = geometry.index;
if ( material.wireframe === true ) {
const wireframes = this.wireframes;
let wireframeAttribute = wireframes.get( geometry );
if ( wireframeAttribute === undefined ) {
wireframeAttribute = getWireframeIndex( geometry );
wireframes.set( geometry, wireframeAttribute );
} else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) ) {
this.attributes.delete( wireframeAttribute );
wireframeAttribute = getWireframeIndex( geometry );
wireframes.set( geometry, wireframeAttribute );
}
index = wireframeAttribute;
}
return index;
}