Skip to content

Commit 5313356

Browse files
committed
Added basic Geometry
1 parent 6ab0803 commit 5313356

5 files changed

Lines changed: 503 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2020 Photon Storm Ltd.
4+
* @license {@link https://opensource.org/licenses/MIT|MIT License}
5+
*/
6+
7+
var Class = require('../../utils/Class');
8+
9+
var BufferAttribute = new Class({
10+
11+
initialize:
12+
13+
function BufferAttribute (array, size, normalized)
14+
{
15+
/**
16+
* The array holding data stored in the buffer.
17+
* @type {TypedArray}
18+
*/
19+
this.array = array;
20+
21+
/**
22+
* The length of vectors that are being stored in the array.
23+
* @type {Integer}
24+
*/
25+
this.size = size;
26+
27+
/**
28+
* Stores the array's length divided by the size.
29+
* If the buffer is storing a 3-component vector (such as a position, normal, or color), then this will count the number of such vectors stored.
30+
* @type {Integer}
31+
*/
32+
this.count = array !== undefined ? array.length / size : 0;
33+
34+
/**
35+
* Indicates how the underlying data in the buffer maps to the values in the GLSL shader code.
36+
* See the constructor above for details.
37+
* @type {boolean}
38+
*/
39+
this.normalized = normalized === true;
40+
41+
/**
42+
* Whether the buffer is dynamic or not.
43+
* If false, the GPU is informed that contents of the buffer are likely to be used often and not change often.
44+
* This corresponds to the gl.STATIC_DRAW flag.
45+
* If true, the GPU is informed that contents of the buffer are likely to be used often and change often.
46+
* This corresponds to the gl.DYNAMIC_DRAW flag.
47+
* @type {boolean}
48+
* @default false
49+
*/
50+
this.dynamic = false;
51+
52+
/**
53+
* Object containing:
54+
* offset: Default is 0. Position at whcih to start update.
55+
* count: Default is -1, which means don't use update ranges.
56+
* This can be used to only update some components of stored vectors (for example, just the component related to color).
57+
*/
58+
this.updateRange = { offset: 0, count: -1 };
59+
60+
/**
61+
* A version number, incremented every time the data changes.
62+
* @type {Integer}
63+
* @default 0
64+
*/
65+
this.version = 0;
66+
},
67+
68+
setArray: function (array)
69+
{
70+
this.count = array !== undefined ? array.length / this.size : 0;
71+
72+
this.array = array;
73+
74+
// inc version?
75+
76+
return this;
77+
}
78+
79+
// copy / clone?
80+
81+
});
82+
83+
module.exports = BufferAttribute;

src/layer3d/geometry/Geometry.js

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2020 Photon Storm Ltd.
4+
* @license {@link https://opensource.org/licenses/MIT|MIT License}
5+
*/
6+
7+
var Box3 = require('../math/Box3');
8+
var BufferAttribute = require('./BufferAttribute');
9+
var Class = require('../../utils/Class');
10+
var Sphere = require('../math/Sphere');
11+
12+
var geometryId = 1;
13+
14+
var Geometry = new Class({
15+
16+
initialize:
17+
18+
function Geometry ()
19+
{
20+
this.id = geometryId++;
21+
22+
/**
23+
* This hashmap has an id the name of the attribute to be set and as value the buffer to set it to.
24+
* Rather than accessing this property directly, use `addAttribute` and `getAttribute` to access attributes of this geometry.
25+
*/
26+
this.attributes = {};
27+
28+
/**
29+
* Hashmap of Attributes Array for morph targets.
30+
*/
31+
this.morphAttributes = {};
32+
33+
/**
34+
* Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles" and each triangle is associated with the indices of three vertices.
35+
* This attribute therefore stores the index of each vertex for each triangular face.
36+
* If this attribute is not set, the renderer assumes that each three contiguous positions represent a single triangle.
37+
* @type {BufferAttribute}
38+
*/
39+
this.index = null;
40+
41+
/**
42+
* Bounding box for the bufferGeometry, which can be calculated with `computeBoundingBox`.
43+
* @type {Box3}
44+
*/
45+
this.boundingBox = new Box3();
46+
47+
/**
48+
* Bounding sphere for the bufferGeometry, which can be calculated with `computeBoundingSphere`.
49+
* @type {Sphere}
50+
*/
51+
this.boundingSphere = new Sphere();
52+
53+
/**
54+
* Split the geometry into groups, each of which will be rendered in a separate WebGL draw call. This allows an array of materials to be used with the geometry.
55+
* Each group is an object of the form:
56+
* { start: Integer, count: Integer, materialIndex: Integer }
57+
*/
58+
this.groups = [];
59+
60+
/**
61+
* A version number, incremented every time the attribute object or index object changes to mark VAO drity.
62+
*/
63+
this.version = 0;
64+
},
65+
66+
/**
67+
* Adds an attribute to this geometry.
68+
* Use this rather than the attributes property.
69+
* @param {string} name
70+
* @param {BufferAttribute|InterleavedBufferAttribute} attribute
71+
*/
72+
addAttribute: function (name, attribute)
73+
{
74+
this.attributes[name] = attribute;
75+
},
76+
77+
/**
78+
* Returns the attribute with the specified name.
79+
* @return {BufferAttribute|InterleavedBufferAttribute}
80+
*/
81+
getAttribute: function (name)
82+
{
83+
return this.attributes[name];
84+
},
85+
86+
/**
87+
* Removes the attribute with the specified name.
88+
*/
89+
removeAttribute: function (name)
90+
{
91+
delete this.attributes[name];
92+
},
93+
94+
/**
95+
* Set the index buffer.
96+
* @param {Array|BufferAttribute} index
97+
*/
98+
setIndex: function (index)
99+
{
100+
if (Array.isArray(index))
101+
{
102+
this.index = new BufferAttribute(new Uint16Array(index), 1);
103+
}
104+
else
105+
{
106+
this.index = index;
107+
}
108+
},
109+
110+
/**
111+
* Adds a group to this geometry; see the groups for details.
112+
* @param {number} start
113+
* @param {number} count
114+
* @param {number} materialIndex
115+
*/
116+
addGroup: function (start, count, materialIndex)
117+
{
118+
this.groups.push({
119+
start: start,
120+
count: count,
121+
materialIndex: materialIndex !== undefined ? materialIndex : 0
122+
});
123+
},
124+
125+
/**
126+
* Clears all groups.
127+
*/
128+
clearGroups: function ()
129+
{
130+
this.groups = [];
131+
},
132+
133+
/**
134+
* Computes bounding box of the geometry, updating `boundingBox`.
135+
* Bounding boxes aren't computed by default. They need to be explicitly computed.
136+
*/
137+
computeBoundingBox: function ()
138+
{
139+
var position = this.attributes['a_Position'] || this.attributes['position'];
140+
141+
if (position.isInterleavedBufferAttribute)
142+
{
143+
var data = position.data;
144+
145+
this.boundingBox.setFromArray(data.array, data.stride);
146+
}
147+
else
148+
{
149+
this.boundingBox.setFromArray(position.array, position.size);
150+
}
151+
},
152+
153+
/**
154+
* Computes bounding sphere of the geometry, updating `boundingSphere`.
155+
*
156+
* Bounding spheres aren't computed by default. They need to be explicitly computed.
157+
*/
158+
computeBoundingSphere: function ()
159+
{
160+
var position = this.attributes['a_Position'] || this.attributes['position'];
161+
162+
if (position.isInterleavedBufferAttribute)
163+
{
164+
var data = position.data;
165+
166+
this.boundingSphere.setFromArray(data.array, data.stride);
167+
}
168+
else
169+
{
170+
this.boundingSphere.setFromArray(position.array, position.size);
171+
}
172+
},
173+
174+
/**
175+
* Disposes the object from memory.
176+
* You need to call this when you want the BufferGeometry removed while the application is running.
177+
*/
178+
dispose: function ()
179+
{
180+
// TODO
181+
}
182+
183+
});
184+
185+
module.exports = Geometry;
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2020 Photon Storm Ltd.
4+
* @license {@link https://opensource.org/licenses/MIT|MIT License}
5+
*/
6+
7+
var BufferAttribute = require('./BufferAttribute');
8+
var Class = require('../../utils/Class');
9+
var Geometry = require('./Geometry');
10+
11+
var PlaneGeometry = new Class({
12+
13+
Extends: Geometry,
14+
15+
initialize:
16+
17+
function PlaneGeometry (width, height, widthSegments, heightSegments)
18+
{
19+
Geometry.call(this);
20+
21+
this.build(width, height, widthSegments, heightSegments);
22+
},
23+
24+
build: function (width, height, widthSegments, heightSegments)
25+
{
26+
width = width || 1;
27+
height = height || 1;
28+
29+
var halfWidth = width / 2;
30+
var halfHeight = height / 2;
31+
32+
var gridX = Math.floor(widthSegments) || 1;
33+
var gridY = Math.floor(heightSegments) || 1;
34+
35+
var gridX1 = gridX + 1;
36+
var gridY1 = gridY + 1;
37+
38+
var segmentWidth = width / gridX;
39+
var segmentHeight = height / gridY;
40+
41+
var ix, iy;
42+
43+
// buffers
44+
45+
var indices = [];
46+
var vertices = [];
47+
var normals = [];
48+
var uvs = [];
49+
50+
// generate vertices, normals and uvs
51+
52+
for (iy = 0; iy < gridY1; iy++)
53+
{
54+
var y = iy * segmentHeight - halfHeight;
55+
56+
for (ix = 0; ix < gridX1; ix++)
57+
{
58+
var x = ix * segmentWidth - halfWidth;
59+
60+
vertices.push(x, 0, y);
61+
62+
normals.push(0, 1, 0);
63+
64+
uvs.push(ix / gridX);
65+
uvs.push(1 - (iy / gridY));
66+
}
67+
}
68+
69+
// indices
70+
71+
for (iy = 0; iy < gridY; iy++)
72+
{
73+
for (ix = 0; ix < gridX; ix++)
74+
{
75+
var a = ix + gridX1 * iy;
76+
var b = ix + gridX1 * (iy + 1);
77+
var c = (ix + 1) + gridX1 * (iy + 1);
78+
var d = (ix + 1) + gridX1 * iy;
79+
80+
// faces
81+
82+
indices.push(a, b, d);
83+
indices.push(b, c, d);
84+
}
85+
}
86+
87+
// build geometry
88+
89+
this.setIndex(indices);
90+
this.addAttribute('a_Position', new BufferAttribute(new Float32Array(vertices), 3));
91+
this.addAttribute('a_Normal', new BufferAttribute(new Float32Array(normals), 3));
92+
this.addAttribute('a_Uv', new BufferAttribute(new Float32Array(uvs), 2));
93+
94+
this.computeBoundingBox();
95+
this.computeBoundingSphere();
96+
}
97+
98+
});
99+
100+
module.exports = PlaneGeometry;

0 commit comments

Comments
 (0)