Skip to content

Commit 26d1c78

Browse files
rchadwicmrdoob
authored andcommitted
Support all Typed Array datatypes in bufferAttribute (mrdoob#8618)
* merge bufferAttributeTypes with dev * else if * serialize the normalized flag * update docs * remove support for DataView as BufferAttribute source. This is to specific purpose, and geometry using this will break in too many other methods * reimplement the DataView as a BufferAttribute data source * try to warn when bufferAttribute contains a DataView and cannot be read * Changed too many `warn` to `error` * Code quality update in BufferAttribute datatype selection * support load and save of normalized flag in BufferAttribute * Check for DataView attribute buffers * mend * Revert "mend" This reverts commit 1b4c876. * try to fix after --ammend causes conflicts * working on cleaning this all up * More whitespace cleanup * more code style cleanup * strike OBE comment * more spacing cleanup
1 parent ae4d9bf commit 26d1c78

File tree

6 files changed

+322
-24
lines changed

6 files changed

+322
-24
lines changed

docs/api/core/BufferAttribute.html

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ <h1>[name]</h1>
1515
</div>
1616

1717
<h2>Constructor</h2>
18-
<h3>[name]([page:TypedArray array], [page:Integer itemSize])</h3>
18+
<h3>[name]([page:TypedArray array], [page:Integer itemSize], [page:Boolean normalized])</h3>
1919
<div>
2020
Instantiates this attribute with data from the associated buffer.
21-
itemSize gives the number of values of the array that should be associated with a particular vertex.
21+
itemSize gives the number of values of the array that should be associated with a particular vertex. normalized indicates how the underlying data in the buffer maps to the values in the GLSL shader code.
2222
</div>
2323

2424
<h2>Properties</h2>
2525

2626
<h3>[property:TypedArray array]</h3>
2727
<div>
28-
Stores the data associated with this attribute. This element should have <code>itemSize * numVertices</code> elements, where numVertices is the number of vertices in the associated [page:BufferGeometry geometry].
28+
Stores the data associated with this attribute. This element should have <code>itemSize * numVertices</code> elements, where numVertices is the number of vertices in the associated [page:BufferGeometry geometry]. [page:TypedArray array] can be an instance of UInt8Array, Int8Array, UInt16Array, Int16Array, or Float32Array.
2929
</div>
3030

3131
<h3>[property:Integer itemSize]</h3>
@@ -44,6 +44,11 @@ <h3>[property:Boolean needsUpdate]</h3>
4444
Flag to indicate that this attribute has changed and should be re-send to the GPU. Set this to true when you modify the value of the array.
4545
</div>
4646

47+
<h3>[property:Boolean normalized]</h3>
48+
<div>
49+
Indicates how the underlying data in the buffer maps to the values in the GLSL code. For instance, if [page:TypedArray array] is an instance of UInt16Array, and [page:Boolean normalized] is true, the values 0 - +65535 in the array data will be mapped to 0.0f - +1.0f in the GLSL attribute. An Int16Array (signed) would map from -32767 - +32767 to -1.0f - +1.0f. If [page:Boolean normalized] is false, the values will be converted to floats which contain the exact value, i.e. 32767 becomes 32767.0f.
50+
</div>
51+
4752
<h3>[property:Integer version]</h3>
4853
<div>
4954
A version number, incremented every time the needsUpdate property is set to true.
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<title>three.js webgl - buffergeometry - uint</title>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
7+
<style>
8+
body {
9+
color: #cccccc;
10+
font-family:Monospace;
11+
font-size:13px;
12+
text-align:center;
13+
14+
background-color: #050505;
15+
margin: 0px;
16+
overflow: hidden;
17+
}
18+
19+
#info {
20+
position: absolute;
21+
top: 0px; width: 100%;
22+
padding: 5px;
23+
}
24+
25+
a {
26+
color: #0080ff;
27+
}
28+
29+
</style>
30+
</head>
31+
<body>
32+
33+
<div id="container"></div>
34+
<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> webgl - buffergeometry - BufferAttributeTypes</div>
35+
36+
<script src="../build/three.min.js"></script>
37+
38+
<script src="js/Detector.js"></script>
39+
<script src="js/libs/stats.min.js"></script>
40+
41+
<script>
42+
43+
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
44+
45+
var container, stats;
46+
47+
var camera, scene, renderer;
48+
49+
var mesh;
50+
51+
init();
52+
animate();
53+
54+
function init() {
55+
56+
container = document.getElementById( 'container' );
57+
58+
//
59+
60+
camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 3500 );
61+
camera.position.z = 2750;
62+
63+
scene = new THREE.Scene();
64+
scene.fog = new THREE.Fog( 0x050505, 2000, 3500 );
65+
66+
//
67+
68+
scene.add( new THREE.AmbientLight( 0x444444 ) );
69+
70+
var light1 = new THREE.DirectionalLight( 0xffffff, 0.5 );
71+
light1.position.set( 1, 1, 1 );
72+
scene.add( light1 );
73+
74+
var light2 = new THREE.DirectionalLight( 0xffffff, 1.5 );
75+
light2.position.set( 0, -1, 0 );
76+
scene.add( light2 );
77+
78+
//
79+
80+
var triangles = 500000;
81+
82+
var geometry = new THREE.BufferGeometry();
83+
84+
var indices = new Uint32Array( triangles * 3 );
85+
86+
for ( var i = 0; i < indices.length; i ++ ) {
87+
88+
indices[ i ] = i;
89+
90+
}
91+
92+
var positions = new Float32Array( triangles * 3 * 3 );
93+
var normals = new Int16Array( triangles * 3 * 3 );
94+
var colors = new Uint8Array( triangles * 3 * 3 );
95+
96+
var color = new THREE.Color();
97+
98+
var n = 800, n2 = n/2; // triangles spread in the cube
99+
var d = 12, d2 = d/2; // individual triangle size
100+
101+
var pA = new THREE.Vector3();
102+
var pB = new THREE.Vector3();
103+
var pC = new THREE.Vector3();
104+
105+
var cb = new THREE.Vector3();
106+
var ab = new THREE.Vector3();
107+
108+
for ( var i = 0; i < positions.length; i += 9 ) {
109+
110+
// positions
111+
112+
var x = Math.random() * n - n2;
113+
var y = Math.random() * n - n2;
114+
var z = Math.random() * n - n2;
115+
116+
var ax = x + Math.random() * d - d2;
117+
var ay = y + Math.random() * d - d2;
118+
var az = z + Math.random() * d - d2;
119+
120+
var bx = x + Math.random() * d - d2;
121+
var by = y + Math.random() * d - d2;
122+
var bz = z + Math.random() * d - d2;
123+
124+
var cx = x + Math.random() * d - d2;
125+
var cy = y + Math.random() * d - d2;
126+
var cz = z + Math.random() * d - d2;
127+
128+
positions[ i ] = ax;
129+
positions[ i + 1 ] = ay;
130+
positions[ i + 2 ] = az;
131+
132+
positions[ i + 3 ] = bx;
133+
positions[ i + 4 ] = by;
134+
positions[ i + 5 ] = bz;
135+
136+
positions[ i + 6 ] = cx;
137+
positions[ i + 7 ] = cy;
138+
positions[ i + 8 ] = cz;
139+
140+
// flat face normals
141+
142+
pA.set( ax, ay, az );
143+
pB.set( bx, by, bz );
144+
pC.set( cx, cy, cz );
145+
146+
cb.subVectors( pC, pB );
147+
ab.subVectors( pA, pB );
148+
cb.cross( ab );
149+
150+
cb.normalize();
151+
152+
var nx = cb.x;
153+
var ny = cb.y;
154+
var nz = cb.z;
155+
156+
normals[ i ] = nx * 32767;
157+
normals[ i + 1 ] = ny * 32767;
158+
normals[ i + 2 ] = nz * 32767;
159+
160+
normals[ i + 3 ] = nx * 32767;
161+
normals[ i + 4 ] = ny * 32767;
162+
normals[ i + 5 ] = nz * 32767;
163+
164+
normals[ i + 6 ] = nx * 32767;
165+
normals[ i + 7 ] = ny * 32767;
166+
normals[ i + 8 ] = nz * 32767;
167+
168+
// colors
169+
170+
var vx = ( x / n ) + 0.5;
171+
var vy = ( y / n ) + 0.5;
172+
var vz = ( z / n ) + 0.5;
173+
174+
color.setRGB( vx, vy, vz );
175+
176+
colors[ i ] = color.r * 255;
177+
colors[ i + 1 ] = color.g * 255;
178+
colors[ i + 2 ] = color.b * 255;
179+
180+
colors[ i + 3 ] = color.r * 255;
181+
colors[ i + 4 ] = color.g * 255;
182+
colors[ i + 5 ] = color.b * 255;
183+
184+
colors[ i + 6 ] = color.r * 255;
185+
colors[ i + 7 ] = color.g * 255;
186+
colors[ i + 8 ] = color.b * 255;
187+
188+
}
189+
190+
geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
191+
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
192+
geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3, true ) );
193+
geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3, true ) );
194+
195+
geometry.computeBoundingSphere();
196+
197+
var material = new THREE.MeshPhongMaterial( {
198+
color: 0xaaaaaa, specular: 0xffffff, shininess: 250,
199+
side: THREE.DoubleSide, vertexColors: THREE.VertexColors
200+
} );
201+
202+
mesh = new THREE.Mesh( geometry, material );
203+
scene.add( mesh );
204+
205+
//
206+
207+
renderer = new THREE.WebGLRenderer( { antialias: false } );
208+
renderer.setClearColor( scene.fog.color );
209+
renderer.setPixelRatio( window.devicePixelRatio );
210+
renderer.setSize( window.innerWidth, window.innerHeight );
211+
212+
renderer.gammaInput = true;
213+
renderer.gammaOutput = true;
214+
215+
container.appendChild( renderer.domElement );
216+
217+
//
218+
219+
stats = new Stats();
220+
stats.domElement.style.position = 'absolute';
221+
stats.domElement.style.top = '0px';
222+
container.appendChild( stats.domElement );
223+
224+
//
225+
226+
window.addEventListener( 'resize', onWindowResize, false );
227+
228+
}
229+
230+
function onWindowResize() {
231+
232+
camera.aspect = window.innerWidth / window.innerHeight;
233+
camera.updateProjectionMatrix();
234+
235+
renderer.setSize( window.innerWidth, window.innerHeight );
236+
237+
}
238+
239+
//
240+
241+
function animate() {
242+
243+
requestAnimationFrame( animate );
244+
245+
render();
246+
stats.update();
247+
248+
}
249+
250+
function render() {
251+
252+
var time = Date.now() * 0.001;
253+
254+
mesh.rotation.x = time * 0.25;
255+
mesh.rotation.y = time * 0.5;
256+
257+
renderer.render( scene, camera );
258+
259+
}
260+
261+
</script>
262+
263+
</body>
264+
</html>

src/core/BufferAttribute.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @author mrdoob / http://mrdoob.com/
33
*/
44

5-
THREE.BufferAttribute = function ( array, itemSize ) {
5+
THREE.BufferAttribute = function ( array, itemSize, normalized ) {
66

77
this.uuid = THREE.Math.generateUUID();
88

@@ -13,6 +13,7 @@ THREE.BufferAttribute = function ( array, itemSize ) {
1313
this.updateRange = { offset: 0, count: - 1 };
1414

1515
this.version = 0;
16+
this.normalized = normalized ? true : false;
1617

1718
};
1819

src/core/BufferGeometry.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,8 @@ THREE.BufferGeometry.prototype = {
918918
data.data.attributes[ key ] = {
919919
itemSize: attribute.itemSize,
920920
type: attribute.array.constructor.name,
921-
array: array
921+
array: array,
922+
normalized: attribute.normalized
922923
};
923924

924925
}

src/loaders/BufferGeometryLoader.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ THREE.BufferGeometryLoader.prototype = {
5656

5757
var attribute = attributes[ key ];
5858
var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );
59-
60-
geometry.addAttribute( key, new THREE.BufferAttribute( typedArray, attribute.itemSize ) );
59+
var normalized = attribute.normalized || false;
60+
geometry.addAttribute( key, new THREE.BufferAttribute( typedArray, attribute.itemSize , normalized) );
6161

6262
}
6363

0 commit comments

Comments
 (0)