1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | var constants = require('@pixi/constants');
|
6 | var runner = require('@pixi/runner');
|
7 | var utils = require('@pixi/utils');
|
8 | var Attribute = require('./Attribute.js');
|
9 | var Buffer = require('./Buffer.js');
|
10 | var interleaveTypedArrays = require('./utils/interleaveTypedArrays.js');
|
11 |
|
12 | const byteSizeMap = { 5126: 4, 5123: 2, 5121: 1 };
|
13 | let UID = 0;
|
14 | const map = {
|
15 | Float32Array,
|
16 | Uint32Array,
|
17 | Int32Array,
|
18 | Uint8Array,
|
19 | Uint16Array
|
20 | };
|
21 | class Geometry {
|
22 | constructor(buffers = [], attributes = {}) {
|
23 | this.buffers = buffers;
|
24 | this.indexBuffer = null;
|
25 | this.attributes = attributes;
|
26 | this.glVertexArrayObjects = {};
|
27 | this.id = UID++;
|
28 | this.instanced = false;
|
29 | this.instanceCount = 1;
|
30 | this.disposeRunner = new runner.Runner("disposeGeometry");
|
31 | this.refCount = 0;
|
32 | }
|
33 | addAttribute(id, buffer, size = 0, normalized = false, type, stride, start, instance = false) {
|
34 | if (!buffer) {
|
35 | throw new Error("You must pass a buffer when creating an attribute");
|
36 | }
|
37 | if (!(buffer instanceof Buffer.Buffer)) {
|
38 | if (buffer instanceof Array) {
|
39 | buffer = new Float32Array(buffer);
|
40 | }
|
41 | buffer = new Buffer.Buffer(buffer);
|
42 | }
|
43 | const ids = id.split("|");
|
44 | if (ids.length > 1) {
|
45 | for (let i = 0; i < ids.length; i++) {
|
46 | this.addAttribute(ids[i], buffer, size, normalized, type);
|
47 | }
|
48 | return this;
|
49 | }
|
50 | let bufferIndex = this.buffers.indexOf(buffer);
|
51 | if (bufferIndex === -1) {
|
52 | this.buffers.push(buffer);
|
53 | bufferIndex = this.buffers.length - 1;
|
54 | }
|
55 | this.attributes[id] = new Attribute.Attribute(bufferIndex, size, normalized, type, stride, start, instance);
|
56 | this.instanced = this.instanced || instance;
|
57 | return this;
|
58 | }
|
59 | getAttribute(id) {
|
60 | return this.attributes[id];
|
61 | }
|
62 | getBuffer(id) {
|
63 | return this.buffers[this.getAttribute(id).buffer];
|
64 | }
|
65 | addIndex(buffer) {
|
66 | if (!(buffer instanceof Buffer.Buffer)) {
|
67 | if (buffer instanceof Array) {
|
68 | buffer = new Uint16Array(buffer);
|
69 | }
|
70 | buffer = new Buffer.Buffer(buffer);
|
71 | }
|
72 | buffer.type = constants.BUFFER_TYPE.ELEMENT_ARRAY_BUFFER;
|
73 | this.indexBuffer = buffer;
|
74 | if (!this.buffers.includes(buffer)) {
|
75 | this.buffers.push(buffer);
|
76 | }
|
77 | return this;
|
78 | }
|
79 | getIndex() {
|
80 | return this.indexBuffer;
|
81 | }
|
82 | interleave() {
|
83 | if (this.buffers.length === 1 || this.buffers.length === 2 && this.indexBuffer)
|
84 | return this;
|
85 | const arrays = [];
|
86 | const sizes = [];
|
87 | const interleavedBuffer = new Buffer.Buffer();
|
88 | let i;
|
89 | for (i in this.attributes) {
|
90 | const attribute = this.attributes[i];
|
91 | const buffer = this.buffers[attribute.buffer];
|
92 | arrays.push(buffer.data);
|
93 | sizes.push(attribute.size * byteSizeMap[attribute.type] / 4);
|
94 | attribute.buffer = 0;
|
95 | }
|
96 | interleavedBuffer.data = interleaveTypedArrays.interleaveTypedArrays(arrays, sizes);
|
97 | for (i = 0; i < this.buffers.length; i++) {
|
98 | if (this.buffers[i] !== this.indexBuffer) {
|
99 | this.buffers[i].destroy();
|
100 | }
|
101 | }
|
102 | this.buffers = [interleavedBuffer];
|
103 | if (this.indexBuffer) {
|
104 | this.buffers.push(this.indexBuffer);
|
105 | }
|
106 | return this;
|
107 | }
|
108 | getSize() {
|
109 | for (const i in this.attributes) {
|
110 | const attribute = this.attributes[i];
|
111 | const buffer = this.buffers[attribute.buffer];
|
112 | return buffer.data.length / (attribute.stride / 4 || attribute.size);
|
113 | }
|
114 | return 0;
|
115 | }
|
116 | dispose() {
|
117 | this.disposeRunner.emit(this, false);
|
118 | }
|
119 | destroy() {
|
120 | this.dispose();
|
121 | this.buffers = null;
|
122 | this.indexBuffer = null;
|
123 | this.attributes = null;
|
124 | }
|
125 | clone() {
|
126 | const geometry = new Geometry();
|
127 | for (let i = 0; i < this.buffers.length; i++) {
|
128 | geometry.buffers[i] = new Buffer.Buffer(this.buffers[i].data.slice(0));
|
129 | }
|
130 | for (const i in this.attributes) {
|
131 | const attrib = this.attributes[i];
|
132 | geometry.attributes[i] = new Attribute.Attribute(attrib.buffer, attrib.size, attrib.normalized, attrib.type, attrib.stride, attrib.start, attrib.instance);
|
133 | }
|
134 | if (this.indexBuffer) {
|
135 | geometry.indexBuffer = geometry.buffers[this.buffers.indexOf(this.indexBuffer)];
|
136 | geometry.indexBuffer.type = constants.BUFFER_TYPE.ELEMENT_ARRAY_BUFFER;
|
137 | }
|
138 | return geometry;
|
139 | }
|
140 | static merge(geometries) {
|
141 | const geometryOut = new Geometry();
|
142 | const arrays = [];
|
143 | const sizes = [];
|
144 | const offsets = [];
|
145 | let geometry;
|
146 | for (let i = 0; i < geometries.length; i++) {
|
147 | geometry = geometries[i];
|
148 | for (let j = 0; j < geometry.buffers.length; j++) {
|
149 | sizes[j] = sizes[j] || 0;
|
150 | sizes[j] += geometry.buffers[j].data.length;
|
151 | offsets[j] = 0;
|
152 | }
|
153 | }
|
154 | for (let i = 0; i < geometry.buffers.length; i++) {
|
155 | arrays[i] = new map[utils.getBufferType(geometry.buffers[i].data)](sizes[i]);
|
156 | geometryOut.buffers[i] = new Buffer.Buffer(arrays[i]);
|
157 | }
|
158 | for (let i = 0; i < geometries.length; i++) {
|
159 | geometry = geometries[i];
|
160 | for (let j = 0; j < geometry.buffers.length; j++) {
|
161 | arrays[j].set(geometry.buffers[j].data, offsets[j]);
|
162 | offsets[j] += geometry.buffers[j].data.length;
|
163 | }
|
164 | }
|
165 | geometryOut.attributes = geometry.attributes;
|
166 | if (geometry.indexBuffer) {
|
167 | geometryOut.indexBuffer = geometryOut.buffers[geometry.buffers.indexOf(geometry.indexBuffer)];
|
168 | geometryOut.indexBuffer.type = constants.BUFFER_TYPE.ELEMENT_ARRAY_BUFFER;
|
169 | let offset = 0;
|
170 | let stride = 0;
|
171 | let offset2 = 0;
|
172 | let bufferIndexToCount = 0;
|
173 | for (let i = 0; i < geometry.buffers.length; i++) {
|
174 | if (geometry.buffers[i] !== geometry.indexBuffer) {
|
175 | bufferIndexToCount = i;
|
176 | break;
|
177 | }
|
178 | }
|
179 | for (const i in geometry.attributes) {
|
180 | const attribute = geometry.attributes[i];
|
181 | if ((attribute.buffer | 0) === bufferIndexToCount) {
|
182 | stride += attribute.size * byteSizeMap[attribute.type] / 4;
|
183 | }
|
184 | }
|
185 | for (let i = 0; i < geometries.length; i++) {
|
186 | const indexBufferData = geometries[i].indexBuffer.data;
|
187 | for (let j = 0; j < indexBufferData.length; j++) {
|
188 | geometryOut.indexBuffer.data[j + offset2] += offset;
|
189 | }
|
190 | offset += geometries[i].buffers[bufferIndexToCount].data.length / stride;
|
191 | offset2 += indexBufferData.length;
|
192 | }
|
193 | }
|
194 | return geometryOut;
|
195 | }
|
196 | }
|
197 |
|
198 | exports.Geometry = Geometry;
|
199 |
|