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