提交 4418d1a1 编写于 作者: M Mugen87

BufferGeometryUtils: Provide function for drawMode conversion.

上级 55a6e7f6
...@@ -73,6 +73,16 @@ ...@@ -73,6 +73,16 @@
</p> </p>
<h3>[method:BufferGeometry convertToTriangles]( [param:BufferGeometry geometry], [param:TrianglesDrawMode drawMode] )</h3>
<p>
geometry -- Instance of [page:BufferGeometry BufferGeometry].<br />
drawMode -- The draw mode of the given geometry.<br /><br />
Returns a new indexed [page:BufferGeometry BufferGeometry] based on the [page:DrawModes THREE.TrianglesDrawMode] draw mode. This mode
corresponds to the *gl.TRIANGLES* WebGL primitive.
</p>
<h2>Source</h2> <h2>Source</h2>
<p> <p>
......
...@@ -73,6 +73,16 @@ ...@@ -73,6 +73,16 @@
</p> </p>
<h3>[method:BufferGeometry convertToTriangles]( [param:BufferGeometry geometry], [param:TrianglesDrawMode drawMode] )</h3>
<p>
geometry -- Instance of [page:BufferGeometry BufferGeometry].<br />
drawMode -- The draw mode of the given geometry.<br /><br />
Returns a new indexed [page:BufferGeometry BufferGeometry] based on the [page:DrawModes THREE.TrianglesDrawMode] draw mode. This mode
corresponds to the *gl.TRIANGLES* WebGL primitive.
</p>
<h2>Source</h2> <h2>Source</h2>
<p> <p>
......
...@@ -622,6 +622,116 @@ THREE.BufferGeometryUtils = { ...@@ -622,6 +622,116 @@ THREE.BufferGeometryUtils = {
return result; return result;
},
/**
* @param {THREE.BufferGeometry} geometry
* @param {number} drawMode
* @return {THREE.BufferGeometry>}
*/
convertToTriangles: function ( geometry, drawMode ) {
if ( drawMode === THREE.TrianglesDrawMode ) {
console.warn( 'THREE.BufferGeometryUtils.convertToTriangles(): Geometry already defined as triangles.' );
return geometry;
}
if ( drawMode === THREE.TriangleFanDrawMode || drawMode === THREE.TriangleStripDrawMode ) {
var index = geometry.getIndex();
// generate index if not present
if ( index === null ) {
var indices = [];
var position = geometry.getAttribute( 'position' );
if ( position !== undefined ) {
for ( var i = 0; i < position.count; i ++ ) {
indices.push( i );
}
geometry.setIndex( indices );
index = geometry.getIndex();
} else {
console.error( 'THREE.BufferGeometryUtils.convertToTriangles(): Undefined position attribute. Unable to perform conversion.' );
return geometry;
}
}
//
var numberOfTriangles = index.count - 2;
var newIndices = [];
if ( drawMode === THREE.TriangleFanDrawMode ) {
// gl.TRIANGLE_FAN
for ( var i = 1; i <= numberOfTriangles; i ++ ) {
newIndices.push( index.getX( 0 ) );
newIndices.push( index.getX( i ) );
newIndices.push( index.getX( i + 1 ) );
}
} else {
// gl.TRIANGLE_STRIP
for ( var i = 0; i < numberOfTriangles; i ++ ) {
if ( i % 2 === 0 ) {
newIndices.push( index.getX( i ) );
newIndices.push( index.getX( i + 1 ) );
newIndices.push( index.getX( i + 2 ) );
} else {
newIndices.push( index.getX( i + 2 ) );
newIndices.push( index.getX( i + 1 ) );
newIndices.push( index.getX( i ) );
}
}
}
if ( ( newIndices.length / 3 ) !== numberOfTriangles ) {
console.error( 'THREE.BufferGeometryUtils.convertToTriangles(): Unable to generate correct amount of triangles.' );
}
// build final geometry
var newGeometry = geometry.clone();
newGeometry.setIndex( newIndices );
return newGeometry;
} else {
console.error( 'THREE.BufferGeometryUtils.convertToTriangles(): Unknown draw mode:', drawMode );
return geometry;
}
} }
}; };
import { BufferAttribute, BufferGeometry } from '../../../src/Three'; import { BufferAttribute, BufferGeometry, InterleavedBufferAttribute, TrianglesDrawModes } from '../../../src/Three';
export namespace BufferGeometryUtils { export namespace BufferGeometryUtils {
export function mergeBufferGeometries( geometries: BufferGeometry[], useGroups?: boolean ): BufferGeometry; export function mergeBufferGeometries( geometries: BufferGeometry[], useGroups?: boolean ): BufferGeometry;
export function computeTangents( geometry: BufferGeometry ): null; export function computeTangents( geometry: BufferGeometry ): null;
export function mergeBufferAttributes( attributes: BufferAttribute[] ): BufferAttribute; export function mergeBufferAttributes( attributes: BufferAttribute[] ): BufferAttribute;
export function interleaveAttributes( attributes: BufferAttribute[] ): InterleavedBufferAttribute;
export function estimateBytesUsed( geometry: BufferGeometry ): number;
export function mergeVertices( geometry: BufferGeometry, tolerance?: number ): BufferGeometry;
export function convertToTriangles( geometry: BufferGeometry, drawMode: TrianglesDrawModes ): BufferGeometry;
} }
...@@ -7,6 +7,9 @@ import { ...@@ -7,6 +7,9 @@ import {
BufferGeometry, BufferGeometry,
InterleavedBuffer, InterleavedBuffer,
InterleavedBufferAttribute, InterleavedBufferAttribute,
TriangleFanDrawMode,
TriangleStripDrawMode,
TrianglesDrawMode,
Vector2, Vector2,
Vector3 Vector3
} from "../../../build/three.module.js"; } from "../../../build/three.module.js";
...@@ -631,6 +634,116 @@ var BufferGeometryUtils = { ...@@ -631,6 +634,116 @@ var BufferGeometryUtils = {
return result; return result;
},
/**
* @param {BufferGeometry} geometry
* @param {number} drawMode
* @return {BufferGeometry>}
*/
convertToTriangles: function ( geometry, drawMode ) {
if ( drawMode === TrianglesDrawMode ) {
console.warn( 'THREE.BufferGeometryUtils.convertToTriangles(): Geometry already defined as triangles.' );
return geometry;
}
if ( drawMode === TriangleFanDrawMode || drawMode === TriangleStripDrawMode ) {
var index = geometry.getIndex();
// generate index if not present
if ( index === null ) {
var indices = [];
var position = geometry.getAttribute( 'position' );
if ( position !== undefined ) {
for ( var i = 0; i < position.count; i ++ ) {
indices.push( i );
}
geometry.setIndex( indices );
index = geometry.getIndex();
} else {
console.error( 'THREE.BufferGeometryUtils.convertToTriangles(): Undefined position attribute. Unable to perform conversion.' );
return geometry;
}
}
//
var numberOfTriangles = index.count - 2;
var newIndices = [];
if ( drawMode === TriangleFanDrawMode ) {
// gl.TRIANGLE_FAN
for ( var i = 1; i <= numberOfTriangles; i ++ ) {
newIndices.push( index.getX( 0 ) );
newIndices.push( index.getX( i ) );
newIndices.push( index.getX( i + 1 ) );
}
} else {
// gl.TRIANGLE_STRIP
for ( var i = 0; i < numberOfTriangles; i ++ ) {
if ( i % 2 === 0 ) {
newIndices.push( index.getX( i ) );
newIndices.push( index.getX( i + 1 ) );
newIndices.push( index.getX( i + 2 ) );
} else {
newIndices.push( index.getX( i + 2 ) );
newIndices.push( index.getX( i + 1 ) );
newIndices.push( index.getX( i ) );
}
}
}
if ( ( newIndices.length / 3 ) !== numberOfTriangles ) {
console.error( 'THREE.BufferGeometryUtils.convertToTriangles(): Unable to generate correct amount of triangles.' );
}
// build final geometry
var newGeometry = geometry.clone();
newGeometry.setIndex( newIndices );
return newGeometry;
} else {
console.error( 'THREE.BufferGeometryUtils.convertToTriangles(): Unknown draw mode:', drawMode );
return geometry;
}
} }
}; };
......
...@@ -7,6 +7,7 @@ import { BufferGeometryUtils } from '../../../../examples/jsm/utils/BufferGeomet ...@@ -7,6 +7,7 @@ import { BufferGeometryUtils } from '../../../../examples/jsm/utils/BufferGeomet
import { BufferAttribute } from '../../../../src/core/BufferAttribute'; import { BufferAttribute } from '../../../../src/core/BufferAttribute';
import { BufferGeometry } from '../../../../src/core/BufferGeometry'; import { BufferGeometry } from '../../../../src/core/BufferGeometry';
import { TriangleStripDrawMode, TriangleFanDrawMode } from '../../../../src/constants';
export default QUnit.module( 'BufferGeometryUtils', () => { export default QUnit.module( 'BufferGeometryUtils', () => {
...@@ -129,4 +130,44 @@ export default QUnit.module( 'BufferGeometryUtils', () => { ...@@ -129,4 +130,44 @@ export default QUnit.module( 'BufferGeometryUtils', () => {
} ); } );
QUnit.test( 'convertToTriangles()', ( assert ) => {
// TRIANGLE_STRIP
const vertices1 = [];
vertices1.push( 0, 0, 0 ); // v0
vertices1.push( 1, 0, 0 ); // v1
vertices1.push( 0, 1, 0 ); // v2
vertices1.push( 2, 0, 0 ); // v3
vertices1.push( 2, 1, 0 ); // v4
vertices1.push( 3, 0, 0 ); // v5
var geometry1 = new BufferGeometry();
geometry1.setAttribute( 'position', new BufferAttribute( new Float32Array( vertices1 ), 3 ) );
geometry1 = BufferGeometryUtils.convertToTriangles( geometry1, TriangleStripDrawMode );
assert.deepEqual( geometry1.index.array, new Uint16Array( [ 0, 1, 2, 3, 2, 1, 2, 3, 4, 5, 4, 3 ] ), 'correct triangle indices from triangle strip' );
// TRIANGLE_FAN
const vertices2 = [];
vertices2.push( 0, 0, 0 ); // v0
vertices2.push( 1, 0, 0 ); // v1
vertices2.push( 1, 1, 0 ); // v2
vertices2.push( 0, 1, 0 ); // v3
vertices2.push( - 1, 1, 0 ); // v4
vertices2.push( - 1, 0, 0 ); // v5
var geometry2 = new BufferGeometry();
geometry2.setAttribute( 'position', new BufferAttribute( new Float32Array( vertices2 ), 3 ) );
geometry2 = BufferGeometryUtils.convertToTriangles( geometry2, TriangleFanDrawMode );
assert.deepEqual( geometry2.index.array, new Uint16Array( [ 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5 ] ), 'correct triangle indices from triangle fan' );
} );
} ); } );
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册