1 | 'use strict'
|
2 |
|
3 | var createBuffer = require('gl-buffer')
|
4 | var createVAO = require('gl-vao')
|
5 | var createShader = require('./shaders/index')
|
6 |
|
7 | module.exports = createSpikes
|
8 |
|
9 | var identity = [1,0,0,0,
|
10 | 0,1,0,0,
|
11 | 0,0,1,0,
|
12 | 0,0,0,1]
|
13 |
|
14 | function AxisSpikes(gl, buffer, vao, shader) {
|
15 | this.gl = gl
|
16 | this.buffer = buffer
|
17 | this.vao = vao
|
18 | this.shader = shader
|
19 | this.pixelRatio = 1
|
20 | this.bounds = [[-1000,-1000,-1000], [1000,1000,1000]]
|
21 | this.position = [0,0,0]
|
22 | this.lineWidth = [2,2,2]
|
23 | this.colors = [[0,0,0,1], [0,0,0,1], [0,0,0,1]]
|
24 | this.enabled = [true,true,true]
|
25 | this.drawSides = [true,true,true]
|
26 | this.axes = null
|
27 | }
|
28 |
|
29 | var proto = AxisSpikes.prototype
|
30 |
|
31 | var OUTER_FACE = [0,0,0]
|
32 | var INNER_FACE = [0,0,0]
|
33 |
|
34 | var SHAPE = [0,0]
|
35 |
|
36 | proto.isTransparent = function() {
|
37 | return false
|
38 | }
|
39 |
|
40 | proto.drawTransparent = function(camera) {}
|
41 |
|
42 | proto.draw = function(camera) {
|
43 | var gl = this.gl
|
44 | var vao = this.vao
|
45 | var shader = this.shader
|
46 |
|
47 | vao.bind()
|
48 | shader.bind()
|
49 |
|
50 | var model = camera.model || identity
|
51 | var view = camera.view || identity
|
52 | var projection = camera.projection || identity
|
53 |
|
54 | var axis
|
55 | if(this.axes) {
|
56 | axis = this.axes.lastCubeProps.axis
|
57 | }
|
58 |
|
59 | var outerFace = OUTER_FACE
|
60 | var innerFace = INNER_FACE
|
61 | for(var i=0; i<3; ++i) {
|
62 | if(axis && axis[i] < 0) {
|
63 | outerFace[i] = this.bounds[0][i]
|
64 | innerFace[i] = this.bounds[1][i]
|
65 | } else {
|
66 | outerFace[i] = this.bounds[1][i]
|
67 | innerFace[i] = this.bounds[0][i]
|
68 | }
|
69 | }
|
70 |
|
71 | SHAPE[0] = gl.drawingBufferWidth
|
72 | SHAPE[1] = gl.drawingBufferHeight
|
73 |
|
74 | shader.uniforms.model = model
|
75 | shader.uniforms.view = view
|
76 | shader.uniforms.projection = projection
|
77 | shader.uniforms.coordinates = [this.position, outerFace, innerFace]
|
78 | shader.uniforms.colors = this.colors
|
79 | shader.uniforms.screenShape = SHAPE
|
80 |
|
81 | for(var i=0; i<3; ++i) {
|
82 | shader.uniforms.lineWidth = this.lineWidth[i] * this.pixelRatio
|
83 | if(this.enabled[i]) {
|
84 | vao.draw(gl.TRIANGLES, 6, 6*i)
|
85 | if(this.drawSides[i]) {
|
86 | vao.draw(gl.TRIANGLES, 12, 18+12*i)
|
87 | }
|
88 | }
|
89 | }
|
90 |
|
91 | vao.unbind()
|
92 | }
|
93 |
|
94 | proto.update = function(options) {
|
95 | if(!options) {
|
96 | return
|
97 | }
|
98 | if("bounds" in options) {
|
99 | this.bounds = options.bounds
|
100 | }
|
101 | if("position" in options) {
|
102 | this.position = options.position
|
103 | }
|
104 | if("lineWidth" in options) {
|
105 | this.lineWidth = options.lineWidth
|
106 | }
|
107 | if("colors" in options) {
|
108 | this.colors = options.colors
|
109 | }
|
110 | if("enabled" in options) {
|
111 | this.enabled = options.enabled
|
112 | }
|
113 | if("drawSides" in options) {
|
114 | this.drawSides = options.drawSides
|
115 | }
|
116 | }
|
117 |
|
118 | proto.dispose = function() {
|
119 | this.vao.dispose()
|
120 | this.buffer.dispose()
|
121 | this.shader.dispose()
|
122 | }
|
123 |
|
124 |
|
125 |
|
126 | function createSpikes(gl, options) {
|
127 |
|
128 | var data = [ ]
|
129 |
|
130 | function line(x,y,z,i,l,h) {
|
131 | var row = [x,y,z, 0,0,0, 1]
|
132 | row[i+3] = 1
|
133 | row[i] = l
|
134 | data.push.apply(data, row)
|
135 | row[6] = -1
|
136 | data.push.apply(data, row)
|
137 | row[i] = h
|
138 | data.push.apply(data, row)
|
139 | data.push.apply(data, row)
|
140 | row[6] = 1
|
141 | data.push.apply(data, row)
|
142 | row[i] = l
|
143 | data.push.apply(data, row)
|
144 | }
|
145 |
|
146 | line(0,0,0, 0, 0, 1)
|
147 | line(0,0,0, 1, 0, 1)
|
148 | line(0,0,0, 2, 0, 1)
|
149 |
|
150 | line(1,0,0, 1, -1,1)
|
151 | line(1,0,0, 2, -1,1)
|
152 |
|
153 | line(0,1,0, 0, -1,1)
|
154 | line(0,1,0, 2, -1,1)
|
155 |
|
156 | line(0,0,1, 0, -1,1)
|
157 | line(0,0,1, 1, -1,1)
|
158 |
|
159 | var buffer = createBuffer(gl, data)
|
160 | var vao = createVAO(gl, [{
|
161 | type: gl.FLOAT,
|
162 | buffer: buffer,
|
163 | size: 3,
|
164 | offset: 0,
|
165 | stride: 28
|
166 | }, {
|
167 | type: gl.FLOAT,
|
168 | buffer: buffer,
|
169 | size: 3,
|
170 | offset: 12,
|
171 | stride: 28
|
172 | }, {
|
173 | type: gl.FLOAT,
|
174 | buffer: buffer,
|
175 | size: 1,
|
176 | offset: 24,
|
177 | stride: 28
|
178 | }])
|
179 |
|
180 |
|
181 | var shader = createShader(gl)
|
182 | shader.attributes.position.location = 0
|
183 | shader.attributes.color.location = 1
|
184 | shader.attributes.weight.location = 2
|
185 |
|
186 |
|
187 | var spikes = new AxisSpikes(gl, buffer, vao, shader)
|
188 |
|
189 |
|
190 | spikes.update(options)
|
191 |
|
192 |
|
193 | return spikes
|
194 | }
|