-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
124 lines (97 loc) Β· 3.42 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
var faceNormals = require('face-normals')
var Bindings = require('./lib/bindings')
var flatten = require('./lib/flatten')
var pack = require('array-pack-2d')
module.exports = KindredGeometry
var counter = parseInt(Math.random().toString(32).slice(2, 10), 32)
function KindredGeometry (cells, positions, normals, uvs) {
if (!(this instanceof KindredGeometry)) {
return new KindredGeometry(cells, positions, normals, uvs)
}
if (cells && cells.positions && cells.cells) {
positions = cells.positions
normals = cells.normals
uvs = cells.uvs
cells = cells.cells
}
this.id = counter++
this.dirty = true
this.cache = new Map()
this.length = 0
this.elements = cells ? pack(cells, Uint32Array) : null
this.attribData = []
this.attribSize = []
this.attribName = []
this.attribRaw = []
if (positions) this.attr('position', positions)
if (normals) this.attr('normal', normals)
if (uvs) this.attr('uv', uvs)
}
KindredGeometry.prototype.attr = function attr (name, attr, opts) {
this.dirty = true
var defaultDims = typeof attr[0] === 'number' ? 3 : attr[0].length
var dims = (opts && opts.dimensions) || defaultDims
var type = (opts && opts.type) || 'float32'
var index = (!opts || opts.index !== false) && this.elements
var flat = flatten(attr, index, dims, type)
var i = this.attribName.indexOf(name)
if (i === -1) i = this.attribName.length
this.attribName[i] = name
this.attribSize[i] = dims
this.attribData[i] = flat
this.length = (i === 0) ? (flat.length / dims) : this.length
return this
}
KindredGeometry.prototype.attrFaceNormals = function (name) {
var faceNorms = faceNormals(this.attribData[0])
return this.attr(name || 'normal', faceNorms, { index: false })
}
KindredGeometry.prototype.attrVertNormals = function (name) {
if (!this.elements) {
throw new Error('Vertex (smooth) normals are only available if your mesh is indexed')
}
throw new Error('TODO: implement vertex normal calculation')
// var vertNorms = vertNormals(this.attribRaw[0], this.elements)
// return this.attr(name || 'normal', vertNorms, { index: true })
}
KindredGeometry.prototype.attrNormals = function (name) {
return this.elements
? this.attrVertNormals(name)
: this.attrFaceNormals(name)
}
KindredGeometry.prototype.bind = function (gl, attributeOrder) {
this._getBindings(gl).bind(attributeOrder)
}
KindredGeometry.prototype._createBindings = function (gl, prev) {
if (prev) prev.dispose()
var bindings = new Bindings(gl)
for (var i = 0; i < this.attribName.length; i++) {
bindings.push(this.attribName[i], this.attribSize[i], this.attribData[i])
}
return bindings
}
KindredGeometry.prototype._getBindings = function (gl) {
var bindings = this.cache.get(gl)
if (this.dirty || !bindings) {
bindings = this._createBindings(gl, bindings)
this.cache.set(gl, bindings)
}
this.dirty = false
return bindings
}
KindredGeometry.prototype.draw = function (gl, primitive, start, count) {
var bindings = this._getBindings(gl)
var state = bindings.attributeState
var drawStart = start || 0
var drawCount = typeof count === 'number' ? count : this.length
var prim = typeof primitive === 'number' ? primitive : gl.TRIANGLES
state.done(bindings.id)
gl.drawArrays(prim, drawStart, drawCount)
}
KindredGeometry.prototype.dispose = function () {
this.cache.forEach(disposeBinding)
this.cache.clear()
}
function disposeBinding (bindings) {
bindings.dispose()
}